mybatis plus 中的查询优化

传统的mybatis plus 查询写法

对于常规的mybatis单表查询,我们既可以采用LambdaQueryWrapper查询,也可以使用QueryWrapper查询。
LambdaQueryWrapper具有防误写、规范代码等好处,但是缺点是无法在复杂的多表查询中使用。
相比较来说,使用QueryWrapper编写查询更加灵活,可以适应更复杂的查询场景。
我们首先看一个QueryWrapper查询的例子

 
  1. public List<UserMo> list (UserForm userForm) {

  2. QueryWrapper<UserMo> queryWrapper = new QueryWrapper<>();

  3. queryWrapper.like(StringTool.isNotEmpty(userForm.getUserName(), "name", userForm.getUserName());

  4. queryWrapper.eq(StringTool.isNotEmpty(userForm.getMobile(), "mobile", userForm.getMobile());

  5. // 其它的查询条件...

  6. return userMapper.selectList(queryWrapper);

  7. }

对于上面的查询语句来说,可以很好的对前端传值进行处理,当userForm中有前端传值的话,就会往SQL语句中加一条where条件。
但是这样做的话会有一个相对来说比较复杂的点,那就是当UserForm中的字段过于多的时候,我们也许得写十几行的这种重复判断的语句。  

通过自定义注解来解决通用查询条件过多问题

通过观察mybatis plus 对于queryWrapper相关查询方法的列子,我们可以找出一类通用方法

可以看出来这几个方法都是传的同样的三个参数。
我想对于这些简单的通用的查询条件,也许可以有一个通用的方法来填充。
我首先设置了一个枚举类,将这些查询条件列出来,并在构造方法中,将对应的方法以反射的方式取到。 

 

 
  1. public enum QueryConditionEnum {

  2.  
  3. EQ("eq"),

  4. NE("ne"),

  5. GT("gt"),

  6. GE("ge"),

  7. LT("lt"),

  8. LE("le"),

  9. LIKE("like"),

  10. NOT_LIKE("notLike"),

  11. LIKE_LEFT("likeLeft"),

  12. LIKE_RIGHT("likeRight");

  13.  
  14. private String name;

  15.  
  16. private Method method;

  17.  
  18.  
  19. QueryConditionEnum (String name) {

  20. this.name = name;

  21. try {

  22. Method method = AbstractWrapper.class.getDeclaredMethod(name, boolean.class, Object.class, Object.class);

  23. this.method = method;

  24. } catch (NoSuchMethodException e) {

  25. }

  26. }

  27.  
  28. }

再者,我想通过注解的方式来规定需要以什么方法填充,默认为EQ,对此写了一个QueryCondition注解。  

 

 
  1. @Retention(RetentionPolicy.RUNTIME)

  2. @Target({ElementType.FIELD})

  3. public @interface QueryCondition {

  4.  
  5. /**

  6. * 默认查询方式

  7. *

  8. * @return

  9. */

  10. QueryConditionEnum value() default QueryConditionEnum.EQ;

  11.  
  12. /**

  13. * 是否填充默认查询条件

  14. *

  15. * @return

  16. */

  17. boolean isCondition() default true;

  18.  
  19. }

然后就可以这样构造UserForm  

 

 
  1. public class UserForm {

  2. private String name;

  3.  
  4. @QueryCondition(QueryConditionEnum.LIKE)

  5. private String mobile;

  6. }

我们需要一个工具类填充查询条件,这里我们新增了一个参数 mo对象,这是因为我们的主查询对象是Mo对象,Mo对象存储了相关表格名称、表格字段名信息。  

 

 
  1. @TableName("user")

  2. public class UserMo {

  3. @TableField("name")

  4. private String name;

  5.  
  6. @TableField("mobile")

  7. private String mobile;

  8. }

 

 
  1. public class QueryTool {

  2.  
  3. /**

  4. * 填充默认查询

  5. * @param baseClazz mo对象class

  6. * @param queryWrapper 查询条件

  7. * @param form 请求对象

  8. */

  9. public static void paddingDefaultConditionQuery(Class baseClazz, QueryWrapper queryWrapper, Object form) {

  10. try {

  11. for (Field declaredField : form.getClass().getDeclaredFields()) {

  12. declaredField.setAccessible(true);

  13. Object fieldValue = declaredField.get(form);

  14. QueryCondition queryCondition = declaredField.getAnnotation(QueryCondition.class);

  15. if (fieldValue == null) {

  16. continue;

  17. }

  18. if (queryCondition == null) {

  19. queryWrapper.eq(StringTool.isNotEmpty(fieldValue.toString()),

  20. QueryTool.getTableName(baseClazz) + "." + QueryTool.getTableFieldName(baseClazz, declaredField),

  21. fieldValue.toString());

  22. continue;

  23. }

  24. if (queryCondition.isCondition() == false) {

  25. continue;

  26. }

  27. Method method = queryCondition.value().getMethod();

  28. method.invoke(queryWrapper, StringTool.isNotEmpty(fieldValue.toString()),

  29. QueryTool.getTableName(baseClazz) + "." + QueryTool.getTableFieldName(baseClazz, declaredField),

  30. fieldValue.toString());

  31. }

  32. } catch (Exception e) {

  33. throw new RuntimeException("填充默认的SQL条件出错", e);

  34. }

  35. }

  36.  
  37. /**

  38. * 填充默认排序

  39. *

  40. * @param queryWrapper

  41. * @param pageForm

  42. */

  43. public static void paddingDefaultOrderQuery(QueryWrapper queryWrapper, PageForm pageForm) {

  44. queryWrapper.orderBy(pageForm != null && StringTool.isNotEmpty(pageForm.getColumnName()),

  45. pageForm.getIsAsc() == null ? false : pageForm.getIsAsc(), pageForm.getColumnName());

  46. }

  47.  
  48. /**

  49. * 获取表名称

  50. *

  51. * @return

  52. */

  53. public static String getTableName(Class baseClazz) {

  54. TableName tableName = (TableName) baseClazz.getDeclaredAnnotation(TableName.class);

  55. if (tableName != null && StringTool.isNotEmpty(tableName.value())) {

  56. return tableName.value();

  57. }

  58. return StringTool.toUnderline(baseClazz.getClass().getName());

  59. }

  60.  
  61. /**

  62. * 获取字段名

  63. *

  64. * @param field

  65. * @return

  66. */

  67. public static String getTableFieldName(Class baseClazz, Field field) {

  68. Field baseField = null;

  69. try {

  70. baseField = baseClazz.getDeclaredField(field.getName());

  71. } catch (NoSuchFieldException e) {

  72. e.printStackTrace();

  73. }

  74. if (baseField == null) {

  75. baseField = field;

  76. }

  77. TableId tableId = baseField.getAnnotation(TableId.class);

  78. if (tableId != null && StringTool.isNotEmpty(tableId.value())) {

  79. return tableId.value();

  80. }

  81. TableField tableField = baseField.getAnnotation(TableField.class);

  82. if (tableField != null && StringTool.isNotEmpty(tableField.value())) {

  83. return tableField.value();

  84. }

  85. return StringTool.toUnderline(baseField.getName());

  86. }

  87.  
  88. }

最后我们就可以使用工具类来填充了 。

 

 
  1. public List<UserMo> list (UserForm userForm) {

  2. QueryWrapper<UserMo> queryWrapper = new QueryWrapper<>();

  3. QueryTool.paddingDefaultConditionQuery(UserMo.class, queryWrapper, userForm);

  4. return userMapper.selectList(queryWrapper);

  5. }

 

可以看到这样大大减少了需要填充的字段。如果有特殊字段,也能通过注解方式,跳过特殊字段,再自行填充就好。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

weixin_37576193

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值