MyBatis 这种半封装的ORM框架相较全封装,最大的优点就是 SQL优化方便, 但也有不少痛点,如 简单的 CRUD 逻辑都需要自行处理,*.xml
不能和 *.java
文件友好契合等。
工欲善其事,必先利其器。这里介绍几个工具,可以有效的解决 Mybatis 的痛点,大大的提高工作效率。
涉及 | 说明 |
---|---|
Mybatis Generator |
代码生成器。 |
Mybatis Plugin |
IDE插件,解决 *.xml 不能和 *.java 文件完美契合等。 |
Mybatis PageHelper |
分页插件。 |
Mybatis Generator
Mybatis Generator 是 Mybatis 提供的代码生成器,可以生成DAO层所需的*.java
, *.xml
和 实体类
,包括可以简单的CRUD相关所需。
注意 : 默认情况下,反复运行
*.java
文件会被覆盖,而*.xml
会合并。
1 | <!-- generator --> |
generatorConfig.xml
踩坑记
table.schema
: 使用oracle时,最好使用 schema 指定用户名,因为当实例下有多个用户拥有相同的表时,若对表进行变更,会无法及时更新。
1 |
|
启动方式
generator 有很多启动方式,个人认为 main方法 启动,最为友好,以下为示例。
1 | package tk.gushizone.system.common.util; |
Mybatis Plugin
相关IDE插件有很多,以 IDEA 为例,我使用的是
Free Mybatis Plugin
。类似的Mybatis Plugin
和Mybatis Plus
功能更强大,但是收费。
主要功能
- 关联
*.java
和*.xml
,并提供相关验证。 - 自动补全和代码生成等。
Free Mybatis Plugin
新版已支持 generator!
Mybatis PageHelper
Mybatis PageHelper
是一款非常好用的 Mybatis 分页插件。支持各种数据库,使用起来也十分方便。
1 | <!-- pagehelper --> |
1 | pagehelper: |
分页方式
这里简单的介绍一下利用 PageHelper
实现分页的方式。
Mybatis PageHelper
提供了很多种实现方式,这里只列举常用的方式。
涉及 | 说明 |
---|---|
PageHelper.startPage 静态方法 |
推荐开发使用,耦合度和代码侵入性小。 |
ISelect接口 方式 |
推荐框架使用,代码侵入性小,且安全性高。 |
PageHelper.startPage
静态方法
这里介绍一种常用的方式: PageHelper.startPage
+ PageInfo
。
分页时,sql 会被拦截。分页后,实际返回是
Page<E>
类型的对象,Page
是ArrayList
的子类 , 如果想取出分页信息,需要强制转换为Page<E>
,或使用PageInfo
。
1 | // 获取第1页,10条内容,默认查询总数count |
ISelect接口
方式
JDK8后,配合 lambda表达式
更适合架构设计。 ISelect接口方式
在 JDK8 以前使用并不友好,这里不加赘述。
可以将此段代码封装到架构底层,再用
lambda
配合ISelect接口
,可以做到分页代码在上层业务代码中达到无侵入。
1 | // 返回Page对象 |
排序
1 | String order = StringUtils.EMPTY; |
注意项
PageHelper.startPage 方法重要提示
只有紧跟在 PageHelper.startPage
方法后的第一个Mybatis的查询(Select)方法会被分页。
线程安全性 :只要 PageHelper.startPage
静态方法后跟着一个select
方法就会线程安全,因为分页参数和线程是绑定的 。反之,生产的分页参数会一直存于该线程中,没被消费,当这个该线程被再次调用时,可能会产生了莫名其妙的分页。所以一定要避免中间可能会抛异常的操作。
1 | // 开始分页 |
分页插件不支持嵌套结果映射
由于嵌套结果方式会导致结果集被折叠,因此分页查询的结果在折叠后总数会减少,所以无法保证分页结果数量正确。即 不支持Mybatis一对多的正常分页 。
解决方案
- 主子表分开查询,(若需要)先条件过滤子表,再分页主表,再获取子表信息。
- 主子表一起查询,逻辑分页。
分页插件不支持带有 for update
语句的分页
对于带有for update
的sql,会抛出运行时异常,对于这样的sql建议手动分页,毕竟这样的sql需要重视。
请不要配置多个分页插件
请不要在系统中配置多个分页插件(使用Spring时,mybatis-config.xml
和Spring<bean>
配置方式,请选择其中一种,不要同时配置多个分页插件)!