当前位置: 首页 > news >正文

使用注解封装查询相关的功能

文章目录

  • 一、最终使用方法
  • 二、工具类的封装
    • 1、query查询对象定义
    • 2、TupleUtils工具类
    • 3、LogicalTuple
    • 4、Dialect
    • 5、MySQLDialect
    • 6、ComparisonTuple
    • 7、定义注解
    • 8、定义切面方法监控添加注解的方法
    • 9、OrTuple
    • 10、AndTuple
  • 具体的类
    • 1、WordUtils
    • 2、tuple
    • 3、query
    • 4、LogicalTuple
    • 5、MySQLDialect
    • 6、ComparisonTuple
    • 7、LessThanTuple
    • 8、QueryConverterAspect
    • 9、OrTuple
    • 10、AndTuple

一、最终使用方法

  1. 在controller类上添加@QueryParam(name=“前端传来的key设置”,fields={“表中的字段名(若是在mapper.xml文件中给表设置了别名则需改成别名.字段名)”},operator=“操作符号”)
    在这里插入图片描述
  2. 在mapper.xml文件的SQL语句中使用${@工具类路径@工具类中的方法名(参数)}
    在这里插入图片描述
<select id="findByQuery" parameterType="org.sharpframework.core.common.query.Query" resultMap="wasteRecordResult">select <include refid="wasteRecordColumns"/>, <include refid="solidWasteColumns"/>from rec_waste_record t1left join was_solid_waste t3 on t1.waste_id = t3.id<where><if test="tuple != null and tuple.list != null"><foreach collection="tuple.list" index="index" item="t">${@org.sharpframework.core.common.util.TupleUtils@leftParentheses(t)}<choose><when test="t.type == 'logical'"> ${t.operator} </when><when test="t.type == 'comparison' and t.operator == 'in'">${@org.sharpframework.core.common.util.TupleUtils@convertOperator(t.operator)} #{t.value}</when><when test="t.type == 'comparison' and t.operator == 'inn'">${@org.sharpframework.core.common.util.TupleUtils@convertOperator(t.operator)} #{t.value}</when><when test="t.type == 'comparison' and t.operator == 'bt'">${t.column} ${@org.sharpframework.core.common.util.TupleUtils@convertOperator(t.operator)} #{t.value1} and #{t.value2}</when><when test="t.type == 'comparison' and t.operator == 'lk'">${t.column} like CONCAT('%',#{t.value},'%')</when><when test="t.type == 'comparison'">${t.column} ${@org.sharpframework.core.common.util.TupleUtils@convertOperator(t.operator)} #{t.value}</when></choose>${@org.sharpframework.core.common.util.TupleUtils@rightParentheses(t)}</foreach></if></where><choose><when test="sort != null">order by ${sort}</when><otherwise>order by label desc</otherwise></choose></select>

二、工具类的封装

1、query查询对象定义

  • 在query对象中使用WordUtils工具类——对字符串命名方式做处理,具体代码见下文
  • query对象中定义了一个tuple抽象对象——这个类是

2、TupleUtils工具类

这个类中引用了Tuple,LogicalTuple,Dialect,MySQLDialect

3、LogicalTuple

这个类继承了Tuple,是一个抽象类

4、Dialect

package org.sharpframework.core.common.query.dialect;public interface Dialect {String convert(String tupleOperator);
}

该类是一个接口类,实现类是MySQLDialect

5、MySQLDialect

引用了ComparisonTuple

6、ComparisonTuple

在这里插入图片描述

是一个抽象类,继承了Tuple,引用了WordUtils.toUnderlineName()将驼峰命名改为下划线命名,需要哪种操作直接在这个类的build方法中添加,new的这个类需要继承这个类并且定义一个构造函数 ,一个案例见下文LessThanTuple ,若是需要添加便依照这个类写
在这里插入图片描述

7、定义注解

  1. 创建一个QueryParam注解类
package org.sharpframework.core.common.query.annotation;import java.lang.annotation.*;@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(QueryParams.class)
public @interface QueryParam {String name();String[] fields();String operator() default "=";
}

@Repeatable(QueryParams.class)作用允许在一个方法上同一个注解多次使用

  1. 创建一个QueryParams包装QueryParam
package org.sharpframework.core.common.query.annotation;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface QueryParams {QueryParam[] value();
}

