一、Mybatis的不足之处
Mybatis是一款优秀的及其灵活的持久层框架,通过XML配置并映射到Mapper接口为Service层提供基础数据操作入口。
这么优秀的框架竟然还有不足之处?
俗话说人无完人,因为Mybatis实在是太灵活了,灵活到每个Mapper接口都需要定制对应的XML,所以就会引发一些问题。
问题一:配置文件繁多
假如一个系统中DB中涉及100张表,我们就需要写100
个Mapper接口,还没完,最可怕的是,我们要为这100
个Mapper接口定制与之对应的100
套XML。而每个Mapper都必不可少的需要增删改查功能,我们就要写100
遍增删改查,作为高贵的Java开发工程师,这是不能容忍的,于是Mybatis Generator
诞生了,然而又会引发另一个问题!
问题二:维护困难
我们使用Mybatis Generator
解决了问题一,再多的文件生成就是了,简单粗暴,貌似解决了所有的问题,Mybatis完美了!
不要高兴的太早,在系统刚刚建立起来时,我们使用Mybatis Generator
生成了一堆XML,在开发过程中,产品忽然提了一个新的需求,项目经理根据这个需求在某张表中增加或变动了一个字段,这时,我猜你的操作是这样:
- 1、找到对应表的XML
- 2、将该XML中自定义的一段标签复制出来,保存在本地
- 3、使用
Mybatis Generator
重新生成该表的XML - 4、将之覆盖当前的XML
- 5、将自定义的一段标签再粘贴进新的XML中
在这个过程中,如果我们在第2步时漏复制了一段标签,等整个操作完成之后,又别是一番滋味在心头~
问题三:编写XML困难
假如肝不错,问题二也是小CASE,那么问题又来了,我们如何在繁长的XML中去编写和修改我们的XML呢。
当我们打开要编辑的XML,映入眼帘的就是1000多行的XML,其中900行都是通用的增删改查操作,要新增一个标签,我们需要拉至文件底部编写新的数据操作,要更新一个标签,我们需要通过Ctrl + F
寻找目标标签再进行修改。
如何避免这些问题呢?
如何让Mybatis增强通用性又不失灵活呢?
二、使用Ourbatis辅助Mybatis
Ourbatis是一款Mybatis开发增强工具,小巧简洁,项目地址:
- Github:https://github.com/ainilili/ourbatis
- Gitee:https://gitee.com/ainilili/ourbatis
- Wiki:https://github.com/ainilili/ourbatis/wiki
- Demo:https://github.com/ainilili/ourbatis-simple
特性:
- 1、简洁方便,可以让Mybatis无XML化开发。
- 2、优雅解耦,通用和自定义的SQL标签完全隔离,让维护更加轻松。
- 3、无侵入性,Mybatis和Ourbatis可同时使用,配置简洁。
- 4、灵活可控,通用模板可自定义及扩展。
- 5、部署快捷,只需要一个依赖,两个配置,即可直接运行。
- 6、多数据源,在多数据源环境下也可以照常使用。
关于Ourbatis使用的一个小Demo
环境:
- Spring Boot 2.0.5.RELEASE
- Ourbatis 1.0.5
- JAVA 8
- Mysql
以Spring Boot 2.0.5.RELEASE
版本为例,在可以正常使用Mybatis的项目中,pom.xml
添加如下依赖:
<dependency>
<groupId>com.smallnico</groupId>
<artifactId>ourbatis-spring-boot-starter</artifactId>
<version>1.0.5</version>
</dependency>
在配置文件中增加一下配置:
ourbatis.domain-locations=实体类所在包名
接下来,Mapper接口只需要继承SimpleMapper
即可:
import org.nico.ourbatis.domain.User;
public interface UserMapper extends SimpleMapper<User, Integer>{
}
至此,一个使用Ourbatis的简单应用已经部署起来了,之后,你就可以使用一些Ourbatis默认的通用操作方法:
public T selectById(K key);
public T selectEntity(T condition);
public List<T> selectList(T condition);
public long selectCount(Object condition);
public List<T> selectPage(Page<Object> page);
default PageResult<T> selectPageResult(Page<Object> page){
long total = selectCount(page.getEntity());
List<T> results = null;
if(total > 0) {
results = selectPage(page);
}
return new Pa