MyBatis Plus简述
- MyBatis Plus(MP)是一个MyBatis的增强工具。
MyBatis Plus在 MyBatis 的基础上只做增强,不做改变,其主要特性有:
- 无侵入:只做增强不做改变,引入它不会对现有工程产生影响。
- 损耗小:启动即会自动注入基于CRUD(增删改查),性能进本无损耗,直接面向对象操作。
- 强大的CRUD操作:内置通用Mapper、通用Service,仅仅通过少量配置即可实现单表部分 CRUD操作,更有强大的条件构造器,满足各类使用需求。
- 支持Lambda形式调用: 通过Lambda表达式,方便的编写各类查询条件,无需再担心字段写错
- 支持主键自动生成:支持多达4种主键策略 (内含分布式唯一ID生成器Sequence),可自由配置,完美解决主键问题
- 支持ActiveRecord模式: 支持ActiveRecord形式调用,实体类只需继承Model类即可进行强大的CRUD操作
- 支持自定义全局通用操作:支持全局通用方法注入 (Write once,use anywhere) 自动更新时间有所体现
- 内置代码生成器: 采用代码或者Maven插件可快速生成Mapper、Model、ServiceController层代码,支持模板引擎,更有超多自定义配置等您来使用
- 内置分页插件:基于MyBatis物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通List查询。
- 分页插件支持多种数据库::支持MySQL、MariaDB、0racle、DB2、H2、HSQL、SQLite、Postgre、SQLServer等多种数据库。
- 内置性能分析插件:可输出SQL语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询。
- 内置全局拦截插件:提供全表delete、update操作智能分析阻断,也可自定义拦截规则,预防误操作。
- MyBatis plus可以任何能使用MyBatis进行CRUD,并且支持标准SQL的数据库,具体支持情况如下:
- MySQL,Oracle,DB2,H2,HSQL,SQLite,PostgreSQL,SQLServer,Phoenix,Gauss ,ClickHouse,Sybase,OceanBase,Firebird,Cubrid.Goldilocks,csiidb
- 达梦数据库,虚谷数据库,人大金仓数据库,南大通用 (华库) 数据库,南大通用数据库,神通数据库,瀚高数据库。
MyBatis Plus基本使用
- 首先,你需要自定义实体类,并且:
1)在类上使用@TableName注解指定数据表的名称
1. 例如配置为@TableName("content_tag”)
2. 如果没有通过以上注解指定名称,则MyBatis plus会自动根据你的实现类的名称转换得到表名称,例如Tag类对应的默认的表名称就是tag
2)在类中与主键对应的属性上使用aTableId注解指定主键的值如何处理
1. 例如配置为@TableId(type = IdTypeAUTO)
2. 如果没有通过以上注解进行配置,则MyBatis plus默认会自动处理主键字段对应的值
- 然后,与使用普通的MyBatis相同,需要自定义数据访问接口,不同的是,此接口应该继承自BaseMapper,且继承的泛型应该是尝试处理的数据表所对应的实体类的类型,例如:
public interface TagMapper extends BaseMapper<Tag>{
}
- 至此,就已经可以使用MyBatis Plus提供的各种数据访问功能,包括:(没有做批量插入、批量修改,自己写)
小结:
- MyBatis Plus 没有做批量插入、批量修改,需要自己写;
- 提供的查询功能,一般是不太适用的,因为他的返回值都是泛型<T>,而这个T就是接口继承BaseMapper<T>中的T,也就是实体类,而我们大多数查询结果不会返回全部数据的对象,而是根据业务需要什么数据,自己在进行封装(VO),所以不太实用;
- 统计查询还是可以使用的( selectCount() )
1)没有条件进行统计时,参数值给null,查询表中所有数据;
@Test
void selectCount() {
Integer count = mapper.selectCount(null);
System.out.println("统计数据完成,统计结果:" + count);
}
2)有条件查询。方法参数:(QueryWrapper<T>)
@Test
void selectCountByName() {
String name = "测试名称";
QueryWrapper<Tag> wrapper = new QueryWrapper<>();
wrapper.eq("name", name);
Integer count = mapper.selectCount(wrapper);
System.out.println("统计数据完成,统计结果:" + count);
}
MyBatis Plus使用建议
- 关于MyBatis plus的使用建议汇总如下:
1)插入单条数据时,使用MyBatis plus提供的方法;
2)批量插入数据时,自定义方法并配置映射的SQL语句;
3)根据id删除单条数据时,使用MyBatis plus提供的方法;
4)根据id批量删除数据时,使用MyBatis plus提供的方法;
5)更新数据时,使用MyBatis plus提供的方法;
6)统计查询时,使用MyBatis plus提供的方法;
7)除了统计查询以外的所有查询,都自定义方法并配置映射的SQL语句。
自动更新时间
- 使用MyBatis plus自动更新创建时间、修改时间的示例
- 使用@Component组件注解,MyBatis plus会自动装配
- 实现接口MetaObjectHandler,自动装配按照类型来装配的,实现此接口达到类型匹配才能自动装配成功。
- 可以看到两个自定义的常量,其值必须与实体类中需要子发动更新时间的属性名保持一致。
@Component
public class TimeMetaObjectHandler implements MetaObjectHandler {
public static final String FIELD_CREATE TIME = "gmtCreate";
public static final String FIELD UPDATE_TIME ="mtModified",
@Override
public void insertFill(MetaObiect metaObiect) {
LocalDateTime now = LocalDateTime.now();
this.setFieldValBvName(FIELD CREATE TIME,now,metaObiect);
this.setFieldValByName(FIELD_UPDATE_TIME,now,metabject);
}
@Override
public void updateFill(MetaObject metaObject) {
LocalDateTime now = LocaDateTime.now();
this.setFieldValByName(FIELD UPDATE TIME,now,metaObject);
}
}
- 最后一步:需要在实体类中自动更新时间字段名上加注解
/**
* 数据创建时间
*/
@TableField(fill = FieldFill.INSERT)
private LocalDateTime gmtCreate;
/**
* 数据最后修改时间
*/
@TableField(fill = FieldFill.INSERT_UPDATE)
private LocalDateTime gmtModified;
使用MyBatis Plus框架 配置Mapper.xml
- 在application.properties文件配置(当Mapper.xml所在的包名是mapper时可以不用配置)
- 当配置信息有误,会报异常(BindingException),这时候去检查xml文件中的mapper标签中的namepasesh的属性值和执行语句中的id属性值是否正确,或者查看properties文件中是否配置有误。
- 配置路径classpath中 /** 表示多级文件夹
# 配置SQL语句的XML文件的位置(未使用mybatis-plus框架)
mybatis.mapper-locations: classpath:mappers/**/*.xml
# 配置SQL语句的XML文件的位置(使用mybatis-plus框架)
mybatis-plus.mapper-locations: classpath:mappers/**/*.xml
实体类中的应用变化
1. 不改变实体类,测试运行会报错,MyBatis Plus框架默认将实体类的名字当作数据库表名,倘若实体类名和数据库表名不一致,它就会不认识数据库表名,然后默认修改以实体类名小写的数据库表名,而实际上数据库表里就不存在这张表,因此报错。
解决方案:通过在实体类上加一个注解@TableName("表名") 来告诉MyBatis Plus框架数据库表名
2. 支持主键自动生成:支持多达4种主键策略;插入数据库的id值如下图所示:
此id值就是在调用接口中的插入方法时,MyBatis Plus框架会自动生成id值,该值的效果可能不是我们想要的,还是比较倾向于从1开始编号。
解决方案:在数据库表对应的实体类中的id属性上加一个注解@TableId(type = IdType.AUTO),加上此注解之后,id的值将交由数据库自动编号,要想达到id值从1开编号目的,还要执行一个SQL指令 “truncate 表名” 此命令将整张表还原成初始的状态(执行这句命令的前提是表里面之前插有测试数据)。