问题:
今天使用mybatis-plus分页查询时,构造QueryWrapper,默认是精确查询,但是我有部分字段是需要模糊查询的。
代码如下:
this.xxxService.page(page, new QueryWrapper<>(xxxEntity));
这是mybatis-plus自带的方法,很多地方都是这么使用的,为了不修改所有涉及到的方法。我决定修改下这个方法。
思路如下:
1.继承mybatis-plus的ServiceImpl类,重写page方法。
2.重新构建QueryWrapper。
3.基于注解构建QueryWrapper。
实现:
注解:查询参数注解(部分代码,in 、between and、order by 等未实现)
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface Query {
public static String EQ = "eq";
public static String LIKE = "like";
public static String LIKE_RIGHT = "likeRight";
String type() default EQ;
/**
* 别名,联合查询是表别名
*/
String alias() default "";
}
重写page方法。
public abstract class BaseServiceImpl<MAPPER extends BaseMapper<ENTITY>, ENTITY> extends ServiceImpl<MAPPER, ENTITY> {
@Override
public IPage<ENTITY> page(IPage<ENTITY> page, Wrapper<ENTITY> queryWrapper) {
QueryWrapper<ENTITY> entityQueryWrapper = buildQueryWrapper(queryWrapper.getEntity(), new QueryWrapper<>());
return this.baseMapper.selectPage(page, entityQueryWrapper);
}
/**
*通用方法构建queryWrapper
*/
private <T> QueryWrapper<ENTITY> buildQueryWrapper(T t,QueryWrapper<ENTITY> queryWrapper){
Field[] fields=t.getClass().getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
Object o;
try {
o = field.get(t);
buildQuery(field,o,queryWrapper);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
return queryWrapper;
}
/**
* 构建查询条件
*/
private QueryWrapper<ENTITY> buildQuery(Field field,Object o,QueryWrapper<ENTITY> queryWrapper){
if(ObjectUtil.isEmpty(o)){
return queryWrapper;
}
String dbName = xX2x_x(field.getName());
Query query = field.getAnnotation(Query.class);
if (query == null) {
queryWrapper.eq(dbName, o);
return queryWrapper;
}
dbName = new StringBuilder(query.alias()).append(dbName).toString();
if (Query.EQ.equals(query.type())) {
queryWrapper.eq(dbName, o);
return queryWrapper;
}
if (Query.LIKE_RIGHT.equals(query.type())) {
queryWrapper.likeRight(dbName, o);
return queryWrapper;
}
if (Query.LIKE.equals(query.type())) {
queryWrapper.like(dbName, o);
return queryWrapper;
}
return queryWrapper;
}
/**
* 将驼峰转为下划线
*
* @param str 字符串
* @return java.lang.String
*/
private String xX2x_x(String str) {
String to = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, str);
return to;
}
在实体上写上注解:
@Query(type = Query.LIKE)
private String name;
测试效果:
2023-07-22 10:55:33.508 DEBUG 61244 --- [ XNIO-1 task-2] c.s.m.t.bpjl.BpjlStoreMapper.selectPage : ==> Preparing: SELECT COUNT(1) FROM xxx_store WHERE name LIKE ?
2023-07-22 10:55:33.509 DEBUG 61244 --- [ XNIO-1 task-2] c.s.m.t.bpjl.BpjlStoreMapper.selectPage : ==> Parameters: %御溪雅苑东%(String)
可以模糊查询了。
以上是记录的开发过程,还有很多可以优化的,后期使用中慢慢优化。
我之所以这么使用是因为,代码都是使用插件生成的。不存在自定义的字段,没有字段错误的干扰。而且都是单表的查询。
复杂的查询,暂时不要这么使用,如果非要这么使用。
注意:
1、构造queryWrapper暂时不支持lambda表达式,
2、命名是驼峰命名转化的,要和数据库做好对应。