/**
* 字段注解
*/
public @interface BuilderField {
/**
* 对应的数据库字段名称
* @return
*/
String name();
}
import lombok.SneakyThrows;
import java.io.Serializable;
import java.lang.invoke.SerializedLambda;
import java.lang.reflect.Method;
import java.util.function.Function;
@FunctionalInterface
public interface BuilderFunction<T, R> extends Function<T, R>, Serializable {
@SneakyThrows
default String getFieldName() {
String methodName = getMethodName();
if (methodName.startsWith("get")) {
methodName = methodName.substring(3);
}
return methodName;
}
@SneakyThrows
default String getMethodName() {
return getSerializedLambda().getImplMethodName();
}
@SneakyThrows
default Class<?> getFieldClass() {
return getReturnType();
}
@SneakyThrows
default SerializedLambda getSerializedLambda() {
Method method = getClass().getDeclaredMethod("writeReplace");
method.setAccessible(true);
return (SerializedLambda) method.invoke(this);
}
@SneakyThrows
default Class<?> getReturnType() {
SerializedLambda lambda = getSerializedLambda();
Class<?> className = Class.forName(lambda.getImplClass().replace("/", "."));
Method method = className.getMethod(getMethodName());
return method.getReturnType();
}
}
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import java.beans.Introspector;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @Description : 查询封装
* @Author : cxw
* @Date : 2023/8/7 13:13
* @Version : 1.0
**/
public class BuilderQuery<T> {
private static Pattern humpPattern = Pattern.compile("[A-Z]");
private static final Pattern GET_PATTERN = Pattern.compile("^get[A-Z].*");
private static final Pattern IS_PATTERN = Pattern.compile("^is[A-Z].*");
private static Logger logger = LoggerFactory.getLogger(BuilderQuery.class);
private Field[] fields;
private String className;
private Class _clazz;
Criteria criteria =null;
public BuilderQuery(Class<?> clazz) {
fields = clazz.getDeclaredFields();
className=clazz.getName();
_clazz=clazz;
}
/**
* 精准匹配 field=val 的sql
* @param func 类的字段名get方法
* @param val 类对应的字段值
* @return
*/
public BuilderQuery eq(BuilderFunction<T, Object> func,Object val) throws Exception {
String field = getFieldName(func.getMethodName());
String _field = getSQLField(field);
if(criteria==null){
criteria=Criteria.where(_field).is(val);
}else {
criteria.and(_field).is(val);
}
return this;
}
/**
* in 查询
* @param func 类的字段名get方法
* @param val 类对应的字段值
* @return
*/
public BuilderQuery in(BuilderFunction<T, Object> func, List<Object> val) throws Exception {
String field = getFieldName(func.getMethodName());
String _field = getSQLField(field);
if(criteria==null){
criteria=Criteria.where(_field).in(val);
}else {
criteria.and(_field).in(val);
}
return this;
}
/**
* like模糊 查询
* @param func 类的字段名get方法
* @param val 类对应的字段值
* @return
*/
public BuilderQuery like(BuilderFunction<T, Object> func, String val,Boolean allLike) throws Exception {
String field = getFieldName(func.getMethodName());
String _field = getSQLField(field);
if(criteria==null){
criteria=Criteria.where(_field).regex(val);
}else {
criteria.and(_field).regex(val);
}
return this;
}
/**
* 大于查询
* @param func 类的字段名get方法
* @param val 类对应的字段值
* @return
*/
public BuilderQuery gt(BuilderFunction<T, Object> func, String val) throws Exception {
String field = getFieldName(func.getMethodName());
String _field = getSQLField(field);
if(criteria==null){
criteria=Criteria.where(_field).gt(val);
}else {
criteria.and(_field).gt(val);
}
return this;
}
/**
* 小于查询
* @param func 类的字段名get方法
* @param val 类对应的字段值
* @return
*/
public BuilderQuery lt(BuilderFunction<T, Object> func, String val) throws Exception {
String field = getFieldName(func.getMethodName());
String _field = getSQLField(field);
if(criteria==null){
criteria=Criteria.where(_field).lt(val);
}else {
criteria.and(_field).lt(val);
}
return this;
}
/**
* 生成字段
* @param field
* @return
* @throws Exception
*/
private String getSQLField(String field) throws Exception {
for (Field field1 : fields) {
if(field1.getName().equals(field)){
// 获取字段上的注解对象
Annotation[] annotations =field1.getDeclaredAnnotations();
String tableField = hasBuilderField(annotations);
if(tableField==null)tableField=humpToLine(field);
return tableField;
}
}
throw new Exception("当前类:"+className+"不存在字段:"+field+"!");
}
/**
* 判断是否存在BuilderField注解
* @param annotations
* @return
*/
public static String hasBuilderField(Annotation[] annotations) {
if(annotations==null||annotations.length==0)return null;
for (Annotation annotation : annotations) {
if(annotation instanceof BuilderField){
return ((BuilderField) annotation).name();
}
}
return null;
}
/**
* 驼峰转下划线
* @param str
* @return
*/
public static String humpToLine(String str){
Matcher matcher = humpPattern.matcher(str);
StringBuffer sb = new StringBuffer();
while(matcher.find()){
matcher.appendReplacement(sb, "_"+matcher.group(0).toLowerCase());
}
matcher.appendTail(sb);
return sb.toString();
}
/**
* 方法名转字段名
* @param methodName
* @return
*/
private String getFieldName(String methodName){
// 对于非标准变量生成的Get方法这里可以直接抛出异常,或者打印异常日志
if (GET_PATTERN.matcher(methodName).matches()) {
methodName = methodName.substring(3);
} else if (IS_PATTERN.matcher(methodName).matches()) {
methodName = methodName.substring(2);
}
return Introspector.decapitalize(methodName);
}
/**
* 获取query
* @return
*/
public Query getQuery() {
Query query = new Query(criteria);
return query;
}
/***
* 使用案例
*
* BuilderQuery<OrgV2DO> builderQuery=new BuilderQuery(OrgV2DO.class);
* builderQuery.eq(OrgV2DO::getId,"123213");
* builderQuery.eq(OrgV2DO::getLastModifiedBy,"123213");
* String org = builderQuery.getQuery();
* System.out.println(org);
*
* ****/
}