MyBatis-Puls简介
(1)MyBatis-Plus(简称MP),是MyBatis的增强工具,在MyBatis的基础上只做增强不做改变,为简化开发,提高效率而生
(2)MyBatis-Puls特性
| 特性 | 简介 |
|---|
| 无侵入 | 只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑 |
| 损耗小 | 启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作,BaseMapper |
| 强大的 CRUD 操作 | 内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作, 更有强大的条件构造器,满足各类使用需求,简单的CRUD操作不用自己编写 |
| 支持 Lambda 形式调用 | 通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错 |
| 支持主键自动生成 | 支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题 |
| 支持 ActiveRecord 模式 | 支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作 |
| 支持自定义全局通用操作 | 支持全局通用方法注入( Write once, use anywhere ) |
| 内置代码生成器 | 采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码, 支持模板引擎,更有超多自定义配置等您来使用(自动生成代码) |
| 内置分页插件 | 基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询 分页插件支持多种数据库:MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库 |
| 内置性能分析插件 | 可输出 SQL 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询 |
| 内置全局拦截插件 | 提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作 |
BaseMapper<T>接口
MyBatis-Plus中的基本CRUD在内置的BaseMapper<T>接口中都已得到了实现,因此继承该接口后可以直接使用其中的方法
增加(Insert)
删除(Delete)
1 2 3 4 5 6 7 8 9 10 11
| int deleteById(Serializable id);
int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper);
|
修改(Update)
1 2 3 4 5
| int updateById(@Param(Constants.ENTITY) T entity);
int update(@Param(Constants.ENTITY) T updateEntity, @Param(Constants.WRAPPER) Wrapper<T> whereWrapper);
|
查询(Selete)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| T selectById(Serializable id);
T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
IPage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
IPage<Map<String, Object>> selectMapsPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
|
通用Service服务
MyBatis-Plus中有一个Iservice<T>接口和其实现类ServiceImpl,封装了常见的业务层逻辑,泛型 T 为任意实体对象,在使用的时候仅需在自己定义的Service接口中继承IService接口,在自己的实现类中实现自己的Service并继承ServiceImpl即可
增加(Save、SaveOrUpdate)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| boolean save(T entity);
boolean saveBatch(Collection<T> entityList);
boolean saveBatch(Collection<T> entityList, int batchSize);
boolean saveOrUpdate(T entity);
boolean saveOrUpdate(T entity, Wrapper<T> updateWrapper);
boolean saveOrUpdateBatch(Collection<T> entityList);
boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize);
|
删除(Remove)
1 2 3 4 5 6 7 8 9 10 11
| boolean remove(Wrapper<T> queryWrapper);
boolean removeById(Serializable id);
boolean removeByMap(Map<String, Object> columnMap);
boolean removeByIds(Collection<? extends Serializable> idList);
|
修改(Update)
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| boolean update(Wrapper<T> updateWrapper);
boolean update(T updateEntity, Wrapper<T> whereWrapper);
boolean updateById(T entity);
boolean updateBatchById(Collection<T> entityList);
boolean updateBatchById(Collection<T> entityList, int batchSize);
|
查询(Get、List、Count)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| T getById(Serializable id);
T getOne(Wrapper<T> queryWrapper);
T getOne(Wrapper<T> queryWrapper, boolean throwEx);
Map<String, Object> getMap(Wrapper<T> queryWrapper);
<V> V getObj(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);
List<T> list();
List<T> list(Wrapper<T> queryWrapper);
Collection<T> listByIds(Collection<? extends Serializable> idList);
Collection<T> listByMap(Map<String, Object> columnMap);
List<Map<String, Object>> listMaps();
List<Map<String, Object>> listMaps(Wrapper<T> queryWrapper);
List<Object> listObjs();
<V> List<V> listObjs(Function<? super Object, V> mapper);
List<Object> listObjs(Wrapper<T> queryWrapper);
<V> List<V> listObjs(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);
int count();
int count(Wrapper<T> queryWrapper);
|
分页(Page)
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| T getById(Serializable id);
T getOne(Wrapper<T> queryWrapper);
T getOne(Wrapper<T> queryWrapper, boolean throwEx);
Map<String, Object> getMap(Wrapper<T> queryWrapper);
<V> V getObj(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);
|
常用注解
| 注解 | 简介 |
|---|
| @TableName | 用于标识实体类对应的表名,在实体类类型上添加@TableName(“t_user”) |
| @TableId | 将某个属性对应的字段标识为主键 value属性:用于指定表中的主键字段 type属性:定义主键策略,默 认为IdType.ASSIGN_ID IdType.ASSIGN_ID:基于雪花算法的策略生成数据id,与数据库id是否设置自增无关 IdType.AUTO:使用数据库的自增策略,数据库需要设置了id自增, 否则无效 |
| @TableField | 设置属性所对应的字段名,如果没有对应字段则设置exist=false |
| @TableLogic | 设置逻辑删除,1已删除,0未删除,使用场景:可以进行数据恢复 物理删除:真实删除,将对应数据从数据库中删除,之后查询不到此条被删除的数据 逻辑删除:虚假删除,将对应数据中代表是否被删除字段的状态修改为“被删除状态”,之后在数据库中仍旧能看到此条数据记录 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| @TableName("t_user") public class User { @TableId(value = "id", type = IdType.AUTO) private Long id; @TableField("username") private String username; private String password; private String gender; private Integer age; private String email; @TableLogic private Integer isDelted; }
|
条件构造器
(1)MP提供了条件构造器Wrapper,可以方便实现稍复杂点的条件查询,很复杂的还是要xml编写sql
(2)mp的条件构造抽象类的结构
| 抽象类 | 简介 |
|---|
| Wrapper | 条件构造抽象类,最顶端父类 |
| AbstractWrapper | 用于查询条件封装,生成 sql 的 where 条件 |
| QueryWrapper | Entity 对象封装操作类,不是用lambda语法 |
| UpdateWrapper | Update 条件封装,用于Entity对象更新操作 |
| AbstractLambdaWrapper | Lambda 语法使用 Wrapper统一处理解析lambda获取数据库字段 |
| LambdaQueryWrapper | 用于Lambda语法使用的查询Wrapper |
| LambdaUpdateWrapper | Lambda 更新封装Wrapper |

