06.MyBatis的dao层开发
1.传统开发方式
-
编写UserMapper接口
-
编写UserMapper实现类
-
编写UserMapper.xml
传统方式问题思考:
-
实现类中,如果方法过多,存在mybatis模板代码重复。
// 1.加载MyBatis核心配置文件 InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml"); // 2.创建sqlSessionFactory工厂对象 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); // 3.获取sqlSession会话对象 SqlSession sqlSession = sqlSessionFactory.openSession();
-
实现类调用方法时,xml中的sql statement硬编码到java代码中,不易后期维护。
思考:否只写接口,不写实现类。只编写接口和Mapper.xml即可?
- 答案是可以的。企业级开发会摒弃Mapper的实现类。
2.代理开发方式
-
采用 Mybatis 的基于接口代理方式实现持久层的开发,这种方式是我们后面进入企业的主流。
-
基于接口代理方式的开发只需要程序员编写 Mapper 接口,Mybatis 框架会为我们动态生成实现类的对象。
小结:面向接口开发 。
但是这种开发方式要求我们遵循一定的规范:
- Mapper.xml映射文件中的namespace与mapper接口的全限定名相同。
- Mapper接口方法名和Mapper.xml映射文件中定义的每个statement的id相同。
- Mapper接口方法的输入参数类型和mapper.xml映射文件中定义的每个sql的parameterType的类型相同。
- Mapper接口方法的输出参数类型和mapper.xml映射文件中定义的每个sql的resultType的类型相
同。
Mapper 接口开发方法只需要程序员编写Mapper 接口(相当于Dao 接口),由Mybatis 框架根据接口
定义创建接口的动态代理对象,代理对象的方法体同上边Dao接口实现类方法。
修改后:
-
mapper.xml代码:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- 设置别名--> <properties resource="jdbc.properties"></properties> <typeAliases> <!-- 方式一:给单个实体起别名--> <!-- <typeAlias type="com.lagou.domain.User" alias="user"/>--> <!-- 方式二:批量起别名--> <package name="com.lagou.domain"/> </typeAliases> <!-- 配置环境变量--> <environments default="mysql"> <!-- 使用mysql环境--> <environment id="mysql"> <!-- 使用JDBC类型事务管理器--> <transactionManager type="JDBC"></transactionManager> <!-- 使用连接池--> <!-- 使用配置,加载数据库连接--> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </dataSource> </environment> </environments> <!-- 引入mapper.xml文件--> <mappers> <!-- 方式一:resoure为接口的全路径--> <!-- <mapper resource="com/lagou/mapper/UserMapper.xml"/>--> <!-- 方式二:定义到类所在的包,批量加载映射--> <package name="com.lagou.mapper"/> </mappers> </configuration>
3.Mybatis基于接口代理方式的内部执行原理
我们的持久层现在只有一个接口,而接口是不实际干活的,那么是谁在做查询的实际工作呢?
下面通过追踪源码看一下:
1、通过追踪源码我们会发现,我们使用的mapper实际上是一个代理对象,是由MapperProxy代理产生的。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-k8xcHHkg-1645261038896)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20220219102230460.png)]
2、追踪MapperProxy的invoke方法会发现,其最终调用了mapperMethod.execute(sqlSession, args)
3、进入execute方法会发现,最终工作的还是sqlSession
- 执行图解