# mybatis-plus-wrapper **Repository Path**: wenbo0/mybatis-plus-wrapper ## Basic Information - **Project Name**: mybatis-plus-wrapper - **Description**: 简化QueryWrapper的注解实现 - **Primary Language**: Unknown - **License**: Apache-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 31 - **Forks**: 4 - **Created**: 2022-06-14 - **Last Updated**: 2025-04-22 ## Categories & Tags **Categories**: database-dev **Tags**: mybatis-plus, QueryWrapper ## README ## 简介 mybatis-plus的增强工具包,在用mybatis-plus写查询接口时,经常会写出类似下面的代码 ```java LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery(Student.class) .like(StringUtils.isNotBlank(student.getName()), Student::getName, student.getName()) .eq(student.getSex() != null, Student::getSex, student.getSex()) .ge(student.getAge() != null, Student::getAge, student.getAge()); ``` mp自带的@TableField(condition=SqlCondition.XX)相对比较复杂,常量只支持eq、noteq、like、likeleft和likeright(v3.4.3),其他类型就得在condition直接写条件sql 所以在字段比较多的情况下会很繁琐,这个工具包的目的就是为了解决以上这种情况,简化繁琐的QueryWrapper的条件构建,让多条件查询能更方便 ## 使用说明 ### 快速开始 ```xml com.gitee.wenbo0 mybatis-plus-wrapper 1.0.15 ``` ### 1. QueryWrapper构建工具 #### 1.1 简单条件查询(全部and拼接) **第一步 在实体类或DTO中需要查询的字段上增加注解@Wrapper** ```java @Getter @Setter @Accessors(chain = true) public class Student { private String id; @Wrapper(WrapperType.LIKE) private String name; @Wrapper private Integer sex; @Wrapper(WrapperType.GE) private Integer age; } ``` **第二步 在构建QueryWrapper的时候使用** ```java QueryWrapper queryWrapper = WrapperUtil.buildQueryWrapper(student); ``` 这时WrapperUtil构建的QueryWrapper等价于简介中的代码构建的QueryWrapper。 **@Wrapper注解介绍** 注解有四个属性 分别是 ```java /** * 条件类型 */ WrapperType value() default WrapperType.EQ; /** * 数据库字段名 默认为pojo字段名小驼峰转下划线 */ String columnName() default ""; /** * 是否忽略空白字符串 */ boolean ignoreBlank() default true; /** * 是否忽略null */ boolean ignoreNull() default true; /** * 条件组名称 */ String group() default ""; ``` value可选值为EQ, NE, LIKE, NOT_LIKE, LIKE_LEFT, LIKE_RIGHT, LT, GT, LE, GE, IN, NOT_IN,分别调用mybatis-plus中的同名方法,默认值为EQ 注意:**目前IN和NOT_IN只支持数组和字符串类型, 字符串类型目前只支持逗号分割字符串** **ignoreNull设置为false时,将会把null作为条件查询** **ignoreBlank设置为false时,并且字段为String类型,将会把空字符串作为条件查询** #### 1.2 复杂条件查询 **第一步 在实体类或DTO类上增加注解@WrapperGroups配置条件组** @Group的group属性为条件组名称,conditionType为条件组内条件拼接类型,splicingType为条件组外条件拼接类型,简单来说,同一条件组的条件会用()括起来,conditionType就是(a=1 **and** b=2)中的and,splicingType就是(a=1 and b=2) **or** (c=1 and d=2)中的or。 **第二步 在需要查询的字段上增加注解@Wrapper** 配置@Wrapper的group属性,相同group则为同一条件组,条件组的配置在第一步 ```java @Getter @Setter @Accessors(chain = true) @WrapperGroups(groups = { @Group(group = "group1", conditionType = ConditionType.OR, splicingType = ConditionType.AND), @Group(group = "group2", conditionType = ConditionType.AND, splicingType = ConditionType.AND) }) public class Student { private String id; @Wrapper(value = WrapperType.LIKE, group="group1") private String name; @Wrapper(group="group1") private Integer sex; @Wrapper(WrapperType.GE, group="group2") private Integer age; } ``` **第三步 在构建QueryWrapper的时候使用** ```java QueryWrapper queryWrapper = WrapperUtil.buildQueryWrapper(student); ``` 第二步的配置相当于 ```java queryWrapper.and(i -> i.like("name","xxx").or().eq("sex","xxx")).and(i -> i.ge("age","xxx")); ``` 生成sql相当于 ```sql select xx from xx where (name like '%xxx%' or sex = 'xxx') and (age >= 'xxx') ``` ### 2. 字典回写 **第一步 处理插件配置** ```java @Bean public DictTextResultSetHandlerPlugin dictTextResultSetHandlerPlugin(){ return new DictTextResultSetHandlerPlugin(); } //如果需要缓存表,通过以下构造方法 默认缓存时间5分钟 @Bean public DictTextResultSetHandlerPlugin dictTextResultSetHandlerPlugin(){ return new DictTextResultSetHandlerPlugin("sys_dict", "sys_user"); } //或 第一个参数为缓存时间(ms),第二个是缓存的表名 @Bean public DictTextResultSetHandlerPlugin dictTextResultSetHandlerPlugin(){ return new DictTextResultSetHandlerPlugin(1000 * 60, "sys_dict", "sys_user"); } ``` **第二步 在实体类或VO中需要回写的字段上增加注解** ```java @Getter @Setter @Accessors(chain = true) public class Student { private String id; private String name; @DictText(keyColumn = "id", textColumn = "dict_text", tableName = "sys_dict", target = "sexName") private Integer sex; @TableField(exist = false) private String sexName; } ``` 通过@DictText注解绑定需要回写的表和字段等属性,在数据查询完成后二次查询将显示值填充到对应字段中,避免频繁的连表查询 需要注意的是字典回写最好在分页接口或数据较少的接口中使用,字典表一定要加索引,否则性能影响较大 缓存的表不宜太多,数据量特别大的表也不适合缓存,除非你内存特别大✌️ textColumn和target支持逗号分割回写多个字段 比如 ``` @DictText(keyColumn = "id", textColumn = "dict_text,dict_type", tableName = "sys_dict", target = "sexName,sexType") ``` **@DictText注解介绍** ```java /** * 要查询的关联表的条件字段名 */ String keyColumn() default "id"; /** * 要查询的关联表的回显字段名 */ String textColumn() default "name"; /** * 实体类中要回写的字段名 */ String target() default ""; /** * 要查询的关联表名称 */ String tableName() default ""; /** * 关联表其他需要的条件字段名 */ String otherColumn() default "dict_id"; /** * 关联表其他需要的条件字段值 */ String otherValue() default ""; /** * 是否为逗号分割 如果设置为true 回写的字典名称同样为逗号分割 */ boolean commaSeparate() default false; ``` otherValue支持使用${}来获取当前对象的字段值 这些属性主要是用来拼接sql,用sql来说明这些字段的意思应该更清楚 ```sql select ${textColumn} from ${tableName} where ${keyColumn} = ${注解的字段的值} ``` 如果有些字典表有dict_id或group_id的字典分组字段,可以用otherColumn和otherValue来查询 ```sql select ${textColumn} from ${tableName} where ${keyColumn} = ${注解的字段的值} and ${otherColumn} = ${otherValue} ``` 如果commaSeparate为true时,代表注解的值为逗号分割字符串,例如1,2,那么回写的结果同样为逗号分割字符串,比如男,女 ```sql select group_concat(${textColumn}) from ${tableName} where ${keyColumn} in (${注解的字段的值}) ``` 这种方式同样可以拼接otherColumn = otherValue 当然,目前这种方式可能会导致1,1只返回男,不过感觉应该够用了,先这样吧