前言
后端一半的时间都是在和关系型数据库打交道,那么虽然我们用 mybatis 这个 ORM 框架,简化代码的开发。但是代码中涉及到太多的重复操作,比如对用户的增删改查和对设备的增删改查。我们毕竟是贪婪而又懒惰的,能够自动化的绝不手动处理,所以不禁想问:有没有威力加强版?
回答是:有,而且很香。
这里要提两点:
- 每个公司基本上都会有自己的威力加强版,即代码生成工具或者是数据操作简化工具。
- 能够自动化的一定要自动化,这也是解决问题和完成任务的区别:完成任务是完成了这样任务,但是后面还会出现类似的;解决问题的思维是完成了这一类任务的处理,后面相同的任务就不再是任务了。
那么,这个威力加强版是什么呢?
是 mybatis-plus 。这个名字很形象,威力加强版无疑了。官网文档的愿景如下:
我们的愿景是成为 MyBatis 最好的搭档,就像 魂斗罗 中的 1P、2P,基友搭配,效率翻倍
– 参见 mybatis-plus官网
由于官方网文档写的非常好,也有详细的视频教程,大家可以选择参看下面的文档和视频链接,本文重点就不在于如何使用的细节了。
官方文档基本上看一下就可以大致知道如何使用了,视频可选择参看。
整合及解答
整合
还是来一个整合教程吧,不然从新上手还是要费一点点时间的。总共分为6步:
- 引入maven依赖,覆盖原先的mybatis依赖。即 mybatis 和 mybatis-plus 的依赖只要有一个就行了:
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.0</version>
</dependency>
- application.yml 或者 application.properties 文件配置,实际上和 mybatis 的配置内容一样,就是要把:
mybatis:
mapper-locations: classpath*:/mapper/*.xml
替换成:
mybatis-plus:
mapper-locations: classpath*:/mapper/*.xml
其他都不变。
- 创建数据表映射对象,比如:
@TableName("sys_user") // 对应的数据表名称,必填
public class UserPlus {
@TableId // 标识这个属性是数据表的主键,可选:当主键名和这个属性名不一致时或者主键不叫id时标识
private String id;
@TableField("username") // 标识这个属性在数据表中的名字是:username。可选:当属性名和数据表字段名不一致时
private String name;
private String password;
@Override
public String toString() {
return "UserPlus{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
", password='" + password + '\'' +
'}';
}
}
- 创建dao层接口(mapper接口)
public interface MyPlusMapper extends BaseMapper<UserPlus> {
}
其中,BaseMapper是包括基础功能的接口,mybatis-plus 自带。
- 添加mapper扫描配置注解,放在main方法的那个类上或者放在带有 @Configuration 注解的类上。
@SpringBootApplication
// 注意,下面的配置中有两个路径,一个是 mybatisplus 自己的,另外一个是你自己的
@MapperScan("com.baomidou.mybatisplus.samples.quickstart.mapper, com.你自己的dao层接口所在的目录")
public class WebTestApplication {
public static void main(String[] args) {
SpringApplication.run(WebTestApplication.class, args);
}
}
完了
真的完了
就是这么简单,使用例程如下:
@Autowired
private MyPlusMapper testMapper;
@Test
public void mybatisTest() {
log.info(testMapper.selectOne(new QueryWrapper<UserPlus>().eq("username", "admin")).toString());
}
输出结果为:
UserPlus{id=‘1140466515787780089’, name=‘admin’, password=‘1231231231’}
如果再配合上 generator 自动生成代码框架。也就是根据你设计好的数据表来自动生成:
- service层的代码
- dao层的代码
- 数据表映射对象
- mapper.xml文件
这意味着什么呢?意味着足够简单,意味着急速开发,意味着解决了一个问题:即各类单表的CURD操作,提升了我们的生产效率。
解惑
- 第一点中,因为mybatis-plus是建立在 mybatis基础之上的,所以叫 plus。其本身内置了 Mybatis依赖库了,所以没必要重复引用。
- 第二点中,mybatis和 mybatis-plus 的配置基本是一样的,但是由于二者名字不同,所以yaml中的配置键名也变成了 mybatis-plus
- 第三点中,和 mybatis 程序一样,需要建立数据映射对象。但是此处重点在于代码中的注解,具体解释参见代码注释,以及 文档
- 第四点中,你会发现 dao 层接口除了继承了通用接口外,什么注解都没加。这是因为 mybatis-plus 在启动时会扫描这些接口,并创建好代理对象自动交给 spring 托管。所以我们可以直接 @Autowired 进行注入。但是它又是怎么知道这些接口文件在哪里呢?也即哪些接口是需要被扫描的呢?
- 这就引出了第五点,即 mybatis-plus 扫描的接口需要我们去配置一下,告诉他去哪里扫描。实际上注解中的第一个路径不是必须的,可以去掉,关键是要写上自己的。
- 最后实际使用时,可以通过方法名字就知道这个方法是干什么的。涉及到条件过滤的,只有更新的时候使用
UpdateWrapper
来设置更新条件,其他操作都使用QueryWrapper
来设置过滤条件。更详细参见 文档
至于 mybatis-plus 其他的高阶用法请自行学习,遇事不决选mybatis-plus,自然而然就会了。
最佳实践
核心思想
1. 对单表的操作首先考虑使用 mybatis-plus,实在不行的情况才自行实现(基本没有这种情况)
2. 优先考虑使用 Service 层的plus方法,其次才是使用 dao 层的plus方法。
3. 遇到单表操作不知道怎么写的情况,请查看官方文档
最佳实践
- 更新的最佳实践
mapper.update(po, new UpdateWrapper<Po>().eq("id", id)); 这样只会更新 po 中非空的属性。适合多字段更新
mapper.update(null, new UpdateWrapper<Po>().set("name", name).eq("id", id)); 这样只会更新 Po 表中的 name 字段。适合少量字段的更新,set也可以带过滤条件
mapper.updateById(po); 这样会自动根据 PO 中的 id 字段去更新数据,并且忽略空值
-
mybatis-plus自带的方法调用入口有:
- service层继承得到的方法
- dao层继承得到的方法
- po对象继承得到的方法
以上几种都可以用来操作数据表
-
过滤条件的使用
- 只有更新的时候使用
UpdateWrapper
来设置更新条件 - 其他操作都使用
QueryWrapper
来设置过滤条件
- 只有更新的时候使用
小结
实际上,mybatis-plus 本身代码的设计也非常好,后续应该仔细看看。掌握的关键在于多实践多看文档,但是千万不要忘记不论如何,mybatis-plus 只是一个工具。掌握工具和理解原理你觉得哪个更重要呢?
彩蛋
既然提到了工具,这里再推荐一个maven依赖库,非常好的第三方工具集,大名鼎鼎的 Hutool
,Hutool官方文档
hutool 虽然只是工具类库,但却是非常优秀的开源项目。千万不要以为其只是一个工具类库而忽视它。
以下引自 hutool 的介绍,有必要看看其设计思想:
Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅,让Java语言也可以“甜甜的”。
Hutool如何改变我们的Coding方式:
Hutool的目标是使用一个工具方法代替一段复杂代码,从而最大限度的避免“复制粘贴”代码的问题,彻底改变我们写代码的方式。
以计算MD5为例:
- 【以前】打开搜索引擎 -> 搜“Java MD5加密” -> 打开某篇博客-> 复制粘贴 -> 改改好用
- 【现在】引入Hutool -> SecureUtil.md5()
Hutool的存在就是为了减少代码搜索成本,避免网络上参差不齐的代码出现导致的bug。
Hutool使用规约唯一一条
遇到工具方法需要设计,首先去官方文档左侧列表查找有无现成的实现,不确定的话使用浏览器搜索 功能名 + hutool 关键字。
确实不行,才自行进行设计解决。
更多参见:java后端开发教程系列目录