Mybatis-plus 实体类自定义查询注解
自定义查询注解是为实体类中某些实体属性作为查询条件定义的,在实体属性上引入注解可以实现自动生成查询条件QueryWrapper的功能。
·
文章目录
前言
自定义查询注解是为实体类中某些实体属性作为查询条件定义的,在实体属性上引入注解可以实现自动生成查询条件QueryWrapper的功能。
一、为什么引入自定义查询注解
一个实体作为查询条件,但实体里面的属性很多,如果写在mapper.xml里面要写很多的判断,如果用mybatis-plus 的LambdaQueryWrapper会显得很臃肿如下:
/**
* 公共查询条件
* @param bean
* @return
*/
private LambdaQueryWrapper<Bean> getCommonCondition(Bean bean) {
LambdaQueryWrapper<Bean> lqw = new LambdaQueryWrapper<Bean>()
.like(StringUtils.isNotNull(bean.getLName()), Bean::getLeadName, bean.getSName())
.like(StringUtils.isNotNull(bean.getTName()), Bean::getTeamName, bean.getTName())
.eq(StringUtils.isNotNull(bean.getActId()), Bean::getActId, bean.getActId())
.eq(StringUtils.isNotNull(bean.getIdCard()), Bean::getLeadIdCard, bean.getIdCard())
.like(StringUtils.isNotNull(bean.getPhone()), Bean::getLeadPhone, bean.getPhone())
.gt(StringUtils.isNotNull(bean.getStartTime()), Bean::getCreateTime, bean.getStartTime())
.lt(StringUtils.isNotNull(bean.getEndTime()), Bean::getCreateTime, bean.getEndTime())
.eq(StringUtils.isNotNull(bean.getStatus()), Bean::getCheckStatus, bean.getStatus());
return lqw;
}
二、自定义查询注解定义
1.Query 注解
代码如下:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 自定义导出Excel数据注解
*
* @author lys
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Query {
/**
* 对应数据库字段,为空取实体属性名 驼峰转下划线
*/
public String filedColumn() default "";
/**
* 分隔符,读取字符串组内容
*/
public String separator() default ",";
/**
* 另一个类中的属性名称,支持多级获取,以小数点隔开
*/
public String targetAttr() default "";
/**
* 字段类型
*/
Type type() default Type.EQUAL;
enum Type {
EQUAL //相等
, GREATER_THAN// 大于等于
, GREATER_THAN_NQ //大于
, LESS_THAN //小于等于
, LESS_THAN_NQ //小于
, NOT_EQUAL //不等于
, NOT_NULL //不为空
, INNER_LIKE //中模糊查询
, LEFT_LIKE // 左模糊查询
, RIGHT_LIKE //右模糊查询
, IN //包含
, BETWEEN //between
, UNIX_TIMESTAMP //查询时间
}
}
2.Querys 注解(用于属性多个条件情况)
代码如下:
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Excel注解集
* @author lys
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Querys {
Query[] value();
}
3.Query注解处理工具类
代码如下:
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.core.annotation.Query;
import com.core.annotation.Querys;
import com.core.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* Query相关处理
* @author lys
*/
public class QueryUtil {
private static final Logger log = LoggerFactory.getLogger(QueryUtil.class);
public static <T> QueryWrapper setQueryWrapper(T bean){
QueryWrapper<T> queryWrapper = new QueryWrapper<>();
if (bean == null) {
return queryWrapper;
}
try {
List<Object[]> fields = getFields(bean.getClass());
for (Object[] os : fields){
Field field = (Field) os[0];
Query q = (Query) os[1];
Object val = getTargetValue(bean, field, q);
if(val == null) {continue;}
String filedColumn = StringUtils.isBlank(q.filedColumn()) ? StrUtil.toUnderlineCase(field.getName()) :q.filedColumn();
switch (q.type()) {
// case EQUAL:
// queryWrapper.eq(ReflectUtil.getFieldName(field),val);
// break;
case GREATER_THAN: // 大于等于
queryWrapper.ge(filedColumn, val);
break;
case GREATER_THAN_NQ: //大于
queryWrapper.gt(filedColumn, val);
break;
case LESS_THAN: //小于等于
queryWrapper.le(filedColumn, val);
break;
case LESS_THAN_NQ: //小于
queryWrapper.lt(filedColumn, val);
break;
case INNER_LIKE: //中模糊查询
queryWrapper.like(filedColumn, val);
break;
case LEFT_LIKE: //左模糊查询
queryWrapper.likeLeft(filedColumn, val);
break;
case RIGHT_LIKE: //右模糊查询
queryWrapper.likeRight(filedColumn, val);
break;
case IN: //包含
if (field.getGenericType().toString().equals("class java.lang.String")) {
queryWrapper.in(filedColumn, ((String)val).split(q.separator()));
} else if (CollUtil.isNotEmpty((Collection) val)) {
queryWrapper.in(filedColumn, (Collection) val);
}
break; //不等于
case NOT_EQUAL:
queryWrapper.ne(filedColumn, val);
break;
case NOT_NULL: //不为空
queryWrapper.isNotNull(filedColumn);
break;
case BETWEEN: //between
List between = new ArrayList<>((List) val);
queryWrapper.between(filedColumn, between.get(0), between.get(1));
break;
case UNIX_TIMESTAMP: //查询时间
List UNIX_TIMESTAMP = new ArrayList<>((List) val);
if (!UNIX_TIMESTAMP.isEmpty()) {
SimpleDateFormat fm = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date time1 = fm.parse(UNIX_TIMESTAMP.get(0).toString());
Date time2 = fm.parse(UNIX_TIMESTAMP.get(1).toString());
queryWrapper.between(filedColumn, time1, time2);
}
break;
default: //默认等于
queryWrapper.eq(filedColumn,val);
break;
}
}
} catch (Exception e) {
log.error("设置查询条件失败{}", e);
}
return queryWrapper;
}
/**
* 获取bean值
* @param vo
* @param field
* @return
* @throws Exception
*/
public static Object getObjectValue(Object vo, Field field) throws Exception {
Object o = field.get(vo);
if(o == null) {return null;}
if (field.getGenericType().toString().equals("class java.lang.String")) {
String val = (String) o;
if (StringUtils.isBlank(val)) {
o = null;
}
} else
// 如果类型是Integer
if (field.getGenericType().toString().equals("class java.lang.int")) {
int val = Integer.parseInt((String) o);
if (val == 0) {
o = null;
}
} else {
// 如果类型是Double
if (field.getGenericType().toString().equals("class java.lang.long")) {
long val = Long.parseLong((String) o);
if (val == 0) {
o = null;
}
}
}
return o;
}
/**
* 获取bean中的属性值
*
* @param vo 实体对象
* @param field 字段
* @param query 注解
* @return 最终的属性值
* @throws Exception
*/
private static Object getTargetValue(Object vo, Field field, Query query) throws Exception {
Object o = getObjectValue(vo, field);
if(o == null) {return o;}
if (StringUtils.isNotEmpty(query.targetAttr())) {
String target = query.targetAttr();
if (target.contains(".")) {
String[] targets = target.split("[.]");
for (String name : targets) {
o = getValue(o, name);
}
} else {
o = getValue(o, target);
}
}
return o;
}
/**
* 以类的属性的get方法方法形式获取值
*
* @param o
* @param name
* @return value
* @throws Exception
*/
private static Object getValue(Object o, String name) throws Exception {
if (StringUtils.isNotNull(o) && StringUtils.isNotEmpty(name)) {
if(o instanceof Map) {
Map<String, Object> objectMap = BeanUtil.beanToMap(o);
if(objectMap.containsKey(name)) {
return objectMap.get(name);
}
return null;
} else {
Class<?> clazz = o.getClass();
Field field = clazz.getDeclaredField(name);
field.setAccessible(true);
o = getObjectValue(o, field);
}
}
return o;
}
/**
* 获取字段注解信息
*/
public static List<Object[]> getFields(Class clazz) {
List<Object[]> fields = new ArrayList<Object[]>();
List<Field> tempFields = new ArrayList<>();
tempFields.addAll(Arrays.asList(clazz.getSuperclass().getDeclaredFields()));
tempFields.addAll(Arrays.asList(clazz.getDeclaredFields()));
for (Field field : tempFields) {
// 单注解
if (field.isAnnotationPresent(Query.class)) {
Query attr = field.getAnnotation(Query.class);
if (attr != null ) {
field.setAccessible(true);
fields.add(new Object[]{field, attr});
}
}
// 多注解
if (field.isAnnotationPresent(Querys.class)) {
Querys attrs = field.getAnnotation(Querys.class);
Query[] querys = attrs.value();
for (Query attr : querys) {
if (attr != null) {
field.setAccessible(true);
fields.add(new Object[]{field, attr});
}
}
}
}
return fields;
}
}
4.示例
1.单注解方式
/**
* 创建者
*/
@ApiModelProperty(value = "创建者")
@TableField(fill = FieldFill.INSERT)
@Query
private String createBy;
2.多注解方式
/**
* 请求参数
*/
@ApiModelProperty(value = "请求参数")
@TableField(exist = false)
@JsonIgnore
@Querys({
@Query(filedColumn = "create_time", targetAttr = "params.beginTime",type = Query.Type.GREATER_THAN),
@Query(filedColumn = "create_time", targetAttr = "params.endTime",type = Query.Type.LESS_THAN)
})
private Map<String, Object> params = new HashMap<>();
3.应用示例
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import com.fasterxml.jackson.annotation.JsonFormat;
import com.common.core.annotation.Query;
import com.common.core.annotation.Querys;
import io.swagger.annotations.ApiModelProperty;
/**
* (Demo)请求实体类
* @author lys
*/
@Data
@EqualsAndHashCode(callSuper = true)
@NoArgsConstructor
public class ReqDemo {
@ApiModelProperty(value = "唯一标识")
@Query
private Long id;
@ApiModelProperty(value = "名称")
@Query(type = Query.Type.INNER_LIKE)
private String name;
@ApiModelProperty(value = "身份证号")
@Query(type = Query.Type.INNER_LIKE)
private String idcard;
@ApiModelProperty(value = "创建者")
@Query
private String createBy;
//多注解方式
@ApiModelProperty(value = "请求参数")
@Querys({
@Query(filedColumn = "create_time", targetAttr = "params.beginTime",type = Query.Type.GREATER_THAN),
@Query(filedColumn = "create_time", targetAttr = "params.endTime",type = Query.Type.LESS_THAN)
})
private Map<String, Object> params = new HashMap<>();
}
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.common.mybatis.core.page.PageQuery;
import com.common.mybatis.core.page.TableDataInfo;
import com.common.mybatis.util.QueryUtil;
import com.demo.domain.Demo;
import com.demo.domain.req.ReqDemo;
import com.demo.mapper.DemoMapper;
import com.demo.service.DemoService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* (Demo)表服务实现类
* @author lys
*/
@RequiredArgsConstructor
@Service
public class DemoServiceImpl extends ServiceImpl<DemoMapper, Demo> implements DemoService {
@Override
public TableDataInfo<Demo> selectPageList(ReqDemo bean, PageQuery pageQuery) {
QueryWrapper<Demo> queryWrapper = QueryUtil.setQueryWrapper(bean);
//xml方式
Page<Demo> page = this.getBaseMapper().selectPageList(pageQuery.build(), queryWrapper);
return TableDataInfo.build(page);
}
@Override
public List<Demo> selectList(ReqDemo bean) {
QueryWrapper<Demo> queryWrapper = QueryUtil.setQueryWrapper(bean);
//直接调用 mybatis-plus baseMapper方式
return this.getBaseMapper().selectList(queryWrapper);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.demo.mapper.DemoMapper">
<resultMap type="com.demo.domain.Demo" id="DemoMap">
<result property="id" column="id" jdbcType="INTEGER"/>
<result property="name" column="name" jdbcType="VARCHAR"/>
<result property="idcard" column="idcard" jdbcType="VARCHAR"/>
<result property="age" column="age" jdbcType="INTEGER"/>
<result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
<result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
<result property="createBy" column="create_by" jdbcType="VARCHAR"/>
<result property="updateBy" column="update_by" jdbcType="VARCHAR"/>
</resultMap>
<select id="selectPageList" resultType="com.demo.domain.Demo">
select id,name,idcard,age,create_time,update_time,create_by,update_by
from demo as q ${ew.customSqlSegment}
</select>
</mapper>
总结
本文仅用于学习记录,如有不合理地方欢迎指出。
参考来源:https://blog.csdn.net/ly1316221439/article/details/123555418
更多推荐
已为社区贡献1条内容
所有评论(0)