通过注解和反射将实体类快速转为为Wrapper对象
添加Student的配置文件 StudentMapper.xmldao层接口的StudentMapper.java,service的接口和实现类可以暂时不创建。pom.xml中添加hutool依赖,hutool包里包装了通过反射获取类中的字段,获取字段中的值的方法。将age字段改为age1,自定义column()的值,设置字段对应相应的列名为column()的值。将name字段添加@Wrapper
·
通过注解和反射将实体类快速转为为Wrapper对象
通过注解和反射将实体类快速转为为Wrapper对象
一、思路
- 在实体类中需要参与判断的字段上添加注解@Wrapper,
- value()对应wrapper上的对应操作(eq,lt,gt等),
- column()的值为该字段对应数据库中的列名,默认是字段名。
- 通过反射获取实体类上的字段集合fields,
- 遍历fields,获取每个field的值和注解,
- 解析注解上的value()和column(),根据这两个值增加该字段对应的wrapper操作。
二、实现
-
构建一个基于 SpringBoot+MyBatis-Plus 的项目。
-
创建数据表student并填充测试数据
-
创建实体类Student,
将name字段添加@Wrapper,不另外设置值,
value()将默认为Comparison.EQ,
column()为空,将使用字段名作为列名
将age字段改为age1,自定义column()的值,设置字段对应相应的列名为column()的值
package com.hsh.MySQLUtil.model;
import com.baomidou.mybatisplus.annotation.TableField;
import com.hsh.MySQLUtil.annotation.Wrapper;
import com.hsh.MySQLUtil.enmu.Comparison;
import lombok.Data;
/**
* @author hsh
* @date 2023/7/26 22:07
*/
// 可以使用lombok的@Data注解自动生成其set/get方法
@Data
public class Student {
private Integer id;
@Wrapper
private String name;
@Wrapper(value = Comparison.LT, column = "age")
private Integer age1;
}
-
添加Student的配置文件 StudentMapper.xml dao层接口的StudentMapper.java,service的接口和实现类可以暂时不创建。可以通过MyBatisX插件批量生成这些文件
链接: https://blog.csdn.net/SUMMERENT/article/details/129587241 -
pom.xml中添加hutool依赖,hutool包里包装了通过反射获取类中的字段,获取字段中的值的方法。
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>4.1.0</version>
</dependency>
- 新建比较类型的枚举类Comparison
package com.hsh.MySQLUtil.enmu;
/**
* @author hsh
* @date 2023/7/26 22:37
*/
public enum Comparison {
EQ,
LT,
GT
}
- 新建注解@Wrapper
package com.hsh.MySQLUtil.annotation;
import com.hsh.MySQLUtil.enmu.Comparison;
import java.lang.annotation.*;
/**
* @author hsh
* @date 2023/7/26 22:38
*/
@Target(ElementType.FIELD)
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface Wrapper {
//默认使用eq,一个字段上只能使用一个Wrapper注解
Comparison value() default Comparison.EQ;
//设置该字段对应的列名
String column() default "";
}
- 新建构建Wrapper的工具类QueryWrapperBuilder
package com.hsh.MySQLUtil.util;
import cn.hutool.core.util.ReflectUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hsh.MySQLUtil.annotation.Wrapper;
import com.hsh.MySQLUtil.enmu.Comparison;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.List;
/**
* @author hsh
* @date 2023/7/27 19:58
*/
public class QueryWrapperBuilder {
public static <T> QueryWrapper<T> buildQueryWrapper(T t) {
QueryWrapper<T> wrapper = new QueryWrapper<T>();
if (t == null) {
return wrapper;
}
//hutool包装的方法,获得一个类中所有字段列表,包括其父类中的字段和私有字段
//相当于getDeclaredFields()和getFields()的结合体
Field[] fields = ReflectUtil.getFields(t.getClass());
List<Field> list = Arrays.asList(fields);
if (list.isEmpty()) {
return wrapper;
}
for (Field field : list) {
//hutool包装的方法,与field.get(t)类似,但不需要try/catch
Object value = ReflectUtil.getFieldValue(t, field.getName());
//字段值为空时不参与条件查询
if (value == null || "".equals(value)) {
continue;
}
//允许访问私有字段
field.setAccessible(true);
//获取Wrapper注解
Wrapper wrapperAnno = field.getAnnotation(Wrapper.class);
if (wrapperAnno == null) {
continue;
}
//设置该字段对应数据库的列名,默认字段名=列名
String name = wrapperAnno.column().isEmpty()
? field.getName()
: wrapperAnno.column();
//根据注解的值添加对应的wrapper操作
switch (wrapperAnno.value()) {
case EQ:
wrapper.eq(name, value);
break;
case LT:
wrapper.lt(name, value);
break;
case GT:
wrapper.gt(name, value);
break;
}
}
return wrapper;
}
}
- 为了测试步骤简洁,直接在Controller生成Wrapper对象并调用
package com.hsh.MySQLUtil.controller;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.hsh.MySQLUtil.mapper.StudentMapper;
import com.hsh.MySQLUtil.model.Student;
import com.hsh.MySQLUtil.util.QueryWrapperBuilder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
/**
* @author hsh
* @date 2023/7/24 4:01
*/
@RestController
public class StudentController {
@Resource
private StudentMapper studentMapper;
@GetMapping("/find")
public List find() {
// QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
// queryWrapper.eq("age",18);
Student student = new Student();
student.setAge1(19);
student.setName("张三");
QueryWrapper<Student> queryWrapper = QueryWrapperBuilder.buildQueryWrapper(student);
List<Student> students = studentMapper.selectList(queryWrapper);
System.out.println(students);
return students;
}
}
- 可以看到已经可以通过student对象生成对应的wrapper对象,并生成对应的sql语句。
更多推荐
已为社区贡献1条内容
所有评论(0)