项目背景
MybatisPlus 使得查询数据库变的简单,那么能否页面查询接口也变得这么简单?当然可以
目的
代码生成,就满足页面查询所有表字段的基本查询
实现
为了侵入小,使用工具类方式实现
1.基础功能
1.1主要代码在buildFieldWrapper (组装字段条件)
实现思路: 遍历实体,将字段对应值非空,加入eq(等于条件)
/**
*组装字段条件
*/
private static <T> void buildFieldWrapper(T t, QueryWrapper<T> queryWrapper, Field[] declaredFields, TableAlias tableAlias) {
for (Field field : declaredFields) {
field.setAccessible(true);
String fieldName = ReflectUtil.getFieldName(field);
if("serialVersionUID".equals(fieldName)){
//序列化id忽略
continue;
}
QueryConditions queryConditions = field.getAnnotation(QueryConditions.class);
//条件值
Object fieldValue = ReflectUtil.getFieldValue(t, field);
if(null == fieldValue || StrUtil.isBlank(fieldValue.toString())){
continue;
}
//条件名称
String dbFiledName = getDbFieldName(tableAlias,field,queryConditions);
if (queryConditions != null) {
if (ConditionsType.EQ.equals(queryConditions.type())) {
queryWrapper.eq(dbFiledName, fieldValue);
}
if (ConditionsType.LIKE.equals(queryConditions.type())) {
queryWrapper.like(dbFiledName, fieldValue);
}
}else {
//默认都是等于条件
queryWrapper.eq(dbFiledName, fieldValue);
}
}
}
1.2 使用
将参数类,传入工具方法
public IPage<JobPageResVo> queryPage(JobPageQueryVo pageQueryVo, PageVo page) {
Page convert = Convert.convert(Page.class, page);
return this.baseMapper.queryPage(convert, QueryWrapperUtils.toQueryWrapper(pageQueryVo));
}
2.扩展功能
2.1扩展其他条件
注解
只是等于满足不了需求,使用注释方式实现
package com.g_link.phm.common.annocation.QueryHandle;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 查询条件
*/
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface QueryConditions {
/**
* 条件
*/
ConditionsType type() default ConditionsType.EQ;
/**
*自定义查询字段,
* 如多表关联需要配置【表名.字段名】(b.name)
*/
String queryFiled() default "";
}
枚举类,举出需要的条件
package com.g_link.phm.common.annocation.QueryHandle;
public enum ConditionsType {
/**
* 等于
*/
EQ,
/**
* 模糊查询
*/
LIKE
}
使用范例
@QueryConditions(type = ConditionsType.LIKE)
public class BookEntity implements Serializable {
private static final long serialVersionUID=1L;
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
/**
* 作业名称
*/
@QueryConditions(type = ConditionsType.LIKE)
private String name;
}
2.2 快展排序
注解
package com.g_link.phm.common.annocation.QueryHandle;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface OrderBy {
String desc() default "create_at";
String asc() default "";
}
使用范例
@OrderBy(desc = "b.create_at")
@GroupBy("b.id")
@Data
public class BookPageQueryVo {
2.3 扩展分组group by
注解
package com.g_link.phm.common.annocation.QueryHandle;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface GroupBy {
String value();
}
使用范例
@OrderBy(desc = "j.create_at")
@GroupBy("j.id")
@Data
public class JobPageQueryVo {
2.4 扩展表别名
如果使用了关联查询,表一搬会起别名
注解
/**
* 表,别名,
* 用于关联查询起了别名查询条件使用
* 如:别名 t
* select t.* from table t
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TableAlias {
String value();
}
使用范例
@TableAlias("b")
public class BookEntity implements Serializable {
3.完整工具类代码
package com.g_link.phm.common.util;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.g_link.phm.common.annocation.QueryHandle.*;
import java.lang.reflect.Field;
/**
* 根据【实体注解】,组装查询条件
*/
public class QueryWrapperUtils {
public static <T> QueryWrapper toQueryWrapper(T t) {
QueryWrapper<T> queryWrapper = new QueryWrapper<>();
//组装排序
buildOrderBy(t, queryWrapper);
//组装分组
buildGroupBy(t, queryWrapper);
//组装查询条件
buildQueryWrapper(t, queryWrapper);
return queryWrapper;
}
/**
* 组装查询条件
* @param t 实体
* @param queryWrapper 返回查询条件对象
*/
private static <T> void buildQueryWrapper(T t, QueryWrapper<T> queryWrapper) {
TableAlias tableAlias = t.getClass().getAnnotation(TableAlias.class);
//组装字段条件
buildFieldWrapper(t, queryWrapper, t.getClass().getDeclaredFields(), tableAlias);
//应付扩展查询vo,查询实体中字段情况
Class<?> superclass = t.getClass().getSuperclass();
tableAlias = superclass.getAnnotation(TableAlias.class);
if(tableAlias != null) {
//组装字段条件
buildFieldWrapper(t, queryWrapper, superclass.getDeclaredFields(), tableAlias);
}
}
/**
*组装字段条件
*/
private static <T> void buildFieldWrapper(T t, QueryWrapper<T> queryWrapper, Field[] declaredFields, TableAlias tableAlias) {
for (Field field : declaredFields) {
field.setAccessible(true);
String fieldName = ReflectUtil.getFieldName(field);
if("serialVersionUID".equals(fieldName)){
//序列化id忽略
continue;
}
QueryConditions queryConditions = field.getAnnotation(QueryConditions.class);
//条件值
Object fieldValue = ReflectUtil.getFieldValue(t, field);
if(null == fieldValue || StrUtil.isBlank(fieldValue.toString())){
continue;
}
//条件名称
String dbFiledName = getDbFieldName(tableAlias,field,queryConditions);
if (queryConditions != null) {
if (ConditionsType.EQ.equals(queryConditions.type())) {
queryWrapper.eq(dbFiledName, fieldValue);
}
if (ConditionsType.LIKE.equals(queryConditions.type())) {
queryWrapper.like(dbFiledName, fieldValue);
}
}else {
//默认都是等于条件
queryWrapper.eq(dbFiledName, fieldValue);
}
}
}
/**
* 组装分组
* @param t 实体
* @param queryWrapper 返回查询条件对象
*/
private static <T> void buildGroupBy(T t, QueryWrapper<T> queryWrapper) {
GroupBy groupBy = t.getClass().getAnnotation(GroupBy.class);
if(groupBy != null && StrUtil.isNotBlank(groupBy.value())){
queryWrapper.groupBy(groupBy.value());
}
}
/**
* 组装排序
* @param t 实体
* @param queryWrapper 返回查询条件对象
*/
private static <T> void buildOrderBy(T t, QueryWrapper<T> queryWrapper) {
OrderBy order = t.getClass().getAnnotation(OrderBy.class);
if(order != null) {
if(StrUtil.isNotBlank(order.desc())){
queryWrapper.orderByDesc(order.desc());
}
if(StrUtil.isNotBlank(order.asc())){
queryWrapper.orderByAsc(order.asc());
}
}
}
/**
* 获取数据库字段名称
* 1.是否有自定义【数据库字段名】,有则直接使用
* 2.没有则,将实体字段转换为【数据库字段】
* 2.1如果有表明,则加表明前缀,组装为tableAlias.filed;应对多变关联查询
* @param tableAlias 关联查询起得表别名
* @param field 实体字段名称
* @param queryConditions 查询条件,包含
*/
private static String getDbFieldName(TableAlias tableAlias,Field field,QueryConditions queryConditions) {
String dbFiledName = "";
if(queryConditions != null && StrUtil.isNotBlank(queryConditions.queryFiled())){
dbFiledName = queryConditions.queryFiled();
}else {
String fieldName = ReflectUtil.getFieldName(field);
StringBuilder dbFiledNameBuilder = new StringBuilder(fieldName.charAt(0) + "");
for (int i = 1; i < fieldName.length(); i++) {
char c = fieldName.charAt(i);
if(Character.isUpperCase(c)){
dbFiledNameBuilder.append("_").append(Character.toLowerCase(c));
}else {
dbFiledNameBuilder.append(c);
}
}
dbFiledName = dbFiledNameBuilder.toString();
if(tableAlias != null && StrUtil.isNotBlank(tableAlias.value())){
dbFiledName = tableAlias.value()+"."+ dbFiledNameBuilder;
}
}
return dbFiledName;
}
}