传统的mybatis plus 查询写法
对于常规的mybatis单表查询,我们既可以采用LambdaQueryWrapper查询,也可以使用QueryWrapper查询。
LambdaQueryWrapper具有防误写、规范代码等好处,但是缺点是无法在复杂的多表查询中使用。
相比较来说,使用QueryWrapper编写查询更加灵活,可以适应更复杂的查询场景。
我们首先看一个QueryWrapper查询的例子
-
public
List<UserMo>
list (UserForm userForm) {
-
QueryWrapper<UserMo> queryWrapper =
new QueryWrapper<>();
-
queryWrapper.like(StringTool.isNotEmpty(userForm.getUserName(),
"name", userForm.getUserName());
-
queryWrapper.eq(StringTool.isNotEmpty(userForm.getMobile(),
"mobile", userForm.getMobile());
-
// 其它的查询条件...
-
return userMapper.selectList(queryWrapper);
-
}
对于上面的查询语句来说,可以很好的对前端传值进行处理,当userForm中有前端传值的话,就会往SQL语句中加一条where条件。
但是这样做的话会有一个相对来说比较复杂的点,那就是当UserForm中的字段过于多的时候,我们也许得写十几行的这种重复判断的语句。
通过自定义注解来解决通用查询条件过多问题
通过观察mybatis plus 对于queryWrapper相关查询方法的列子,我们可以找出一类通用方法
可以看出来这几个方法都是传的同样的三个参数。
我想对于这些简单的通用的查询条件,也许可以有一个通用的方法来填充。
我首先设置了一个枚举类,将这些查询条件列出来,并在构造方法中,将对应的方法以反射的方式取到。
-
public
enum QueryConditionEnum {
-
-
EQ(
"eq"),
-
NE(
"ne"),
-
GT(
"gt"),
-
GE(
"ge"),
-
LT(
"lt"),
-
LE(
"le"),
-
LIKE(
"like"),
-
NOT_LIKE(
"notLike"),
-
LIKE_LEFT(
"likeLeft"),
-
LIKE_RIGHT(
"likeRight");
-
-
private String name;
-
-
private Method method;
-
-
-
QueryConditionEnum (String name) {
-
this.name = name;
-
try {
-
Method method = AbstractWrapper.
class.getDeclaredMethod(name,
boolean.
class, Object.
class, Object.
class);
-
this.method = method;
-
}
catch (NoSuchMethodException e) {
-
}
-
}
-
-
}
再者,我想通过注解的方式来规定需要以什么方法填充,默认为EQ,对此写了一个QueryCondition注解。
-
@Retention(RetentionPolicy.RUNTIME)
-
@Target({ElementType.FIELD})
-
public
@interface QueryCondition {
-
-
/**
-
* 默认查询方式
-
*
-
* @return
-
*/
-
QueryConditionEnum
value()
default
QueryConditionEnum
.EQ;
-
-
/**
-
* 是否填充默认查询条件
-
*
-
* @return
-
*/
-
boolean
isCondition()
default
true;
-
-
}
然后就可以这样构造UserForm
-
public
class UserForm {
-
private String name;
-
-
@QueryCondition(QueryConditionEnum.LIKE)
-
private String mobile;
-
}
我们需要一个工具类填充查询条件,这里我们新增了一个参数 mo对象,这是因为我们的主查询对象是Mo对象,Mo对象存储了相关表格名称、表格字段名信息。
-
@TableName("user")
-
public
class UserMo {
-
@TableField("name")
-
private String name;
-
-
@TableField("mobile")
-
private String mobile;
-
}
-
public
class QueryTool {
-
-
/**
-
* 填充默认查询
-
* @param baseClazz mo对象class
-
* @param queryWrapper 查询条件
-
* @param form 请求对象
-
*/
-
public
static
void paddingDefaultConditionQuery(
Class baseClazz, QueryWrapper queryWrapper, Object form) {
-
try {
-
for (Field declaredField : form.getClass().getDeclaredFields()) {
-
declaredField.setAccessible(
true);
-
Object fieldValue = declaredField.get(form);
-
QueryCondition queryCondition = declaredField.getAnnotation(QueryCondition.
class);
-
if (fieldValue ==
null) {
-
continue;
-
}
-
if (queryCondition ==
null) {
-
queryWrapper.eq(StringTool.isNotEmpty(fieldValue.toString()),
-
QueryTool.getTableName(baseClazz) +
"." + QueryTool.getTableFieldName(baseClazz, declaredField),
-
fieldValue.toString());
-
continue;
-
}
-
if (queryCondition.isCondition() ==
false) {
-
continue;
-
}
-
Method method = queryCondition.value().getMethod();
-
method.invoke(queryWrapper, StringTool.isNotEmpty(fieldValue.toString()),
-
QueryTool.getTableName(baseClazz) +
"." + QueryTool.getTableFieldName(baseClazz, declaredField),
-
fieldValue.toString());
-
}
-
}
catch (
Exception e) {
-
throw
new
RuntimeException(
"填充默认的SQL条件出错", e);
-
}
-
}
-
-
/**
-
* 填充默认排序
-
*
-
* @param queryWrapper
-
* @param pageForm
-
*/
-
public
static
void paddingDefaultOrderQuery(QueryWrapper queryWrapper, PageForm pageForm) {
-
queryWrapper.orderBy(pageForm !=
null && StringTool.isNotEmpty(pageForm.getColumnName()),
-
pageForm.getIsAsc() ==
null ?
false : pageForm.getIsAsc(), pageForm.getColumnName());
-
}
-
-
/**
-
* 获取表名称
-
*
-
* @return
-
*/
-
public
static
String getTableName(
Class baseClazz) {
-
TableName tableName = (TableName) baseClazz.getDeclaredAnnotation(TableName.
class);
-
if (tableName !=
null && StringTool.isNotEmpty(tableName.value())) {
-
return tableName.value();
-
}
-
return StringTool.toUnderline(baseClazz.getClass().getName());
-
}
-
-
/**
-
* 获取字段名
-
*
-
* @param field
-
* @
return
-
*/
-
public
static
String getTableFieldName(
Class baseClazz, Field field) {
-
Field baseField =
null;
-
try {
-
baseField = baseClazz.getDeclaredField(field.getName());
-
}
catch (NoSuchFieldException e) {
-
e.printStackTrace();
-
}
-
if (baseField ==
null) {
-
baseField = field;
-
}
-
TableId tableId = baseField.getAnnotation(TableId.
class);
-
if (tableId !=
null && StringTool.isNotEmpty(tableId.value())) {
-
return tableId.value();
-
}
-
TableField tableField = baseField.getAnnotation(TableField.
class);
-
if (tableField !=
null && StringTool.isNotEmpty(tableField.value())) {
-
return tableField.value();
-
}
-
return StringTool.toUnderline(baseField.getName());
-
}
-
-
}
最后我们就可以使用工具类来填充了 。
-
public
List<UserMo>
list (UserForm userForm) {
-
QueryWrapper<UserMo> queryWrapper =
new QueryWrapper<>();
-
QueryTool.paddingDefaultConditionQuery(UserMo.
class, queryWrapper, userForm);
-
return userMapper.selectList(queryWrapper);
-
}
可以看到这样大大减少了需要填充的字段。如果有特殊字段,也能通过注解方式,跳过特殊字段,再自行填充就好。
作者:李涛
转载:https://blog.csdn.net/m0_46573967/article/details/112857333