MyBatisPlus查询对象转QueryWrapper工具类
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MyBatisPlus查询对象转QueryWrapper工具类相关的知识,希望对你有一定的参考价值。
技术背景
在使用MyBatisPlus技术实际项目中,尤其是后台管理系统之类的项目中,经常会出现大量的需要将查询对象转换成QueryWrapper的应用场景,这时候就需要编写出现大量的转换代码,比如:
待转换的查询实体类
@Getter
@Setter
@ToString(callSuper = true)
public class MemberQuery extends BaseQuery
/**
* 昵称
*/
private String nickname;
/**
* 性别:1女 2男 3未知
*/
private Integer gender;
/**
* 生日:下限
*/
private LocalDate start;
/**
* 生日:上限
*/
private LocalDate end;
/**
* 电话
*/
private String tel;
/**
* 外键:角色编号
*/
private Long roleId;
/**
* 状态:1未激活 2激活
*/
private Integer state;
@Builder
public MemberQuery(Integer pageNum, Integer pageSize, String nickname, Integer gender, LocalDate start, LocalDate end, String tel, Long roleId, Integer state)
super(pageNum, pageSize);
this.nickname = nickname;
this.gender = gender;
this.start = start;
this.end = end;
this.tel = tel;
this.roleId = roleId;
this.state = state;
上面查询类引用的BaseQuery封装了分页信息,具体代码如下:
@Setter
@ToString
@AllArgsConstructor
public class BaseQuery
/**
* 页码
*/
private Integer pageNum;
/**
* 页面大小
*/
private Integer pageSize;
public Integer getPageNum()
return pageNum == null ? 1 : pageNum;
public Integer getPageSize()
return pageSize == null ? GlobalConst.PAGE_SIZE : pageSize;
在Controller中进行转换
@PostMapping("/list")
public ResultBean list(@RequestBody MemberQuery memberQuery)
IPage<Member> page = new Page<>(memberQuery.getPageNum(), memberQuery.getPageSize());
LambdaQueryWrapper<Member> queryWrapper = new LambdaQueryWrapper<>();
if (memberQuery.getNickname() != null)
queryWrapper.like(Member::getNickname, memberQuery.getNickname());
if (memberQuery.getTel() != null)
queryWrapper.like(Member::getTel, memberQuery.getTel());
if (memberQuery.getGender() != null)
queryWrapper.eq(Member::getGender, memberQuery.getGender());
if (memberQuery.getRoleId() != null)
queryWrapper.eq(Member::getRoleId, memberQuery.getRoleId());
if (memberQuery.getState() != null)
queryWrapper.eq(Member::getState, memberQuery.getState());
if (memberQuery.getStart() != null)
queryWrapper.ge(Member::getBirth,memberQuery.getStart());
if(memberQuery.getEnd() != null)
queryWrapper.le(Member::getBirth,memberQuery.getEnd());
memberService.page(page, queryWrapper);
PageBean<Member> pageBean = PageBean.init(page);
return ResultBeanUtil.success().buildData("pageBean",pageBean);
上面大量的转换代码,不仅写起来烦琐,而且也不优雅。此时可以采用注解+反射技术编写一个工具类:将Query对象转换成Wrapper,具体代码如下:
优化方案
表示关系运算的接口
public interface Logic
String and = "AND";
String or = "OR";
表示逻辑运算的枚举
- Between
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Between
String logic() default Logic.and;
- EQ
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface EQ
String logic() default Logic.and;
String value() default "";
- IN
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface IN
String logic() default Logic.and;
String value() default "";
- Like
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Like
String logic() default "AND";
String value() default "";
- NE
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface NE
String logic() default Logic.and;
String value() default "";
封装区间的Bean
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class RangeBean<T>
/**
* 下限
*/
private T start;
/**
* 上限
*/
private T end;
具体转换的工具类
public class QueryWrapperUtil<T>
/**
* 将查询对象转换成MyBatisPlus中的QueryWrapper
* @param query
* @param <T>
* @return
*/
public static <T> QueryWrapper<T> build(Object query)
QueryWrapper<T> queryWrapper = new QueryWrapper<>();
//获取Query类中都有哪些属性
final Field[] fields = query.getClass().getDeclaredFields();
for (Field field : fields)
field.setAccessible(true);
java.lang.Object fieldValue = null;
try
fieldValue = field.get(query);
catch (IllegalAccessException e)
e.printStackTrace();
if (fieldValue != null)
//获取Query类属性上的注解
final Annotation[] annotations = field.getAnnotations();
for (Annotation annotation : annotations)
//获取Query类属性的名称
final String fieldName = field.getName();
//获取Query类对应的表字段名
final String columnName = StringUtil.hump2underscore(fieldName);
//获取Query类属性上的注解类型的字节码
final Class<? extends Annotation> annotationType = annotation.annotationType();
if (EQ.class == annotationType)
EQ eq = (EQ) annotation;
fun(eq.logic(), queryWrapper);
queryWrapper.eq(columnName, fieldValue);
else if (Like.class == annotationType)
Like like = (Like) annotation;
fun(like.logic(), queryWrapper);
queryWrapper.like(columnName, fieldValue);
else if (IN.class == annotationType)
IN in = (IN) annotation;
fun(in.logic(), queryWrapper);
queryWrapper.in(columnName, fieldValue);
else if (NE.class == annotationType)
NE ne = (NE) annotation;
fun(ne.logic(), queryWrapper);
queryWrapper.ne(columnName, fieldValue);
else if (Between.class == annotationType)
Between between = (Between) annotation;
fun(between.logic(), queryWrapper);
RangeBean rangeBean = (RangeBean) fieldValue;
queryWrapper.between(columnName, rangeBean.getStart(), rangeBean.getEnd());
return queryWrapper;
/**
* 添加or关系
* @param logic
* @param queryWrapper
* @param <T>
*/
private static <T> void fun(String logic, QueryWrapper<T> queryWrapper)
if ("or".equalsIgnoreCase(logic))
queryWrapper.or();
优化方案:工具类应用
@PostMapping("/list")
public ResultBean list(@RequestBody MemberQuery memberQuery)
IPage<Member> page = new Page<>(memberQuery.getPageNum(), memberQuery.getPageSize());
QueryWrapper<Member> queryWrapper = QueryWrapperUtil.build(memberQuery);
memberService.page(page, queryWrapper);
PageBean<Member> pageBean = PageBean.init(page);
return ResultBeanUtil.success().addData("pageBean",pageBean);
以上是关于MyBatisPlus查询对象转QueryWrapper工具类的主要内容,如果未能解决你的问题,请参考以下文章
MybatisPlus resultMap标签collection的注解写法