Mybatis-Plus常用点
本文章主要针对于mybatis-plus的一些功能、使用细节的梳理,并没有关于它的语法、方法进行整理,使用方法请自行查阅其他文章。
1. yml配置
以下为整理的常用yml配置,配置后无需配置mybatis且无需引入mybatis依赖
mybatis-plus:
mapper-locations: classpath:mapper/**/*.xml # mapper映射文件(默认存在)
type-aliases-package: com.itheima.mp.demain # 别名包
configuration:
map-underscore-to-camel-case: true # 是否开启下划线与驼峰的映射(默认打开)
cache-enabled: false # 是否开启二级缓存(默认关闭)
global-config: # 全局配置
db-config:
id-type: auto #id+1自增策略(默认assign_id雪花算法)
update-strategy: not_empty #null与''都忽略(默认not_null:只忽略null)
# 下面的配置:将所有的删除语句更改为修改语句
logic-delete-field: isDelete # 是否删除;全局逻辑删除的实体字段名,字段类型可以是boolean、integer
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
2. 注解用法
以下为整理的常用注解,基本都是标记类表之间的对应关系
@Data
@TableName("tb_user")
public class User {
//此处配置主键策略优先级 > yml文件
@TableId(value = "id",type = IdType.AUTO)
private Long id;
//与数据库关键字冲突(必加)
@TableField("`order`")
private Integer order;
//is前缀且类型为Boolean(必加)
@TableField("is_delete")
private Boolean isDelete;
//数据表中不存在的(必加)
@TableField(exist = false)
private String address;
}
3. 代码生成器
代码生成器根据表名生成mvc各层,实现快速写代码。
- 新版idea在tool里找,老版会出现other菜单
- 绑定后,根据需求选择生成,可以自动生成mapper.xml
4. DB静态工具
Db静态工具跟IService功能几乎一致,主要用来处理依赖冲突问题,在两个service中可以相互依赖
import com.baomidou.mybatisplus.extension.toolkit.Db;
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
@Autowired
private AddressMapper addressMapper;//不推荐
@Override
public void test() {
//在UserServiceImpl中不推荐注入AddressMapper
addressMapper.saveAddress(new Address());
Db.lambdaUpdate(Address.class).update(new Address());//推荐使用Db静态工具
}
}
5. 枚举处理器
枚举处理器主要用来处理表中数据存储为0,1状态时,通过枚举类对0,1表示内容添加备注
- 配置全局枚举处理器
mybatis-plus:
configuration:
default-enum-type-handler: com.baomidou.mybatisplus.core.handlers.MybatisEnumTypeHandler #全局枚举处理器
2. 编写枚举类
import com.baomidou.mybatisplus.annotation.EnumValue;
import com.fasterxml.jackson.annotation.JsonValue;
import lombok.Getter;
@Getter
public enum UserStatus {
STOP_USING(1,"已停用"),
USING(0,"启用中");
@EnumValue //表示与数据库交互的值
private final Integer status;
@JsonValue //表示返回给前端的值
private final String desc;
UserStatus(Integer status, String desc) {
this.status = status;
this.desc = desc;
}
}
3. 查询数据,查询0状态的用户,返回启用中(注:直接打印不会出现想要字符)
@PostMapping("test")
public List<User> test01(){
return userService.lambdaQuery()
.eq(User::getStatus,UserStatus.USING).list();
}
6. dto与vo的分页查询
mybatis-plus依旧可以使用常规分页方法,这边介绍mybatis-plus自带的。
- 添加分页插件,配置mp的拦截器
@Configuration
public class MybatisConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
// 1.初始化核心插件
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 2.添加分页插件
PaginationInnerInterceptor pageInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
pageInterceptor.setMaxLimit(1000L); // 设置分页上限
interceptor.addInnerInterceptor(pageInterceptor);
return interceptor;
}
}
2. 写两个分页父类,先介绍参数类
@Data
public class PageParam {
/**
* 页码
*/
@TableField(exist = false)
private Integer pageNum = 1;
/**
* 总页数
*/
@TableField(exist = false)
private Integer pageSize = 5;
/**
* 排序字段
*/
@TableField(exist = false)
private String sortBy;
/**
* 是否升序
*/
@TableField(exist = false)
private Boolean isAsc;
/**
* 空排序字段传递排序规则
* @param items
* @return
* @param <T>
*/
public <T> Page<T> toMpPage(OrderItem ... items){
// 分页条件
Page<T> page = Page.of(pageNum, pageSize);
if(StrUtil.isNotBlank(sortBy)){
page.addOrder(new OrderItem(sortBy, isAsc));
}else if(sortBy != null){
page.addOrder(items);
}
return page;
}
/**
* 设定默认值:"更新字段"降序
* @return
* @param <T>
*/
public <T> Page<T> toMpPageDefaultSortByUpdateTime(){
return toMpPage(new OrderItem("update_time", false));
}
}
3. 返回数据result类
@Data
public class PageResult<T> {
/**
* 总条数
*/
private Long total;
/**
* 总页数
*/
private Long pages;
/**
* 当前页数据
*/
private List<T> list;
/**
* 通过BeanUtil拷贝的形式,实现 dto -> vo
* @param po
* @param clazz
* @return
* @param <PO>
* @param <VO>
*/
public static <PO, VO> PageResult<VO> of(Page<PO> po, Class<VO> clazz){
PageResult<VO> result = new PageResult<>();
// 总条数
result.setTotal(po.getTotal());
// 总页数
result.setPages(po.getPages());
// 当前页数据
List<PO> records = po.getRecords();
if(CollUtil.isEmpty(records)){
result.setList(Collections.emptyList());
return result;
}
// 拷贝VO
result.setList(BeanUtil.copyToList(records, clazz));
return result;
}
/**
* 通过传递函数式接口定义规则,实现 dto -> vo
* @param po
* @param convertor
* @return
* @param <PO>
* @param <VO>
*/
public static <PO, VO> PageResult<VO> of(Page<PO> po, Function<PO, VO> convertor){
PageResult<VO> result = new PageResult<>();
// 总条数
result.setTotal(po.getTotal());
// 总页数
result.setPages(po.getPages());
// 当前页数据
List<PO> records = po.getRecords();
if(CollUtil.isEmpty(records)){
result.setList(Collections.emptyList());
return result;
}
// 拷贝VO
result.setList(records.stream().map(convertor).collect(Collectors.toList()));
return result;
}
}
4. 案例1
PageResult<UserVo> list = userService.pageSelect(user);
public PageResult<UserVo> pageSelect(User user) {
//通过传递来的参数点出方法包装为page对象
Page<User> page = user.toMpPageDefaultSortByUpdateTime();
//分页+条件查询
String username = user.getUsername();
Page<User> pageSelect = lambdaQuery()
.like(username != null, User::getUsername, username)
.page(page);
//一般情况,使用基础的BeanUtil赋值,需要Vo和user字段名一致
return PageResult.of(pageSelect, UserVo.class);
}
5. 案例2
PageResult<UserVo> list = userService.pageSelect2(user);
@Override
public PageResult<UserVo> pageSelect2(User user) {
//通过传递来的参数点出方法包装为page对象
Page<User> page = user.toMpPageDefaultSortByUpdateTime();
//分页+条件查询
String username = user.getUsername();
Page<User> pageSelect = lambdaQuery()
.like(username != null, User::getUsername, username)
.page(page);
return PageResult.of(pageSelect,
//传递匿名内部类 - 处理查询出的数据与Vo的转化
userTest -> {
//这里演示拷贝赋值+处理username最后两个字符为**
UserVo userVo = BeanUtil.copyProperties(userTest, UserVo.class);
userVo.setTest(userVo.getUsername().substring(0, userVo.getUsername().length() - 2) + "**");
return userVo;
});
}