常用配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| mybatis-plus: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl global-config: db-config: table-prefix: t_ id-type: auto logic-delete-field: delFlag logic-delete-value: 1 logic-not-delete-value: 0 mapper-locations: mapper/**/*.xml type-aliases-package: com.wen.pojo type-enums-package: com.wen.enums
|
配置分页
(1)创建MybatisPlusConfig配置类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| @Configuration @MapperScan("com.wen.mapper") public class MybatisPlusConfig {
@Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(); paginationInnerInterceptor.setOptimizeJoin(true); paginationInnerInterceptor.setDbType(DbType.MYSQL); paginationInnerInterceptor.setOverflow(true); interceptor.addInnerInterceptor(paginationInnerInterceptor); OptimisticLockerInnerInterceptor optimisticLockerInnerInterceptor = new OptimisticLockerInnerInterceptor(); interceptor.addInnerInterceptor(optimisticLockerInnerInterceptor); return interceptor; }
}
|
(2)测试使用案例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| @Test void testPage() { Page<User> page = new Page<>(2, 5); userMapper.selectPage(page, null); System.out.println("是否有下一页:"+page.hasNext()); System.out.println("是否有上一页:"+page.hasPrevious()); System.out.println("当前页码值:" + page.getCurrent()); System.out.println("每页显示数:" + page.getSize()); System.out.println("总记录数:" + page.getTotal()); System.out.println("总页面数:" + page.getPages()); System.out.println("详细数据:" + page.getRecords()); }
|
属性自动填充
MetaObjectHandler接口是mybatisPlus提供的扩展接口,可以在插入或者更新数据的时候,为一些字段指定默认值。实现这个需求的方法不止一种,在sql层面也可以做到,在建表的时候也可以指定默认值。
(1)实体类上边加上@TableField注解指定进行属性填充的时机(更新、插入、或者更新和插入)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| @SuppressWarnings("serial") @Data @NoArgsConstructor @AllArgsConstructor @TableName("comment") public class Comment { @TableField(fill = FieldFill.INSERT) private Long createBy;
@TableField(fill = FieldFill.INSERT) private Date createTime;
@TableField(fill = FieldFill.INSERT_UPDATE) private Long updateBy;
@TableField(fill = FieldFill.INSERT_UPDATE) private Date updateTime; }
|
(2)类实现MetaObjectHandler接口,重写里面的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
|
@Slf4j @Component public class MyMetaObjectHandler implements MetaObjectHandler {
@Override public void insertFill(MetaObject metaObject) { log.info("插入时自动填充"); this.setFieldValByName("createTime", new Date(), metaObject); this.setFieldValByName("createBy", "123", metaObject); this.setFieldValByName("updateTime", new Date(), metaObject); this.setFieldValByName("updateBy", "123", metaObject); }
@Override public void updateFill(MetaObject metaObject) { log.info("更新时自动填充"); this.setFieldValByName("updateTime", new Date(), metaObject); this.setFieldValByName(" ", "123", metaObject); } }
|