d42:MyBatisPlus逻辑删除,枚举处理器,JSON处理器,分页插件
MyBatisPlus 学习笔记
MyBatisPlus逻辑删除,枚举处理器,JSON处理器,分页插件
1. 逻辑删除
在实际开发中,我们有时不希望真正删除数据,而是将它们隐藏起来。逻辑删除可以帮助我们实现这一需求。通过配置逻辑删除字段,查询时会自动带上逻辑删除字段的条件。
配置逻辑删除
在application.yml
文件中添加以下配置:
global-config:db-config:id-type: auto # 全局主键策略update-strategy: not_null # 默认更新策略logic-delete-field: deleted # 逻辑删除字段logic-delete-value: 1 # 逻辑删除字段值logic-not-delete-value: 0 # 逻辑未删除字段值
使用逻辑删除
在实体类中添加逻辑删除字段,并在MyBatisPlus的配置中启用逻辑删除功能。这样,每次查询时都会自动过滤掉被逻辑删除的记录。
2. 枚举处理器
枚举处理器可以帮助我们将枚举类型与数据库中的数值字段进行映射。通过配置全局处理器,我们可以方便地使用枚举类型。
配置全局处理器
在MyBatis配置文件中添加以下配置:
configuration:default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler
使用枚举处理器
在枚举类对应的数值字段上添加@EnumValue
注解:
@Getter
public enum UserStatus {NORMAL(1, "正常"),FREEZE(2, "冻结");@EnumValueprivate final int value;private final String desc;UserStatus(int value, String desc) {this.value = value;this.desc = desc;}
}
3. JSON处理器
处理数据库中的JSON字段可能会比较复杂。MyBatisPlus提供了JacksonTypeHandler
来方便地处理JSON字段。
定义JSON字段对应的类
@Data
@AllArgsConstructor(staticName = "of")
@NoArgsConstructor
public class UserInfo {private Integer age;private String intro;private String gender;
}
在实体类中使用JSON处理器
在实体类中使用@TableField
注解指定字段类型,并使用JacksonTypeHandler
:
@TableName(value = "user", autoResultMap = true)
@Data
public class User {@TableField(typeHandler = JacksonTypeHandler.class)private UserInfo info;
}
在Mapper中使用JSON处理器
如果在mapper.xml
中定义了SQL逻辑,需要指定处理器:
<insert id="saveUser" parameterType="com.itheima.mp.domain.po.User">INSERT INTO `user` (`id`, `username`, `password`, `phone`, `info`, `balance`)VALUES(#{id}, #{username}, #{password}, #{phone}, #{info,typeHandler=com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler}, #{balance});
</insert>
4. 分页插件
MyBatisPlus的分页插件可以方便地实现分页查询功能。在配置类中添加分页插件即可。
配置分页插件
@Configuration
public class MyBatisConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);paginationInnerInterceptor.setMaxLimit(1000L);interceptor.addInnerInterceptor(paginationInnerInterceptor);return interceptor;}
}
编写通用的分页查询类
@Data
public class PageQuery {private Integer pageNo;private Integer pageSize;private String sortBy;private Boolean isAsc;public <T> Page<T> toMpPage(OrderItem... orders) {Page<T> p = Page.of(pageNo, pageSize);if (sortBy != null) {p.addOrder(new OrderItem(sortBy, isAsc));return p;}if (orders != null) {p.addOrder(orders);}return p;}public <T> Page<T> toMpPage(String defaultSortBy, boolean isAsc) {return this.toMpPage(new OrderItem(defaultSortBy, isAsc));}public <T> Page<T> toMpPageDefaultSortByCreateTimeDesc() {return toMpPage("create_time", false);}public <T> Page<T> toMpPageDefaultSortByUpdateTimeDesc() {return toMpPage("update_time", false);}
}
编写分页DTO
@Data
public class PageDTO<T> {private Long total;private Long pages;private List<T> list;public static <PO, VO> PageDTO<VO> of(Page<PO> page, Class<VO> voClass) {PageDTO<VO> pageDTO = new PageDTO<>();pageDTO.setTotal(page.getTotal());pageDTO.setPages(page.getPages());List<PO> records = page.getRecords();if (records == null) {pageDTO.setList(Collections.emptyList());return pageDTO;}pageDTO.setList(BeanUtil.copyToList(records, voClass));return pageDTO;}public static <PO, VO> PageDTO<VO> of(Page<PO> page, Function<PO, VO> convertor) {PageDTO<VO> pageDTO = new PageDTO<>();pageDTO.setTotal(page.getTotal());pageDTO.setPages(page.getPages());List<PO> records = page.getRecords();if (records == null) {pageDTO.setList(Collections.emptyList());return pageDTO;}pageDTO.setList(records.stream().map(convertor).collect(Collectors.toList()));return pageDTO;}
}