8、定义切面方法监控添加注解的方法

  1. 创建QueryConverterAspect类,添加@Aspect和@Component
  2. 使用aop的@Around(表达式)环绕注解,表达式使用@annotation(params),params指定了注解类型,参数对应的类型便是注解的类型
    在这里插入图片描述
  3. 使用joinPoint获取监控的方法参数——joinPoint.getArgs();
  4. 遍历参数,判断参数中是否存在定义的Query参数——if (Query.class.isInstance(arg)) {
    • 将参数强转为Query类型,定义一个Tuple的list集合
    • 遍历params中的value——QueryParam param: params.value()
    • 根据注解中param参数值作为key从监控方法传来的Query参数中拿到查询条件值——
    • 最后构建Tuple对象

引用了OrTuple,AndTuple

9、OrTuple

继承了LogicalTuple

10、AndTuple

继承了LogicalTuple

具体的类

1、WordUtils

这是一个Java类,名为WordUtils,包含了一些用于处理字符串命名转换的静态方法。主要有三个方法:toUnderlineNametoCamelCasetoCapitalizeCamelCase。以下是对每个方法的解释:

  1. toUnderlineName方法:

    • 输入:一个字符串 s
    • 输出:将输入字符串转换为下划线风格的命名,即将驼峰命名法转换为下划线分隔的命名法。
    • 实现:遍历输入字符串,根据大写字母的位置插入下划线,并将所有字母转换为小写。
  2. toCamelCase方法:

    • 输入:一个字符串 s
    • 输出:将输入字符串转换为驼峰命名法。
    • 实现:将输入字符串中的下划线分隔符去除,并将分隔符后的字母转换为大写。
  3. toCapitalizeCamelCase方法:

    • 输入:一个字符串 s
    • 输出:将输入字符串转换为首字母大写的驼峰命名法。
    • 实现:首先调用toCamelCase方法将字符串转换为驼峰命名法,然后将结果字符串的首字母大写。

这些方法主要用于在不同的命名风格之间进行转换,例如在数据库表字段名和Java实体类属性名之间进行转换,或者在不同编码规范中进行统一。

package org.sharpframework.core.common.util;public class WordUtils {public static String toUnderlineName(String s) {if (s == null) {return null;}StringBuilder sb = new StringBuilder();boolean upperCase = false;for (int i = 0; i < s.length(); i++) {char c = s.charAt(i);boolean nextUpperCase = true;if (i < (s.length() - 1)) {nextUpperCase = Character.isUpperCase(s.charAt(i + 1));}if ((i >= 0) && Character.isUpperCase(c)) {if (!upperCase || !nextUpperCase) {if (i > 0) sb.append(SEPARATOR);}upperCase = true;} else {upperCase = false;}sb.append(Character.toLowerCase(c));}return sb.toString();}public static String toCamelCase(String s) {if (s == null) {return null;}s = s.toLowerCase();StringBuilder sb = new StringBuilder(s.length());boolean upperCase = false;for (int i = 0; i < s.length(); i++) {char c = s.charAt(i);if (c == SEPARATOR) {upperCase = true;} else if (upperCase) {sb.append(Character.toUpperCase(c));upperCase = false;} else {sb.append(c);}}return sb.toString();}public static String toCapitalizeCamelCase(String s) {if (s == null) {return null;}s = toCamelCase(s);return s.substring(0, 1).toUpperCase() + s.substring(1);}private static final char SEPARATOR = '_';
}

2、tuple

package org.sharpframework.core.common.query.tuple;import java.io.Serializable;
import java.util.List;public abstract class Tuple implements Serializable {/*** */private static final long serialVersionUID = 3777119166784500369L;public static final String TUPLE_TYPE_LOGICAL = "logical";public static final String TUPLE_TYPE_COMPARISON = "comparison";public abstract String getType();public abstract List<Tuple> getList();public void setOperator(String operator) {this.operator = operator;}public String getOperator() {return this.operator;}public void setParent(Tuple parent) {this.parent = parent;}public Tuple getParent() {return this.parent;}/*** 是不是左节点(或者是元组的第一元)* @return*/public Boolean isLeft() {return this.left != null ? this.left : false;}public void setLeft(Boolean left) {this.left = left;}/*** 是不是右节点(或者)* @return*/public Boolean isRight() {return this.right != null ? this.right : false;}public void setRight(Boolean right) {this.right = right;}private String operator;private Tuple parent;private Boolean left;private Boolean right;}

3、query

package org.sharpframework.core.common.query;import org.sharpframework.core.common.query.tuple.Tuple;
import org.sharpframework.core.common.util.WordUtils;import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;public class Query implements Serializable {public final static Integer DEFAULT_PAGE_SIZE = 20;public Integer getOffset() {return offset;}public void setOffset(Integer offset) {this.offset = offset;}public Integer getLimit() {return limit;}public void setLimit(Integer limit) {this.limit = limit;}public String getSort() {return sort;}public void setSort(String sort) {if (sort != null && sort.indexOf(".") >= 0) {String[] s = sort.split("\\.");this.sort = WordUtils.toUnderlineName(s[0]) + " " + s[s.length - 1];} else {this.sort = sort + " ASC";}}public Map <String, String> getParams() {return params;}public void setParams(Map <String, String> params) {this.params = params;}public Tuple getTuple() {return tuple;}public void setTuple(Tuple tuple) {this.tuple = tuple;}private Integer offset = 0;private Integer limit = DEFAULT_PAGE_SIZE;private String sort;private Map<String, String> params = new HashMap <>();private Tuple tuple;
}

4、LogicalTuple

package org.sharpframework.core.common.query.tuple;import java.util.ArrayList;
import java.util.List;public abstract class LogicalTuple extends Tuple {private static final long serialVersionUID = 20353989023793529L;public static final String OPERATOR_AND = "and";public static final String OPERATOR_OR = "or";public static final String OPERATOR_NOT = "not";@Overridepublic String getType() {return Tuple.TUPLE_TYPE_LOGICAL;}public List<Tuple> getTuples() {return this.tuples;}protected List<Tuple> tuples = new ArrayList<Tuple>();
}

5、MySQLDialect

package org.sharpframework.core.common.query.dialect;import org.sharpframework.core.common.query.tuple.ComparisonTuple;public class MySQLDialect implements Dialect {@Overridepublic String convert(String tupleOperator) {//between暂时不实现if (tupleOperator.equals(ComparisonTuple.OPERATOR_BETWEEN)) {return "between";} else if (tupleOperator.equals(ComparisonTuple.OPERATOR_EQUAL)) {return "=";} else if (tupleOperator.equals(ComparisonTuple.OPERATOR_GREATTHAN)) {return ">";} else if (tupleOperator.equals(ComparisonTuple.OPERATOR_GREATHAN_EQUAL)) {return ">=";} else if (tupleOperator.equals(ComparisonTuple.OPERATOR_ISNOTNULL)) {return "is not null";} else if (tupleOperator.equals(ComparisonTuple.OPERATOR_ISNULL)) {return "is null";} else if (tupleOperator.equals(ComparisonTuple.OPERATOR_LESSTHAN)) {return "<";} else if (tupleOperator.equals(ComparisonTuple.OPERATOR_LESSTHAN_EQUAL)) {return "<=";} else if (tupleOperator.equals(ComparisonTuple.OPERATOR_LIKE)) {return "like";} else if (tupleOperator.equals(ComparisonTuple.OPERATOR_NOTEQUAL)) {return "!=";}return "";}}

6、ComparisonTuple

package org.sharpframework.core.common.query.tuple;import org.sharpframework.core.common.util.WordUtils;import java.util.ArrayList;
import java.util.List;public abstract class ComparisonTuple extends Tuple {private static final long serialVersionUID = -3500737829270015221L;public static final String OPERATOR_BETWEEN = "bt";public static final String OPERATOR_EQUAL = "eq";public static final String OPERATOR_NOTEQUAL = "neq";public static final String OPERATOR_LESSTHAN = "lt";public static final String OPERATOR_LESSTHAN_EQUAL = "lte";public static final String OPERATOR_GREATTHAN = "gt";public static final String OPERATOR_GREATHAN_EQUAL = "gte";public static final String OPERATOR_LIKE = "lk";public static final String OPERATOR_ISNULL = "in";public static final String OPERATOR_ISNOTNULL = "inn";@Overridepublic String getType() {return TUPLE_TYPE_COMPARISON;}@Overridepublic List<Tuple> getList() {List<Tuple> list = new ArrayList<Tuple>();list.add(this);return list;}public static ComparisonTuple build(String operator, String column, String... values) {if (operator.equals(OPERATOR_EQUAL)) {return new EqualTuple(column, values[0]);} else if (operator.equals(OPERATOR_NOTEQUAL)) {return new NotEqualTuple(column, values[0]);} else if (operator.equals(OPERATOR_LESSTHAN)) {return new LessThanTuple(column, values[0]);} else if (operator.equals(OPERATOR_LESSTHAN_EQUAL)) {return new LessThanEqualTuple(column, values[0]);} else if (operator.equals(OPERATOR_GREATTHAN)) {return new GreatThanTuple(column, values[0]);} else if (operator.equals(OPERATOR_GREATHAN_EQUAL)) {return new GreatThanEqualTuple(column, values[0]);} else if (operator.equals(OPERATOR_LIKE)) {return new LikeTuple(column, values[0]);} else if (operator.equals(OPERATOR_ISNULL)) {return new IsNullTuple(column);} else if (operator.equals(OPERATOR_ISNOTNULL)) {return new IsNotNullTuple(column);} else if (operator.equals(OPERATOR_BETWEEN)) {return new BetweenTuple(column, values[0], values[1]);}return null;}public String getColumn() {return column;}public void setColumn(String column) {this.column = WordUtils.toUnderlineName(column);}private String column;
}

7、LessThanTuple

package org.sharpframework.core.common.query.tuple;public class LessThanTuple extends ComparisonTuple {/*** */private static final long serialVersionUID = -1695595116531166337L;public LessThanTuple(String column, String value) {this.setOperator(ComparisonTuple.OPERATOR_LESSTHAN);this.setColumn(column);this.value = value;}@Overridepublic String toString() {return this.getColumn() + " " + this.getOperator() + " " + this.value;}private String value;
}

8、QueryConverterAspect


import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.sharpframework.core.common.query.Query;
import org.sharpframework.core.common.query.annotation.QueryParam;
import org.sharpframework.core.common.query.annotation.QueryParams;
import org.sharpframework.core.common.query.tuple.AndTuple;
import org.sharpframework.core.common.query.tuple.ComparisonTuple;
import org.sharpframework.core.common.query.tuple.OrTuple;
import org.sharpframework.core.common.query.tuple.Tuple;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;import java.util.ArrayList;
import java.util.List;
@Component
@Aspect
public class QueryConverterAspect {/*** 如果有多个条件* @param joinPoint* @param params* @return* @throws Throwable*/@Around("@annotation(params)")public Object aroundParams(ProceedingJoinPoint joinPoint, QueryParams params) throws Throwable {// 方法中获取参数Object[] args = joinPoint.getArgs();if (args != null) {for (Object arg: args) {// 如果参数中有Query对象if (Query.class.isInstance(arg)) {Query query = (Query) arg;List<Tuple> andList = new ArrayList <>();for (QueryParam param: params.value()) {// 查询条件值String value = query.getParams().get(param.name());if (value != null && !"".equals(value.trim())) {List<Tuple> orList = new ArrayList <>();for (String column: param.fields()) {Tuple tuple = ComparisonTuple.build(param.operator(), column, value);orList.add(tuple);}Tuple tuple = this.buildOrTuple(orList);if (tuple != null) {andList.add(tuple);}}}query.setTuple(this.buildAndTuple(andList));}}}return joinPoint.proceed(args);}/*** 如果只有一个条件* @param joinPoint* @param param* @return* @throws Throwable*/@Around("@annotation(param)")public Object aroundParam(ProceedingJoinPoint joinPoint, QueryParam param) throws Throwable {// 方法中获取参数Object[] args = joinPoint.getArgs();if (args != null) {for (Object arg: args) {// 如果参数中有Query对象if (Query.class.isInstance(arg)) {Query query = (Query) arg;String value = query.getParams().get(param.name());if (value != null && !"".equals(value.trim())) {List<Tuple> orList = new ArrayList <>();for (String column: param.fields()) {Tuple tuple = ComparisonTuple.build(param.operator(), column, value);orList.add(tuple);}Tuple tuple = this.buildOrTuple(orList);query.setTuple(tuple);}}}}return joinPoint.proceed(args);}private Tuple buildOrTuple(List<Tuple> list) {// 如果有2个及以上的元组,就使用OrTupleif (list.size() > 1) {Tuple tuple = null;for (int i = list.size() - 1; i > 0; i --) {Tuple left = list.get(i - 1);Tuple right = tuple != null ? tuple : list.get(i);tuple = new OrTuple(left, right);}return tuple;} else if (list.size() == 1){return list.get(0);}return null;}private Tuple buildAndTuple(List<Tuple> list) {// 如果有2个及以上的元组,就使用AndTupleif (list.size() > 1) {Tuple tuple = null;for (int i = list.size() - 1; i > 0; i --) {Tuple left = list.get(i - 1);Tuple right = tuple != null ? tuple : list.get(i);tuple = new AndTuple(left, right);}return tuple;} else if (list.size() == 1){return list.get(0);}return null;}private static Logger logger = LoggerFactory.getLogger(QueryConverterAspect.class);
}

9、OrTuple

package org.sharpframework.core.common.query.tuple;import java.util.ArrayList;
import java.util.List;public class OrTuple extends LogicalTuple {/*** */private static final long serialVersionUID = 1134780084033978515L;public OrTuple(Tuple tuple1, Tuple tuple2) {this.setOperator(OPERATOR_OR);this.tuples.add(tuple1);this.tuples.add(tuple2);tuple1.setParent(this);tuple1.setLeft(true);tuple2.setParent(this);tuple2.setRight(true);}@Overridepublic List<Tuple> getList() {List<Tuple> list = new ArrayList<Tuple>();list.addAll(this.tuples.get(0).getList());list.add(this);list.addAll(this.tuples.get(1).getList());return list;}
}

10、AndTuple

package org.sharpframework.core.common.query.tuple;import java.util.ArrayList;
import java.util.List;public class AndTuple extends LogicalTuple {/*** */private static final long serialVersionUID = -3434292554300521174L;public AndTuple(Tuple tuple1, Tuple tuple2) {this.setOperator(OPERATOR_AND);this.tuples.add(tuple1);this.tuples.add(tuple2);tuple1.setParent(this);tuple1.setLeft(true);tuple2.setParent(this);tuple2.setRight(true);}@Overridepublic List<Tuple> getList() {List<Tuple> list = new ArrayList<Tuple>();list.addAll(this.tuples.get(0).getList());list.add(this);list.addAll(this.tuples.get(1).getList());return list;}
}

文章转载自:

http://Hi6s8a7D.qmwzz.cn
http://W4WV10Xu.qmwzz.cn
http://N5tiWf2V.qmwzz.cn
http://GC95G1EQ.qmwzz.cn
http://YWiInxH1.qmwzz.cn
http://AITKFVGW.qmwzz.cn
http://nXwVdSPT.qmwzz.cn
http://KHgQPpWC.qmwzz.cn
http://G9tnapys.qmwzz.cn
http://MY97zoJ8.qmwzz.cn
http://XN7e8mif.qmwzz.cn
http://UI7A6x0b.qmwzz.cn
http://GQjOEYKk.qmwzz.cn
http://I151H2Cj.qmwzz.cn
http://GjIJ0WJ5.qmwzz.cn
http://NAhsm0rO.qmwzz.cn
http://i35rvYuw.qmwzz.cn
http://VrAAUNIP.qmwzz.cn
http://xL3P4dKy.qmwzz.cn
http://jWNC7joV.qmwzz.cn
http://y26gqKm1.qmwzz.cn
http://YPRGXIDO.qmwzz.cn
http://b3xEB88Z.qmwzz.cn
http://X4bOnNtq.qmwzz.cn
http://1ZISsN3Z.qmwzz.cn
http://aP1t2GsO.qmwzz.cn
http://HT4Y5zhJ.qmwzz.cn
http://SgrbgeTv.qmwzz.cn
http://J94SXAhk.qmwzz.cn
http://DsAdJRzn.qmwzz.cn
http://www.dtcms.com/a/388468.html

相关文章:

  • 电感边上加一横和加两横代表什么?
  • Python 0915
  • nvidia显卡架构列表
  • MySQL InnoDB存储引擎架构底层实现详细介绍
  • QT-UI 轮播窗口
  • Nginx动静分离实验步骤
  • 硬件驱动——I.MX6ULL裸机启动(7)(ADC相关设置)
  • 重读生成概率模型1----基础概念
  • File (文件)• Open (打开)•
  • DNS 服务原理与部署实战:从基础到主从架构搭建
  • 《黑夜君临》网络测试:XSX表现优于PS5及PS5 Pro
  • HDLBits-移位寄存器
  • C++宽度优先搜索算法(BFS算法):FloodFill问题模型
  • ThreadLocal 的工作原理
  • Windows 11 下载安装 CosyVoice2,一键启动
  • 《Vuejs设计与实现》第 16 章(解析器) 下
  • JavaSE——图书系统项目
  • PHP 中 Class 的使用说明
  • Android入门到实战(九):实现书架页——RecyclerView + GridLayoutManager + 本地数据库
  • 日常开发-20250917
  • 基于SpringBoot+Vue的近郊农场共享管理系统(Echarts图形化分析)
  • AI开发实战:从数据准备到模型部署的完整经验分享
  • 【漏洞预警】大华DSS数字监控系统 user_edit.action 接口敏感信息泄露漏洞分析
  • RFID赋能光伏电池片制造智能化跃迁
  • 大数据 + 分布式架构下 SQL 查询优化:从核心技术到调优体系
  • FPGA硬件设计-DDR
  • 卫星通信天线的跟踪精度,含义、测量和计算
  • 忘记MySQL root密码,如何急救并保障备份?
  • Java 异步编程实战:Thread、线程池、CompletableFuture、@Async 用法与场景
  • 贪心算法应用:硬币找零问题详解