写点什么

聊聊 MyBatis 的历史,mysql 原理详解

用户头像
极客good
关注
发布于: 刚刚

<mappers>


<mapper resource="mapper/user.xml"/>


</mappers>


</configuration>


下面是某个 mapper 的配置


<?xml version="1.0" encoding="UTF-8"?>


<!DOCTYPE mapper


PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"


"http://mybatis.org/dtd/mybatis-3-mapper.dtd">


<mapper namespace="xml">


<select id="listUser" resultType="user">


select * from? user;


</select>


</mapper>


这个 mapper 里面有个 namespace,我一直不知道它是什么意思。没关系这个 namespace 先随便写,一会就知道它是什么意思了。


增加 entity


package entity;


/**


  • @program: parent_pro

  • @description:

  • @author: 渭水

  • @create: 2021/07/21


*/


public class User {


private int id;


private String username;


private String? password;


private String nickname;


// 省略 getset


}


最后的启动类


package xml;


import entity.User;


import org.apache.ibatis.io.Resources;


import org.apache.ibatis.session.SqlSession;


import org.apache.ibatis.session.SqlSessionFactory;


import org.apache.ibatis.session.SqlSessionFactoryBuilder;


import java.io.IOException;


import java.io.InputStream;


import java.util.List;


/**


  • @program: parent_pro

  • @description:

  • @author: 渭水

  • @create: 2021/07/21


*/


public class MyBatisWithXML {


public static void main(String[] args) {


String resource = "mybatis-config.xml";


InputStream inputStream = null;


try {


inputStream = Resources.getResourceAsStream(resource);


} catch (IOException e) {


e.printStackTrace();


}


SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);


SqlSession session = sqlSessionFactory.openSession();


// 最后通过 session 的 selectList() 方法调用 sql 语句 listStudent


List<User> userList = session.selectList("listUser");


for (User student : userList) {


System.out.println("ID:" + student.getId() + ",NAME:" + student.getUsername());


}


}


}


我们看看整个项目个结构图:



数据库那边,我已经建立好了,大家看看:



运行项目就能看到:



OK,至此项目已经可以运行了。


然后我们分析一下代码:


关于别名




一段一段看


<select id="listUser" resultType="user">


select * from? user limit 5;


</select>


这个里面的 resultType,我们不用看框架,大概就懂它指的是把下面的 sql 语句执行的结果,包装成什么类型。


那么光写个 user,mybatis 知道这个 user 是个什么东西么?


<typeAliases>


<package name="entity"/>


</typeAliases>


上面一段代码的语义就是,把 entity 下面的实体都加一个别名,而别名就是类名。所以 mybatis 就知道上面的 user 其实对应的就是 entity.User 这个类。


关于 namespace




上面已经有了一个 mapper,我现在再加一个 mapper 如下:



和之前那个的区别就是一个 limit 5,一个 limit 10


然后让 mybatis 的主配置文件感知到这个 user2.xml


<mappers>


<mapper? resource="mapper/user.xml"/>


<mapper? resource="mapper/user2.xml"/>


</mappers>


然后运行代码会发现:



说的很清楚 listUser 这个 id 重复了。


在线上工程里,要保证所有的 sql 的 id 都不重复有点困难,所以引入了 namespace 的概念。如果一旦有重复的 id,那么 session 调用的时候得指定 namespace。


List<User> userList = session.selectList("xml.listUser");


原生的 mybatis(使用注解)


================


@Mapper


public interface PersonMapper {


@Select("select id,name ,age from person where id = #{id}")


Person getPersonById(int id);


@Select("<script>"


+"select * from person where 1=1"


+"<if test='name2 != null'> and name = #{name2}" +"</if>"


+"<if test='age != null'> and age = #{age}" +"</if>"


+"</script>")


List<Person> getList(@Param("name2") String name,@Param("age") String age);


@SelectProvider(type = UserDaoProvider.class, method = "getPersonByPara")


Person getPersonByPara(@Param("name") String name, @Param("age") String age);


}


如上面所示


调用的时候就直接写


PersonMapper personMapper = session.getMapper(PersonMapper.class);


Person result = personMapper.getPersonByPara("渭水","");


List<Person> list = personMapper.getList(null,"25");


其实,这就回到我在序言里说的了,在 java 代码里写脚本语言很丑,代码很难读。


我们可以用一个单独的 java 方法来产生 sql 语句,如下;


@Mapper


public interface PersonMapper {


@SelectProvider(type = UserDaoProvider.class, method = "getPersonByPara")


Person getPersonByPara(@Param("name") String name, @Param("age") String age);


}


public class UserDaoProvider {


public String getPersonByPara(Map<String, Object> para) {


String sql = new SQL() {


{


SELECT("id, name, age");


FROM("person");


if (StringUtils.isNotBlank("" + para.get("name"))) {


WHERE("name='" + para.get("name")+"'");


}


if (StringUtils.isNotBlank("" + para.get("age"))) {


WHERE("age=" + para.get("age"));


}


}


}.toString();


System.out.println("----" + sql);


return sql;


}


}


Mybatis 与 spring


==============


通过上面我们可以看到,不管是用 xml 配置,还是直接在 java 文件里写注解,最终都是通过 SqlSession 来指向下一步的操作的。


所以,就算我们把 mybatis 与 spring 整合,其实核心原理还是依赖 SqlSession 的。


第一步,我们先去掉之前的 mybatis 依赖,改成


<dependency>


<groupId>org.mybatis</groupId>


<artifactId>mybatis-spring</artifactId>


<version>2.0.6</version>


</dependency>


然后在 spring 的 xml 里面加上


<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">


<property name="dataSource" ref="dataSource" />


</bean>


dataSource 的相关代码我这边就赘述。


然后,具体来说,整合的思路有两种:


MapperFactoryBean




把我们的 mapper 放到 MapperFactoryBean 里面


public interface UserMapper {


@Select("SELECT * FROM users WHERE


【一线大厂Java面试题解析+核心总结学习笔记+最新架构讲解视频+实战项目源码讲义】
浏览器打开:qq.cn.hn/FTf 免费领取
复制代码


id = #{userId}")


User getUser(@Param("userId") String userId);


}


<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">


<property name="mapperInterface" value="org.mybatis.spring.sample.mapper.UserMapper" />


<property name="sqlSessionFactory" ref="sqlSessionFactory" />


</bean>


使用的时候


public class FooServiceImpl implements FooService {


private final UserMapper userMapper;


public FooServiceImpl(UserMapper userMapper) {


this.userMapper = userMapper;


}


public User doSomeBusinessStuff(String userId) {


return this.userMapper.getUser(userId);


}


}


我们怎么说也是写了年代码的人了,稍微往下追一下吧


先说 userMapper 它最后是 MapperFactoryBean,哦,FactoryBean,来大家看一下:


[https://blog.csdn.net/dlf123321/article/details/47856937](


),也就是说最终 userMapper 是 MapperFactoryBean 调用 getObject 的结果,我们看看代码



public abstract class SqlSessionDaoSupport extends DaoSupport {


private SqlSessionTemplate sqlSessionTemplate;

用户头像

极客good

关注

还未添加个人签名 2021.03.18 加入

还未添加个人简介

评论

发布
暂无评论
聊聊MyBatis的历史,mysql原理详解