Mybatis-Plus 插件学习
1.逻辑删除
在相应字段上添加注解
@TableLogic private Integer deleted;
说明:
使用mp自带方法删除和查找都会附带逻辑删除功能 (自己写的xml不会)
example 删除时 update user set deleted=1 where id =1 and deleted=0 查找时 select * from user where deleted=0
2.通用枚举类
比如一些状态属性
① 声明枚举
定义枚举
public enum AgeEnum implements IEnum<Integer> { ONE(1, "一岁"), TWO(2, "二岁"), THREE(3, "三岁"); private int value; private String desc; @Override public Integer getValue() { return this.value; } }
使用枚举
public class User{ /** * 名字 * 数据库字段: name varchar(20) */ private String name; /** * 年龄,IEnum接口的枚举处理 * 数据库字段:age INT(3) */ private AgeEnum age; /** * 年级,原生枚举(带{@link com.baomidou.mybatisplus.annotation.EnumValue}): * 数据库字段:grade INT(2) */ private GradeEnum grade; }
②配置扫描枚举
mybatis-plus: # 支持统配符 * 或者 ; 分割 typeEnumsPackage: com.baomidou.springboot.entity.enums ....
3.自动填充功能
自动填充,意味着就是设置默认值,不依赖数据库设置默认值,依赖程序实现。
定义填充方法
@Component public class MyMetaObjectHandler implements MetaObjectHandler { private static final Logger LOGGER = LoggerFactory.getLogger(MyMetaObjectHandler.class); @Override public void insertFill(MetaObject metaObject) { LOGGER.info("start insert fill ...."); this.setFieldValByName("createTime", new Date(),metaObject); this.setFieldValByName("updateTime", new Date(), metaObject); this.setFieldValByName("deleteFlag", 0, metaObject); } @Override public void updateFill(MetaObject metaObject) { LOGGER.info("start update fill ...."); this.setFieldValByName("updateTime", new Date(),metaObject); } }
使用填充
public class User { /** * 创建时间 */ @TableField(fill = FieldFill.INSERT) private Date createTime; /** * 修改时间 */ @TableField(fill = FieldFill.INSERT_UPDATE) private Date updateTime; /** * 逻辑删除 */ @TableField(fill = FieldFill.INSERT) @TableLogic private Integer deleteFlag; .... }
fill 属性 可选值
public enum FieldFill { /** * 默认不处理 */ DEFAULT, /** * 插入填充字段 */ INSERT, /** * 更新填充字段 */ UPDATE, /** * 插入和更新填充字段 */ INSERT_UPDATE }
4.sql 注入(拦截)功能
对 sql 进行改写,参考
DefaultSqlInjector
5.分页插件
//Spring boot方式 @EnableTransactionManagement @Configuration @MapperScan("com.baomidou.cloud.service.*.mapper*") public class MybatisPlusConfig { /** * 分页插件 */ @Bean public PaginationInterceptor paginationInterceptor() { return new PaginationInterceptor(); } }
使用
①调用 service 层的page 方法
/** * 列表 */ @GetMapping("/list") @ApiOperation(value = "分页", notes = "传入tenant", position = 4) public R<IPage<BusinessCard>> pageList(BusinessCard businessCard, Page<BusinessCard> page) { IPage<BusinessCard> pages = businessCardService.page(page, Wrappers.query(businessCard)); return R.data(pages); }
②手动编写 xml
定义 xml
<select id="selectPageVo" resultType="com.baomidou.cloud.entity.UserVo"> SELECT id,name FROM user WHERE state=#{state} </select>
定义mapper(需要传入 page参数,与查询参数)
public interface UserMapper{//可以继承或者不继承BaseMapper /** * <p> * 查询 : 根据state状态查询用户列表,分页显示 * 注意!!: 如果入参是有多个,需要加注解指定参数名才能在xml中取值 * </p> * * @param page 分页对象,xml中可以从里面进行取值,传递参数 Page 即自动分页,必须放在第一位(你可以继承Page实现自己的分页对象) * @param state 状态 * @return 分页对象 */ IPage<User> selectPageVo(IPage<User> page, @Param("state") Integer state); }
定义 service
public IPage<User> selectUserPage(Page<User> page, Integer state) { // 不进行 count sql 优化,解决 MP 无法自动优化 SQL 问题,这时候你需要自己查询 count 部分 // page.setOptimizeCountSql(false); // 当 total 为非 0 时(默认为 0),分页插件不会进行 count 查询 // 要点!! 分页返回的对象与传入的对象是同一个 return userMapper.selectPageVo(page, state); }
6.自定义 sql 使用 Wrapper
定义 xml
<select id="getAll" resultType="MysqlData"> SELECT * FROM mysql_data ${ew.customSqlSegment} </select>
定义 mapper
List<MysqlData> getAll(@Param(Constants.WRAPPER) Wrapper wrapper);
service 调用
mysqlMapper.getAll(Wrappers.<MysqlData>lambdaQuery().eq(MysqlData::getGroup, 1));
7.更新/保存时根据条件判断数据库唯一性
@Service public class BusinessCardServiceImpl extends BaseServiceImpl<BusinessCardMapper, BusinessCard> implements IBusinessCardService { @Override public boolean submit(BusinessCard businessCard) { LambdaQueryWrapper<BusinessCard> lqw = Wrappers.<BusinessCard>lambdaQuery().eq(BusinessCard::getTruename, businessCard.getTruename()); Integer cnt = baseMapper.selectCount(businessCard.getId() == null ? lqw : lqw.notIn(BusinessCard::getId, businessCard.getId())); if (cnt > 0) { throw new ApiException("当前名片已存在!"); } return saveOrUpdate(businessCard); } }
8.批处理
try (SqlSession batchSqlSession = sqlSessionBatch()) { int i = 0; for (AppFlowStatistics entity : entityList) { // 获取该对象的更新id,有则更新,否则则插入 Integer updateId = hasUpdateId(entity); if (ObjectUtil.isEmpty(updateId)) { batchSqlSession.insert(sqlStatement(SqlMethod.INSERT_ONE), entity); } else { entity.setId(updateId); MapperMethod.ParamMap<AppFlowStatistics> param = new MapperMethod.ParamMap<>(); param.put(Constants.ENTITY, entity); batchSqlSession.update(sqlStatement(SqlMethod.UPDATE_BY_ID), param); } if (i >= 1 && i % batchSize == 0) { batchSqlSession.flushStatements(); } i++; } batchSqlSession.flushStatements(); }
233