├── .gitignore ├── README.en.md ├── README.md ├── doc ├── DruidShadowHelper_bak.java ├── SqlParserHelper_bak.java └── 计划 ├── elasticsearch-engine-base ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── elasticsearch │ │ │ └── engine │ │ │ └── base │ │ │ ├── ElasticsearchEngineConfiguration.java │ │ │ ├── common │ │ │ ├── factory │ │ │ │ ├── FactoryList.java │ │ │ │ └── MatchingBean.java │ │ │ ├── parse │ │ │ │ ├── ann │ │ │ │ │ ├── EsAnnQueryEngineCommon.java │ │ │ │ │ ├── EsResponseParse.java │ │ │ │ │ ├── QueryHandlerFactory.java │ │ │ │ │ ├── model │ │ │ │ │ │ ├── EsQueryEngine.java │ │ │ │ │ │ └── QueryAnnParser.java │ │ │ │ │ └── param │ │ │ │ │ │ ├── EsParamQueryEngine.java │ │ │ │ │ │ └── QueryParamAnnParser.java │ │ │ │ └── sql │ │ │ │ │ ├── EsSqlQueryHelper.java │ │ │ │ │ ├── SqlParamParseHelper.java │ │ │ │ │ ├── SqlParserHelper.java │ │ │ │ │ └── SqlResponseParse.java │ │ │ ├── proxy │ │ │ │ ├── EsEngineInterfaceScanner.java │ │ │ │ ├── EsEngineProxyBeanFactory.java │ │ │ │ ├── EsProxyExecuteHandler.java │ │ │ │ ├── EsQueryProxy.java │ │ │ │ ├── enums │ │ │ │ │ ├── EsAnnotationQueryEnum.java │ │ │ │ │ ├── EsQueryType.java │ │ │ │ │ └── EsSqlQueryEnum.java │ │ │ │ └── handler │ │ │ │ │ ├── EsQueryProxyExecuteFactory.java │ │ │ │ │ ├── EsQueryProxyExecuteHandler.java │ │ │ │ │ ├── exannotation │ │ │ │ │ ├── AnnotationQueryCommon.java │ │ │ │ │ ├── EsAnnotationQueryFactory.java │ │ │ │ │ ├── EsAnnotationQueryHandler.java │ │ │ │ │ └── impl │ │ │ │ │ │ ├── EsAnnotationModelQueryHandler.java │ │ │ │ │ │ └── EsAnnotationParamQueryHandler.java │ │ │ │ │ ├── exsql │ │ │ │ │ ├── EsSqlQueryFactory.java │ │ │ │ │ ├── EsSqlQueryHandler.java │ │ │ │ │ └── impl │ │ │ │ │ │ └── EsAnnotationSqlQueryHandler.java │ │ │ │ │ └── impl │ │ │ │ │ ├── EsAnnotationQuery.java │ │ │ │ │ ├── EsNativeQuery.java │ │ │ │ │ └── EsSqlQuery.java │ │ │ ├── queryhandler │ │ │ │ ├── ann │ │ │ │ │ ├── model │ │ │ │ │ │ ├── AbstractEsBaseExecuteHandle.java │ │ │ │ │ │ ├── EsBaseExecuteHandle.java │ │ │ │ │ │ └── EsExecuteHandler.java │ │ │ │ │ └── param │ │ │ │ │ │ └── EsParamExecuteHandler.java │ │ │ │ └── sql │ │ │ │ │ └── EsSqlExecuteHandler.java │ │ │ └── utils │ │ │ │ ├── AnnotationUtils.java │ │ │ │ ├── CaseFormatUtils.java │ │ │ │ ├── ClassPathResourceReaderUtils.java │ │ │ │ ├── DateUtils.java │ │ │ │ ├── ExtAnnBeanMapUtils.java │ │ │ │ ├── HttpClientTool.java │ │ │ │ ├── JsonParser.java │ │ │ │ ├── LocalStringUtils.java │ │ │ │ ├── ReflectionUtils.java │ │ │ │ ├── ThreadLocalUtil.java │ │ │ │ └── serializer │ │ │ │ ├── LocalDateDeserializer.java │ │ │ │ ├── LocalDateSerializer.java │ │ │ │ ├── LocalDateTimeDeserializer.java │ │ │ │ ├── LocalDateTimeSerializer.java │ │ │ │ ├── LocalDateTimeUtils.java │ │ │ │ ├── LocalTimeDeserializer.java │ │ │ │ └── LocalTimeSerializer.java │ │ │ ├── config │ │ │ ├── ElasticSearchProperties.java │ │ │ ├── ElasticsearchConfig.java │ │ │ ├── EsEngineConfig.java │ │ │ ├── EsEngineConfigProperties.java │ │ │ └── LoadFactory.java │ │ │ ├── holder │ │ │ ├── AbstractEsRequestHolder.java │ │ │ ├── BoolEsRequestHolder.java │ │ │ └── DisMaxEsRequestHolder.java │ │ │ ├── hook │ │ │ ├── EsHookReedits.java │ │ │ ├── RequestHook.java │ │ │ ├── ResponseHook.java │ │ │ └── UserHooks.java │ │ │ ├── mapping │ │ │ ├── annotation │ │ │ │ ├── Aggs.java │ │ │ │ ├── Collapse.java │ │ │ │ ├── Exist.java │ │ │ │ ├── From.java │ │ │ │ ├── PageAndOrder.java │ │ │ │ ├── Prefix.java │ │ │ │ ├── Range.java │ │ │ │ ├── Sort.java │ │ │ │ ├── Term.java │ │ │ │ ├── Terms.java │ │ │ │ ├── To.java │ │ │ │ ├── WildCard.java │ │ │ │ ├── hook │ │ │ │ │ ├── UseRequestHook.java │ │ │ │ │ └── UseResponseHook.java │ │ │ │ └── method │ │ │ │ │ ├── Exclude.java │ │ │ │ │ ├── Include.java │ │ │ │ │ ├── Order.java │ │ │ │ │ └── Size.java │ │ │ ├── handler │ │ │ │ ├── AbstractQueryHandler.java │ │ │ │ ├── AggsQueryHandler.java │ │ │ │ ├── CollapseQueryHandler.java │ │ │ │ ├── EsConditionHandle.java │ │ │ │ ├── ExistQueryHandler.java │ │ │ │ ├── FromQueryHandler.java │ │ │ │ ├── PageAndOrderQueryHandler.java │ │ │ │ ├── PrefixQueryHandler.java │ │ │ │ ├── RangeQueryHandler.java │ │ │ │ ├── SortQueryHandler.java │ │ │ │ ├── TermQueryHandler.java │ │ │ │ ├── TermsQueryHandler.java │ │ │ │ ├── ToQueryHandler.java │ │ │ │ └── WildCardQueryHandler.java │ │ │ └── model │ │ │ │ ├── AggsQueryBean.java │ │ │ │ ├── CollapseQueryBean.java │ │ │ │ ├── ExistQueryBean.java │ │ │ │ ├── FromQueryBean.java │ │ │ │ ├── PageQueryBean.java │ │ │ │ ├── PrefixQueryBean.java │ │ │ │ ├── RangeQueryBean.java │ │ │ │ ├── SortQueryBean.java │ │ │ │ ├── TermQueryBean.java │ │ │ │ ├── TermsQueryBean.java │ │ │ │ ├── ToQueryBean.java │ │ │ │ ├── WildCardQueryBean.java │ │ │ │ └── extend │ │ │ │ ├── PageParam.java │ │ │ │ ├── RangeParam.java │ │ │ │ └── SignParam.java │ │ │ └── model │ │ │ ├── annotion │ │ │ ├── Base.java │ │ │ ├── ESColumn.java │ │ │ ├── EsHelperProxy.java │ │ │ ├── EsQuery.java │ │ │ ├── EsQueryHandle.java │ │ │ ├── EsQueryIndex.java │ │ │ ├── Ignore.java │ │ │ ├── MethodQuery.java │ │ │ ├── Nested.java │ │ │ ├── Query.java │ │ │ └── Sign.java │ │ │ ├── constant │ │ │ ├── CommonConstant.java │ │ │ └── EsConstant.java │ │ │ ├── domain │ │ │ ├── AbstractQueryBean.java │ │ │ ├── BackDto.java │ │ │ ├── BaseEsRepository.java │ │ │ ├── BaseHit.java │ │ │ ├── BaseResp.java │ │ │ ├── DefaultAggResp.java │ │ │ ├── DefaultQueryModel.java │ │ │ ├── DefaultResp.java │ │ │ ├── EsComplexParam.java │ │ │ ├── EsQueryFieldBean.java │ │ │ ├── EsQueryIndexBean.java │ │ │ ├── ParamParserResultModel.java │ │ │ ├── SqlErrorResponse.java │ │ │ └── SqlResponse.java │ │ │ ├── emenu │ │ │ ├── DataType.java │ │ │ ├── EsConnector.java │ │ │ ├── EsVersionConstant.java │ │ │ ├── JsonNamingStrategy.java │ │ │ ├── QueryModel.java │ │ │ ├── SortType.java │ │ │ ├── SqlFormat.java │ │ │ └── SqlParamParse.java │ │ │ └── exception │ │ │ ├── EsEngineConfigException.java │ │ │ ├── EsEngineExecuteException.java │ │ │ ├── EsEngineJpaExecuteException.java │ │ │ └── EsEngineQueryException.java │ └── resources │ │ ├── META-INF │ │ └── spring.factories │ │ ├── elasticseach-engine.properties │ │ └── engine-banner.txt │ └── test │ └── java │ └── com │ └── elasticsearch │ └── engine │ └── base │ └── ElasticsearchEngineBaseApplicationTests.java ├── elasticsearch-engine-jooq ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── elasticsearch │ │ │ └── engine │ │ │ └── jooq │ │ │ ├── ElasticsearchEngineJooqConfiguration.java │ │ │ ├── annotion │ │ │ └── JooqEsQuery.java │ │ │ ├── aop │ │ │ └── JooqEsQueryAop.java │ │ │ ├── listener │ │ │ └── JooqEsQueryExecuteListener.java │ │ │ └── model │ │ │ └── JooqBackDto.java │ └── resources │ │ └── META-INF │ │ └── spring.factories │ └── test │ └── java │ └── com │ └── elasticsearch │ └── engine │ └── jooq │ └── ElasticsearchEngineJooqApplicationTests.java ├── elasticsearch-engine-jpa ├── pom.xml └── src │ ├── main │ ├── java │ │ ├── com │ │ │ └── elasticsearch │ │ │ │ └── engine │ │ │ │ └── jpa │ │ │ │ ├── ElasticsearchEngineJpaConfiguration.java │ │ │ │ ├── Inspector │ │ │ │ └── JpaEsQueryStatementInspector.java │ │ │ │ ├── annotion │ │ │ │ └── JpaEsQuery.java │ │ │ │ ├── aop │ │ │ │ └── JpaEsQueryAop.java │ │ │ │ └── model │ │ │ │ └── JpaBackDto.java │ │ └── org │ │ │ └── hibernate │ │ │ └── type │ │ │ └── descriptor │ │ │ └── sql │ │ │ └── BasicBinder.java │ └── resources │ │ └── META-INF │ │ └── spring.factories │ └── test │ └── java │ └── com │ └── elasticsearch │ └── engine │ └── jpa │ └── ElasticsearchEngineJpaApplicationTests.java ├── elasticsearch-engine-mybatis ├── pom.xml └── src │ ├── main │ ├── java │ │ └── com │ │ │ └── elasticsearch │ │ │ └── engine │ │ │ └── mybatis │ │ │ ├── ElasticsearchEngineMybatisConfiguration.java │ │ │ ├── annotion │ │ │ └── MybatisEsQuery.java │ │ │ ├── interceptor │ │ │ └── MybatisEsQueryInterceptor.java │ │ │ ├── model │ │ │ └── MybatisBackDto.java │ │ │ └── parse │ │ │ └── SqlParamParseMybatisHelper.java │ └── resources │ │ └── META-INF │ │ └── spring.factories │ └── test │ └── java │ └── com │ └── elasticsearch │ └── engine │ └── mybatis │ └── ElasticsearchEngineMybatisApplicationTests.java ├── pom.xml └── 流程图 .jpg /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | .DS_Store/ 5 | ### STS ### 6 | .apt_generated 7 | .classpath 8 | .factorypath 9 | .project 10 | .settings 11 | .springBeans 12 | 13 | ### IntelliJ IDEA ### 14 | .idea/ 15 | *.iws 16 | *.iml 17 | *.ipr 18 | 19 | ### NetBeans ### 20 | nbproject/private/ 21 | build/ 22 | nbbuild/ 23 | dist/ 24 | nbdist/ 25 | .nb-gradle/ 26 | 27 | -------------------------------------------------------------------------------- /doc/DruidShadowHelper_bak.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.elasticsearchengine.extend.mybatis; 2 | 3 | import com.alibaba.druid.sql.SQLUtils; 4 | import com.alibaba.druid.sql.ast.SQLStatement; 5 | import com.alibaba.druid.sql.visitor.SchemaStatVisitor; 6 | import org.apache.commons.collections4.CollectionUtils; 7 | import org.apache.commons.collections4.MapUtils; 8 | import org.slf4j.Logger; 9 | import org.slf4j.LoggerFactory; 10 | 11 | import java.util.HashMap; 12 | import java.util.List; 13 | import java.util.Map; 14 | 15 | /** 16 | * 基于Druid的SQL表名改写工具 17 | */ 18 | public class DruidShadowHelper_bak { 19 | private static Logger logger = LoggerFactory.getLogger(DruidShadowHelper_bak.class); 20 | 21 | private static boolean prettySql = false; 22 | 23 | public DruidShadowHelper_bak() { 24 | } 25 | 26 | public DruidShadowHelper_bak(boolean prettySql) { 27 | this.prettySql = prettySql; 28 | } 29 | 30 | public static String generateShadowSql(String originSql) { 31 | String dbType = "mysql"; 32 | //解析sql 33 | List statementList = SQLUtils.parseStatements(originSql, dbType); 34 | if (CollectionUtils.isEmpty(statementList)) { 35 | logger.warn("无法解析,返回原SQL:{}", originSql); 36 | return originSql; 37 | } 38 | //遍历 - 获取表名 39 | SchemaStatVisitor visitor = SQLUtils.createSchemaStatVisitor(dbType); 40 | statementList.get(0).accept(visitor); 41 | if (MapUtils.isEmpty(visitor.getTables())) { 42 | logger.warn("无法获取表名,返回原SQL:{}", originSql); 43 | return originSql; 44 | } 45 | Map tableMapping = new HashMap<>(visitor.getTables().size()); 46 | visitor.getTables().keySet().forEach(tableNameStat -> { 47 | tableMapping.put(tableNameStat.getName(), "123"); 48 | }); 49 | //遍历 - 修改表名 50 | return SQLUtils.toSQLString(statementList, dbType, null, new SQLUtils.FormatOption(false, prettySql), tableMapping); 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /doc/计划: -------------------------------------------------------------------------------- 1 | 小版本: 2 | 1)回表查询数量限制 3 | 2)模块拆分 解除依赖 4 | 3)分页查询 5 | 4)固定值查询扩展 双层分组, 分组聚合 6 | 5)自定义注解sql查询 对象参数 (参考 mybatis和jpa实现参数解析) 7 | 6)工具类整理, http工具类优化 8 | 7)sql日志打印支持配置 9 | 8)es 和 mysql字段映射关系支持自定义 10 | 11 | 其他: 12 | 1)@EsCondition 思考 13 | 2)hook 外置话思考 14 | 写在 其他类, 写在一个类里面的方法(一个类中可以声明多个方法) 15 | 3)查询语句日志 可配置 16 | 4)sql 参数校验 阻断 17 | 18 | 19 | sql输出,es真实查询语句输出, es查询统计,es慢查统计, 告警 20 | 21 | 22 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | elasticsearch-engine 6 | com.elasticsearch.engine 7 | 0.0.1-SNAPSHOT 8 | 9 | 4.0.0 10 | 11 | elasticsearch-engine-base 12 | 13 | 14 | 15 | org.springframework.boot 16 | spring-boot-starter 17 | 18 | 19 | org.springframework.boot 20 | spring-boot-starter-test 21 | test 22 | 23 | 24 | org.springframework.boot 25 | spring-boot-configuration-processor 26 | true 27 | 28 | 29 | org.projectlombok 30 | lombok 31 | 32 | 33 | com.fasterxml.jackson.core 34 | jackson-databind 35 | 36 | 37 | com.fasterxml.jackson.core 38 | jackson-annotations 39 | 40 | 41 | org.apache.commons 42 | commons-lang3 43 | 44 | 45 | org.apache.commons 46 | commons-collections4 47 | 48 | 49 | com.google.guava 50 | guava 51 | 52 | 53 | org.reflections 54 | reflections 55 | 56 | 57 | 58 | org.elasticsearch.client 59 | elasticsearch-rest-high-level-client 60 | 61 | 62 | com.github.jsqlparser 63 | jsqlparser 64 | 65 | 66 | org.springframework.boot 67 | spring-boot-starter-aop 68 | 69 | 70 | org.springframework.boot 71 | spring-boot-starter-jdbc 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/ElasticsearchEngineConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base; 2 | 3 | import com.elasticsearch.engine.base.common.parse.ann.QueryHandlerFactory; 4 | import com.elasticsearch.engine.base.config.ElasticSearchProperties; 5 | import com.elasticsearch.engine.base.config.EsEngineConfigProperties; 6 | import com.elasticsearch.engine.base.config.LoadFactory; 7 | import lombok.extern.slf4j.Slf4j; 8 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 9 | import org.springframework.context.annotation.ComponentScan; 10 | import org.springframework.context.annotation.Configuration; 11 | 12 | import javax.annotation.PostConstruct; 13 | import java.util.stream.Collectors; 14 | 15 | /** 16 | * @author wanghuan 17 | * @description: com.elasticsearch.engine.base.ElasticsearchEngineConfiguration 18 | * @date 2022-01-26 11:28 19 | */ 20 | @Slf4j 21 | @Configuration 22 | @EnableConfigurationProperties(value = {ElasticSearchProperties.class, EsEngineConfigProperties.class}) 23 | @ComponentScan(basePackages = "com.elasticsearch.engine.base") 24 | public class ElasticsearchEngineConfiguration { 25 | 26 | @PostConstruct 27 | public void load() { 28 | String banner = LoadFactory.readBanner(); 29 | log.info(banner); 30 | log.info("es-helper-query-handler-scanner load handles:\n{}\n", 31 | QueryHandlerFactory.QUERY_HANDLE_MAP.entrySet().stream().map( 32 | e -> "[\tes-helper] " + e.getKey() + ":" + e.getValue() 33 | ).collect(Collectors.joining("\n")) 34 | ); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/common/factory/FactoryList.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.common.factory; 2 | 3 | /** 4 | * @Author 王欢 5 | * @Date 2020/02/19 6 | * @Time 15:28:59 7 | */ 8 | public interface FactoryList, K> { 9 | E getBean(K factory); 10 | } 11 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/common/factory/MatchingBean.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.common.factory; 2 | 3 | /** 4 | * @Author 王欢 5 | * @Date 2020/02/19 6 | * @Time 15:28:59 7 | */ 8 | public interface MatchingBean { 9 | Boolean matching(T factory); 10 | } 11 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/common/parse/ann/QueryHandlerFactory.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.common.parse.ann; 2 | 3 | import com.elasticsearch.engine.base.common.utils.ReflectionUtils; 4 | import com.elasticsearch.engine.base.mapping.handler.AbstractQueryHandler; 5 | import com.elasticsearch.engine.base.model.annotion.EsQueryHandle; 6 | import com.elasticsearch.engine.base.model.exception.EsEngineConfigException; 7 | import com.elasticsearch.engine.base.model.exception.EsEngineQueryException; 8 | import org.apache.commons.lang3.StringUtils; 9 | import org.reflections.Reflections; 10 | 11 | import java.util.HashMap; 12 | import java.util.Map; 13 | import java.util.Set; 14 | 15 | /** 16 | * @author wanghuan 17 | * @description: QueryHandlerFactory 18 | * @date 2022-01-26 11:28 19 | */ 20 | public class QueryHandlerFactory { 21 | 22 | public static final Map QUERY_HANDLE_MAP = new HashMap<>(); 23 | 24 | /** 25 | * 初始化查询注解和对应的Handler映射 26 | * key: Term value:TermQueryHandler.class 27 | */ 28 | static { 29 | //获取该路径下所有类 30 | Reflections reflections = new Reflections(AbstractQueryHandler.class.getPackage().getName()); 31 | //获取继承了AbstractQueryHandler的所有类 32 | Set> subQueryClazz = reflections.getSubTypesOf(AbstractQueryHandler.class); 33 | for (Class targetClazz : subQueryClazz) { 34 | boolean flag = targetClazz.isAnnotationPresent(EsQueryHandle.class); 35 | if (!flag) { 36 | throw new EsEngineConfigException("query handle have to ann by @EsQueryHandle"); 37 | } 38 | EsQueryHandle ann = targetClazz.getAnnotation(EsQueryHandle.class); 39 | String handleName = ann.queryType(); 40 | if (StringUtils.isBlank(handleName)) { 41 | handleName = ann.value().getSimpleName(); 42 | } 43 | if (StringUtils.isBlank(handleName)) { 44 | throw new EsEngineConfigException("handle-name is undefine"); 45 | } 46 | QueryHandlerFactory.registryQueryHandler(handleName, targetClazz); 47 | } 48 | } 49 | 50 | /** 51 | * 注册查询注解和对应的Handler映射 52 | * 53 | * @param handleName 54 | * @param targetClazz 55 | */ 56 | public static void registryQueryHandler(String handleName, Class targetClazz) { 57 | QUERY_HANDLE_MAP.put(handleName, getTargetHandleInstance(targetClazz)); 58 | } 59 | 60 | /** 61 | * 获取Handler实例 62 | * 63 | * @param handlerName 64 | * @return 65 | */ 66 | public static AbstractQueryHandler getTargetHandleInstance(String handlerName) { 67 | AbstractQueryHandler targetHandler = QUERY_HANDLE_MAP.get(handlerName); 68 | if (targetHandler == null) { 69 | throw new EsEngineQueryException("un-match given handleName"); 70 | } 71 | return targetHandler; 72 | } 73 | 74 | /** 75 | * 创建Handler实例 76 | * 77 | * @param targetClazz 78 | * @return 79 | */ 80 | private static AbstractQueryHandler getTargetHandleInstance(Class targetClazz) { 81 | return ReflectionUtils.newInstance(targetClazz); 82 | } 83 | 84 | 85 | } 86 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/common/parse/ann/model/EsQueryEngine.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.common.parse.ann.model; 2 | 3 | 4 | import com.elasticsearch.engine.base.common.parse.ann.EsAnnQueryEngineCommon; 5 | import com.elasticsearch.engine.base.holder.AbstractEsRequestHolder; 6 | import com.elasticsearch.engine.base.mapping.handler.AbstractQueryHandler; 7 | import com.elasticsearch.engine.base.model.domain.EsQueryFieldBean; 8 | import com.elasticsearch.engine.base.model.domain.EsQueryIndexBean; 9 | import com.elasticsearch.engine.base.model.domain.ParamParserResultModel; 10 | import com.elasticsearch.engine.base.common.parse.ann.QueryHandlerFactory; 11 | 12 | import java.lang.reflect.Method; 13 | 14 | /** 15 | * @author wanghuan 16 | * @description: EsQueryEngine 17 | * @date 2022-01-26 11:28 18 | * @email 1078481395@qq.com 19 | */ 20 | public class EsQueryEngine extends EsAnnQueryEngineCommon { 21 | 22 | /** 23 | * 解析查询参数 24 | * 25 | * @param queryViewObj 26 | * @param visitParent return 27 | */ 28 | public static AbstractEsRequestHolder execute(Method method, Object queryViewObj, boolean visitParent) { 29 | QueryAnnParser translator = QueryAnnParser.instance(); 30 | //解析类注解 index信息及包含的字段 31 | EsQueryIndexBean indexQueryBean = translator.getIndex(method,queryViewObj); 32 | //解析具体的注解 字段,字段值,注解,查询类型 33 | ParamParserResultModel read = translator.read(queryViewObj, visitParent); 34 | //构建查询信息 35 | AbstractEsRequestHolder helper = AbstractEsRequestHolder.builder().config(indexQueryBean).build(read); 36 | for (EsQueryFieldBean queryDes : read.getQueryDesList()) { 37 | String queryKey = queryDes.getQueryType(); 38 | //构建具体的查询处理Handler 39 | AbstractQueryHandler queryHandle = QueryHandlerFactory.getTargetHandleInstance(queryKey); 40 | //拼装查询语句逻辑具体执行 41 | queryHandle.execute(queryDes, helper); 42 | } 43 | //后置逻辑扩展 44 | enginePostProcessor(helper,method); 45 | return helper; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/common/parse/ann/param/EsParamQueryEngine.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.common.parse.ann.param; 2 | 3 | 4 | import com.elasticsearch.engine.base.common.parse.ann.EsAnnQueryEngineCommon; 5 | import com.elasticsearch.engine.base.common.parse.ann.QueryHandlerFactory; 6 | import com.elasticsearch.engine.base.holder.AbstractEsRequestHolder; 7 | import com.elasticsearch.engine.base.mapping.handler.AbstractQueryHandler; 8 | import com.elasticsearch.engine.base.model.domain.EsQueryFieldBean; 9 | import com.elasticsearch.engine.base.model.domain.EsQueryIndexBean; 10 | import com.elasticsearch.engine.base.model.domain.ParamParserResultModel; 11 | 12 | import java.lang.reflect.Method; 13 | 14 | /** 15 | * @author wanghuan 16 | * @description: EsParamQueryEngine 17 | * @date 2022-01-26 11:28 18 | * @email 1078481395@qq.com 19 | */ 20 | public class EsParamQueryEngine extends EsAnnQueryEngineCommon { 21 | 22 | /** 23 | * 解析查询参数 24 | * 25 | * @param method 26 | * @param args 27 | * @return 28 | */ 29 | public static AbstractEsRequestHolder execute(Method method, Object[] args) { 30 | QueryParamAnnParser translator = QueryParamAnnParser.instance(); 31 | //解析类注解 index信息及包含的字段 32 | EsQueryIndexBean indexQueryBean = translator.getIndex(method); 33 | //解析具体的注解 字段,字段值,注解,查询类型 34 | ParamParserResultModel read = translator.read(method, args); 35 | //构建查询信息 36 | AbstractEsRequestHolder helper = AbstractEsRequestHolder.builder().config(indexQueryBean).build(read); 37 | for (EsQueryFieldBean queryDes : read.getQueryDesList()) { 38 | String queryKey = queryDes.getQueryType(); 39 | //构建具体的查询处理Handler 40 | AbstractQueryHandler queryHandle = QueryHandlerFactory.getTargetHandleInstance(queryKey); 41 | //拼装查询语句逻辑具体执行 42 | queryHandle.execute(queryDes, helper); 43 | } 44 | //后置逻辑扩展 45 | enginePostProcessor(helper, method); 46 | return helper; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/common/proxy/EsEngineProxyBeanFactory.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.common.proxy; 2 | 3 | import org.elasticsearch.client.RestHighLevelClient; 4 | import org.springframework.beans.BeansException; 5 | import org.springframework.beans.factory.FactoryBean; 6 | import org.springframework.beans.factory.InitializingBean; 7 | import org.springframework.context.ApplicationContext; 8 | import org.springframework.context.ApplicationContextAware; 9 | 10 | import javax.annotation.Resource; 11 | import java.lang.reflect.Proxy; 12 | import java.util.Objects; 13 | import java.util.Optional; 14 | 15 | /** 16 | * @author wanghuan 17 | * @description EsEngineProxyBeanFactory 18 | * @mail 958721894@qq.com 19 | * @date 2022/6/9 14:10 20 | */ 21 | public class EsEngineProxyBeanFactory implements ApplicationContextAware, InitializingBean, FactoryBean { 22 | 23 | private static final String ENABLE_LOG_OUT_PROPERTIES = "es.helper.queryLogOut.enable"; 24 | private Class targetInterfaceClazz; 25 | private boolean visitQueryBeanParent = Boolean.TRUE; 26 | @Resource 27 | private EsProxyExecuteHandler esProxyExecuteHandler; 28 | private ApplicationContext applicationContext; 29 | private boolean enableLogOut = false; 30 | 31 | public EsEngineProxyBeanFactory(Class targetInterfaceClazz) { 32 | this.targetInterfaceClazz = targetInterfaceClazz; 33 | } 34 | 35 | public EsEngineProxyBeanFactory(Class targetInterfaceClazz, boolean visitQueryBeanParent) { 36 | this.targetInterfaceClazz = targetInterfaceClazz; 37 | this.visitQueryBeanParent = visitQueryBeanParent; 38 | } 39 | 40 | @Override 41 | public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { 42 | this.applicationContext = applicationContext; 43 | } 44 | 45 | /** 46 | * 返回FactoryBean创建的bean 47 | * 调用 getBean("EsEngineProxyBeanFactory"),会调用EsEngineProxyBeanFactory.getObject() 返回对象 48 | * 49 | * @return 50 | */ 51 | @Override 52 | public T getObject() { 53 | return (T) Proxy.newProxyInstance( 54 | targetInterfaceClazz.getClassLoader(), 55 | new Class[]{targetInterfaceClazz}, 56 | new EsQueryProxy(targetInterfaceClazz, visitQueryBeanParent, esProxyExecuteHandler, enableLogOut) 57 | ); 58 | } 59 | 60 | @Override 61 | public Class getObjectType() { 62 | return targetInterfaceClazz; 63 | } 64 | 65 | @Override 66 | public boolean isSingleton() { 67 | return true; 68 | } 69 | 70 | @Override 71 | public void afterPropertiesSet() { 72 | RestHighLevelClient restClient = applicationContext.getBean(RestHighLevelClient.class); 73 | Objects.requireNonNull(restClient, "SpringContext haven't RestHighLevelClient, config it"); 74 | this.enableLogOut = Optional.ofNullable( 75 | applicationContext.getEnvironment().getProperty(ENABLE_LOG_OUT_PROPERTIES, Boolean.class) 76 | ).orElse(true); 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/common/proxy/EsProxyExecuteHandler.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.common.proxy; 2 | 3 | import com.elasticsearch.engine.base.common.proxy.enums.EsQueryType; 4 | import com.elasticsearch.engine.base.common.proxy.handler.EsQueryProxyExecuteFactory; 5 | import com.elasticsearch.engine.base.model.annotion.EsQuery; 6 | import org.springframework.stereotype.Component; 7 | 8 | import javax.annotation.Resource; 9 | import java.lang.reflect.Method; 10 | 11 | /** 12 | * @author wanghuan 13 | * @description: ROOD 14 | * @date 2022-04-15 19:15 15 | */ 16 | @Component 17 | public class EsProxyExecuteHandler { 18 | 19 | @Resource 20 | private EsQueryProxyExecuteFactory esQueryProxyExecuteFactory; 21 | 22 | /** 23 | * 1.注解 24 | * * 1)model注解 25 | * * 2)方法参数注解 26 | * * 1)model注解查询 27 | * * 2)参数注解查询 28 | * 2.sql 29 | * * 1)注解 30 | * * 2)xml 31 | * 3.es原生语句 32 | * * 1)注解 33 | * * 2)xml 34 | * 35 | * @param proxy 36 | * @param method 37 | * @param args 38 | * @return 39 | */ 40 | public Object invoke(Object proxy, Method method, Object[] args) { 41 | EsQueryType annotationQuery = EsQueryType.ANNOTATION; 42 | //有查询注解 43 | if (method.isAnnotationPresent(EsQuery.class)) { 44 | EsQuery annotation = method.getAnnotation(EsQuery.class); 45 | annotationQuery = annotation.queryType(); 46 | } 47 | return esQueryProxyExecuteFactory.getBean(annotationQuery).handle(proxy, method, args); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/common/proxy/EsQueryProxy.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.common.proxy; 2 | 3 | import com.elasticsearch.engine.base.common.utils.ThreadLocalUtil; 4 | import com.elasticsearch.engine.base.model.constant.CommonConstant; 5 | import org.slf4j.Logger; 6 | import org.slf4j.LoggerFactory; 7 | 8 | import java.lang.reflect.InvocationHandler; 9 | import java.lang.reflect.Method; 10 | 11 | /** 12 | * @author wanghuan 13 | * @description EsQueryProxy 14 | * @mail 958721894@qq.com 15 | * @date 2022/6/9 14:12 16 | */ 17 | public class EsQueryProxy implements InvocationHandler { 18 | private static final Logger log = LoggerFactory.getLogger(EsQueryProxy.class); 19 | 20 | private Class targetInterface; 21 | 22 | private boolean visitQueryBeanParent = true; 23 | 24 | private EsProxyExecuteHandler esProxyExecuteHandler; 25 | 26 | private boolean enableLogOut = false; 27 | 28 | public EsQueryProxy(Class targetInterface, boolean visitQueryBeanParent) { 29 | this.targetInterface = targetInterface; 30 | this.visitQueryBeanParent = visitQueryBeanParent; 31 | } 32 | 33 | public EsQueryProxy(Class targetInterface, boolean visitQueryBeanParent, EsProxyExecuteHandler esProxyExecuteHandler, boolean enableLogOut) { 34 | this.targetInterface = targetInterface; 35 | this.visitQueryBeanParent = visitQueryBeanParent; 36 | this.esProxyExecuteHandler = esProxyExecuteHandler; 37 | this.enableLogOut = enableLogOut; 38 | } 39 | 40 | @Override 41 | public Object invoke(Object proxy, Method method, Object[] args) { 42 | String methodName = targetInterface.getSimpleName() + "." + method.getName() + " "; 43 | ThreadLocalUtil.set(CommonConstant.INTERFACE_METHOD_NAME, methodName); 44 | try { 45 | return esProxyExecuteHandler.invoke(proxy, method, args); 46 | } catch (Exception e) { 47 | throw e; 48 | } finally { 49 | ThreadLocalUtil.remove(CommonConstant.INTERFACE_METHOD_NAME); 50 | } 51 | } 52 | 53 | } 54 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/common/proxy/enums/EsAnnotationQueryEnum.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.common.proxy.enums; 2 | 3 | import java.util.Arrays; 4 | import java.util.Optional; 5 | 6 | /** 7 | * @author wanghuan 8 | * @description: es注解查询类型枚举 9 | * @date 2022-04-15 18:16 10 | */ 11 | public enum EsAnnotationQueryEnum { 12 | 13 | /** 14 | * 15 | */ 16 | ANNOTATION_MODEL_QUERY(1, "model注解"), 17 | ANNOTATION_PARAM_QUERY(2, "方法参数注解"), 18 | ; 19 | 20 | private Integer key; 21 | private String value; 22 | 23 | EsAnnotationQueryEnum(Integer key, String value) { 24 | this.key = key; 25 | this.value = value; 26 | } 27 | 28 | public static EsQueryType of(Integer key) { 29 | Optional exportEnum = Arrays.stream(EsQueryType.values()) 30 | .filter(c -> c.getKey().equals(key)).findFirst(); 31 | return exportEnum.orElse(null); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/common/proxy/enums/EsQueryType.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.common.proxy.enums; 2 | 3 | import lombok.Getter; 4 | 5 | import java.util.Arrays; 6 | import java.util.Optional; 7 | 8 | /** 9 | * @author wanghuan 10 | * @description: ES查询执行器handler 11 | * @date 2022-04-15 18:16 12 | */ 13 | @Getter 14 | public enum EsQueryType { 15 | 16 | /** 17 | * 18 | */ 19 | ANNOTATION(1, "注解查询"), 20 | SQL(2, "sql查询"), 21 | ES_NATIVE(3, "es原生语句查询"), 22 | ; 23 | 24 | private Integer key; 25 | private String value; 26 | 27 | EsQueryType(Integer key, String value) { 28 | this.key = key; 29 | this.value = value; 30 | } 31 | 32 | public static EsQueryType of(Integer key) { 33 | Optional exportEnum = Arrays.stream(EsQueryType.values()) 34 | .filter(c -> c.getKey().equals(key)).findFirst(); 35 | return exportEnum.orElse(null); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/common/proxy/enums/EsSqlQueryEnum.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.common.proxy.enums; 2 | 3 | import java.util.Arrays; 4 | import java.util.Optional; 5 | 6 | /** 7 | * @author wanghuan 8 | * @description: es sql查询类型枚举 9 | * @date 2022-04-15 18:16 10 | */ 11 | public enum EsSqlQueryEnum { 12 | 13 | /** 14 | * 15 | */ 16 | ANNOTATION_QUERY(1, "注解查询"), 17 | XML_QUERY(2, "xml查询"), 18 | ; 19 | 20 | private Integer key; 21 | private String value; 22 | 23 | EsSqlQueryEnum(Integer key, String value) { 24 | this.key = key; 25 | this.value = value; 26 | } 27 | 28 | public static EsQueryType of(Integer key) { 29 | Optional exportEnum = Arrays.stream(EsQueryType.values()) 30 | .filter(c -> c.getKey().equals(key)).findFirst(); 31 | return exportEnum.orElse(null); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/common/proxy/handler/EsQueryProxyExecuteFactory.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.common.proxy.handler; 2 | 3 | 4 | import com.elasticsearch.engine.base.common.factory.FactoryList; 5 | import com.elasticsearch.engine.base.common.proxy.enums.EsQueryType; 6 | import com.elasticsearch.engine.base.model.exception.EsEngineExecuteException; 7 | import org.springframework.stereotype.Component; 8 | 9 | import javax.annotation.Resource; 10 | import java.util.List; 11 | 12 | 13 | /** 14 | * @Author 王欢 15 | * @Date 2020/02/19 16 | * @Time 15:28:59 17 | *

18 | * messageProcessFacadeFactory.getBean(MqHandleCodeEnum.of(cache.getEventCode())) 19 | * .process(cache); 20 | */ 21 | @Component 22 | public class EsQueryProxyExecuteFactory implements FactoryList { 23 | 24 | @Resource 25 | private List esQueryProxyHandles; 26 | 27 | @Override 28 | public EsQueryProxyExecuteHandler getBean(EsQueryType factory) { 29 | for (EsQueryProxyExecuteHandler esQueryProxyHandle : esQueryProxyHandles) { 30 | if (esQueryProxyHandle.matching(factory)) { 31 | return esQueryProxyHandle; 32 | } 33 | } 34 | throw new EsEngineExecuteException("factory class not found"); 35 | } 36 | } 37 | 38 | 39 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/common/proxy/handler/EsQueryProxyExecuteHandler.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.common.proxy.handler; 2 | 3 | 4 | import com.elasticsearch.engine.base.common.factory.MatchingBean; 5 | import com.elasticsearch.engine.base.common.proxy.enums.EsQueryType; 6 | 7 | import java.lang.reflect.Method; 8 | 9 | /** 10 | * @Author 王欢 11 | * @Date 2020/02/19 12 | * @Time 15:28:59 13 | */ 14 | public interface EsQueryProxyExecuteHandler extends MatchingBean { 15 | 16 | Object handle(Object proxy, Method method, Object[] args); 17 | } 18 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/common/proxy/handler/exannotation/AnnotationQueryCommon.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.common.proxy.handler.exannotation; 2 | 3 | import com.elasticsearch.engine.base.model.domain.BaseResp; 4 | import com.elasticsearch.engine.base.model.exception.EsEngineExecuteException; 5 | 6 | import java.lang.reflect.Method; 7 | import java.lang.reflect.ParameterizedType; 8 | import java.lang.reflect.Type; 9 | import java.util.Arrays; 10 | import java.util.List; 11 | import java.util.Map; 12 | import java.util.Objects; 13 | import java.util.function.Function; 14 | import java.util.stream.Collectors; 15 | 16 | /** 17 | * @author wanghuan 18 | * @description: 注解proxy查询handler工具类 19 | * @date 2022-04-16 23:08 20 | */ 21 | public class AnnotationQueryCommon { 22 | 23 | /** 24 | * 获取clazz 实现的 implClass接口对应的第一个泛型的class 25 | * 26 | * @param clazz 27 | * @return 28 | */ 29 | public static Class getClazzImplClassGeneric(Class clazz, Class implClass) { 30 | Type type = getClazzImplClassGenericType(clazz, implClass); 31 | //获取到Repository泛型的Entity类 32 | if (type instanceof Class) { 33 | return (Class) type; 34 | } 35 | return null; 36 | } 37 | 38 | /** 39 | * 获取方法返回值对应的泛型 40 | * 41 | * @param method 42 | * @return 43 | */ 44 | public static Class getReturnGenericType(Method method) { 45 | Class actualType = null; 46 | Class returnType = method.getReturnType(); 47 | if (returnType == List.class || returnType == BaseResp.class) { 48 | Type type = method.getGenericReturnType(); 49 | if (type instanceof ParameterizedType) { 50 | Type[] actualTypeArguments = ((ParameterizedType) type).getActualTypeArguments(); 51 | //因为list泛型只有一个值 所以直接取0下标 52 | String typeName = actualTypeArguments[0].getTypeName(); 53 | //真实返回值类型 Class对象 54 | try { 55 | actualType = Class.forName(typeName); 56 | } catch (ClassNotFoundException e) { 57 | throw new RuntimeException(e); 58 | } 59 | } 60 | } 61 | return actualType; 62 | } 63 | 64 | /** 65 | * 获取clazz 实现的 implClass接口对应的第一个泛型的class 66 | * 67 | * @param clazz 68 | * @return 69 | */ 70 | public static Type getClazzImplClassGenericType(Class clazz, Class implClass) { 71 | EsEngineExecuteException esHelperExecuteException = new EsEngineExecuteException("泛型声明异常: " + clazz.getSimpleName() + " implements " + implClass.getSimpleName()); 72 | //获取class实现的接口 73 | Type[] interfaces = clazz.getGenericInterfaces(); 74 | Map, ParameterizedType> collect = Arrays.stream(interfaces).map(type -> { 75 | if (!(type instanceof ParameterizedType)) { 76 | throw new EsEngineExecuteException("泛型声明异常: " + clazz.getSimpleName() + " 缺少泛型声明"); 77 | } 78 | return (ParameterizedType) type; 79 | }).collect(Collectors.toMap(item -> { 80 | try { 81 | return Class.forName(item.getRawType().getTypeName()); 82 | } catch (ClassNotFoundException e) { 83 | throw new RuntimeException(e); 84 | } 85 | }, Function.identity())); 86 | 87 | ParameterizedType parameterizedType = collect.get(implClass); 88 | if (Objects.isNull(parameterizedType)) { 89 | throw esHelperExecuteException; 90 | } 91 | 92 | Type[] actualTypeArguments = parameterizedType.getActualTypeArguments(); 93 | if (actualTypeArguments == null || actualTypeArguments.length < 1) { 94 | throw esHelperExecuteException; 95 | } 96 | //获取到Repository泛型的Entity类 97 | return actualTypeArguments[0]; 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/common/proxy/handler/exannotation/EsAnnotationQueryFactory.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.common.proxy.handler.exannotation; 2 | 3 | import com.elasticsearch.engine.base.common.factory.FactoryList; 4 | import com.elasticsearch.engine.base.common.proxy.enums.EsAnnotationQueryEnum; 5 | import com.elasticsearch.engine.base.model.exception.EsEngineExecuteException; 6 | import org.springframework.stereotype.Component; 7 | 8 | import javax.annotation.Resource; 9 | import java.util.List; 10 | 11 | /** 12 | * @author wanghuan 13 | * @description: ROOD 14 | * @date 2022-04-15 19:03 15 | */ 16 | @Component 17 | public class EsAnnotationQueryFactory implements FactoryList { 18 | 19 | @Resource 20 | private List esAnnotationQueryHandlers; 21 | 22 | @Override 23 | public EsAnnotationQueryHandler getBean(EsAnnotationQueryEnum factory) { 24 | for (EsAnnotationQueryHandler esAnnotationQueryHandler : esAnnotationQueryHandlers) { 25 | if (esAnnotationQueryHandler.matching(factory)) { 26 | return esAnnotationQueryHandler; 27 | } 28 | } 29 | throw new EsEngineExecuteException("factory class not found"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/common/proxy/handler/exannotation/EsAnnotationQueryHandler.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.common.proxy.handler.exannotation; 2 | 3 | 4 | import com.elasticsearch.engine.base.common.factory.MatchingBean; 5 | import com.elasticsearch.engine.base.common.proxy.enums.EsAnnotationQueryEnum; 6 | 7 | import java.lang.reflect.Method; 8 | 9 | /** 10 | * @author wanghuan 11 | * @description: ROOD 12 | * @date 2022-04-15 18:15 13 | */ 14 | public interface EsAnnotationQueryHandler extends MatchingBean { 15 | 16 | Object handle(Object proxy, Method method, Object[] args); 17 | } 18 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/common/proxy/handler/exannotation/impl/EsAnnotationModelQueryHandler.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.common.proxy.handler.exannotation.impl; 2 | 3 | import com.elasticsearch.engine.base.common.proxy.enums.EsAnnotationQueryEnum; 4 | import com.elasticsearch.engine.base.common.proxy.handler.exannotation.AnnotationQueryCommon; 5 | import com.elasticsearch.engine.base.common.proxy.handler.exannotation.EsAnnotationQueryHandler; 6 | import com.elasticsearch.engine.base.common.queryhandler.ann.model.EsExecuteHandler; 7 | import com.elasticsearch.engine.base.common.utils.ThreadLocalUtil; 8 | import com.elasticsearch.engine.base.hook.ResponseHook; 9 | import com.elasticsearch.engine.base.model.constant.CommonConstant; 10 | import com.elasticsearch.engine.base.model.domain.BaseEsRepository; 11 | import com.elasticsearch.engine.base.model.domain.BaseResp; 12 | import com.elasticsearch.engine.base.model.domain.DefaultResp; 13 | import com.elasticsearch.engine.base.model.exception.EsEngineExecuteException; 14 | import com.elasticsearch.engine.base.model.exception.EsEngineQueryException; 15 | import org.springframework.stereotype.Component; 16 | 17 | import javax.annotation.Resource; 18 | import java.lang.reflect.Method; 19 | import java.lang.reflect.Type; 20 | import java.util.List; 21 | import java.util.Objects; 22 | 23 | /** 24 | * @author wanghuan 25 | * @description: model注解proxy查询handler 26 | * @date 2022-04-15 19:08 27 | */ 28 | @Component 29 | public class EsAnnotationModelQueryHandler implements EsAnnotationQueryHandler { 30 | 31 | @Resource 32 | private EsExecuteHandler esExecuteHandler; 33 | 34 | 35 | @Override 36 | public Boolean matching(EsAnnotationQueryEnum factory) { 37 | return EsAnnotationQueryEnum.ANNOTATION_MODEL_QUERY.equals(factory); 38 | } 39 | 40 | @Override 41 | public Object handle(Object proxy, Method method, Object[] args) { 42 | String prefix = ThreadLocalUtil.get(CommonConstant.INTERFACE_METHOD_NAME); 43 | if (args.length > 1) { 44 | throw new EsEngineQueryException(prefix + "ES-ENGINE un-support multi-params, params must be single"); 45 | } 46 | //方法参数 47 | Object param = args[0]; 48 | //方法返回值 49 | Class returnType = method.getReturnType(); 50 | Type returnTypeType = method.getGenericReturnType(); 51 | //方法返回值的泛型 52 | Class returnGenericType = AnnotationQueryCommon.getReturnGenericType(method); 53 | //获取到Repository泛型的Entity类 54 | Class retEntityClass = AnnotationQueryCommon.getClazzImplClassGeneric(method.getDeclaringClass(), BaseEsRepository.class); 55 | //获取到param参数 实现的ResponseHook中的泛型类 56 | Type responseHookResultType = null; 57 | if (ResponseHook.class.isAssignableFrom(param.getClass())) { 58 | responseHookResultType = AnnotationQueryCommon.getClazzImplClassGenericType(param.getClass(), ResponseHook.class); 59 | } 60 | //Repository泛型 单个返回值 61 | if (returnType.isAssignableFrom(retEntityClass)) { 62 | return esExecuteHandler.executeOne(method, param, returnType); 63 | } 64 | //Repository泛型 List返回值 65 | if (List.class.isAssignableFrom(returnType) 66 | && Objects.nonNull(returnGenericType) 67 | && returnGenericType.isAssignableFrom(retEntityClass)) { 68 | return esExecuteHandler.executeList(method, param, returnGenericType); 69 | } 70 | //Repository泛型 BaseResp返回值 71 | if (BaseResp.class.isAssignableFrom(returnType) 72 | && Objects.nonNull(returnGenericType) 73 | && returnGenericType.isAssignableFrom(retEntityClass)) { 74 | return esExecuteHandler.execute(method, param, returnGenericType); 75 | } 76 | //默认固定的实体响应 77 | if (BaseResp.class.isAssignableFrom(returnType) 78 | && Objects.nonNull(returnGenericType) 79 | && DefaultResp.class.isAssignableFrom(returnGenericType)) { 80 | return esExecuteHandler.executeDefaultResp(method, param); 81 | } 82 | //自定义ResponseHook返回值 83 | if (Objects.nonNull(responseHookResultType) && returnTypeType.getTypeName().equals(responseHookResultType.getTypeName())) { 84 | return esExecuteHandler.execute(method, param, returnType).getResult(); 85 | } 86 | throw new EsEngineExecuteException(prefix + "方法返回值泛型匹配异常: 返回值必须是 Repository 的泛型类型或 ResponseHook 的泛型类型或 DefaultResp 的实现类"); 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/common/proxy/handler/exannotation/impl/EsAnnotationParamQueryHandler.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.common.proxy.handler.exannotation.impl; 2 | 3 | import com.elasticsearch.engine.base.common.proxy.enums.EsAnnotationQueryEnum; 4 | import com.elasticsearch.engine.base.common.proxy.handler.exannotation.AnnotationQueryCommon; 5 | import com.elasticsearch.engine.base.common.proxy.handler.exannotation.EsAnnotationQueryHandler; 6 | import com.elasticsearch.engine.base.common.queryhandler.ann.param.EsParamExecuteHandler; 7 | import com.elasticsearch.engine.base.common.utils.ThreadLocalUtil; 8 | import com.elasticsearch.engine.base.model.constant.CommonConstant; 9 | import com.elasticsearch.engine.base.model.domain.BaseEsRepository; 10 | import com.elasticsearch.engine.base.model.domain.BaseResp; 11 | import com.elasticsearch.engine.base.model.exception.EsEngineExecuteException; 12 | import org.springframework.stereotype.Component; 13 | 14 | import javax.annotation.Resource; 15 | import java.lang.reflect.Method; 16 | import java.util.List; 17 | import java.util.Objects; 18 | 19 | /** 20 | * @author wanghuan 21 | * @description: param 注解proxy查询handler 22 | * @date 2022-04-16 22:08 23 | */ 24 | @Component 25 | public class EsAnnotationParamQueryHandler implements EsAnnotationQueryHandler { 26 | 27 | @Resource 28 | private EsParamExecuteHandler esParamExecuteHandler; 29 | 30 | @Override 31 | public Boolean matching(EsAnnotationQueryEnum factory) { 32 | return EsAnnotationQueryEnum.ANNOTATION_PARAM_QUERY.equals(factory); 33 | } 34 | 35 | @Override 36 | public Object handle(Object proxy, Method method, Object[] args) { 37 | String prefix = ThreadLocalUtil.get(CommonConstant.INTERFACE_METHOD_NAME); 38 | //方法返回值 39 | Class returnType = method.getReturnType(); 40 | //方法返回值的泛型 41 | Class returnGenericType = AnnotationQueryCommon.getReturnGenericType(method); 42 | //获取到Repository泛型的Entity类 43 | Class retEntityClass = AnnotationQueryCommon.getClazzImplClassGeneric(method.getDeclaringClass(), BaseEsRepository.class); 44 | //Repository泛型 单个返回值 45 | if (Objects.isNull(retEntityClass)) { 46 | throw new EsEngineExecuteException(prefix + "泛型声明异常:Repository 缺少泛型声明"); 47 | } 48 | if (returnType.isAssignableFrom(retEntityClass)) { 49 | return esParamExecuteHandler.executeOne(method, args, returnType); 50 | } 51 | //Repository泛型 List返回值 52 | if (List.class.isAssignableFrom(returnType) 53 | && Objects.nonNull(returnGenericType) 54 | && returnGenericType.isAssignableFrom(retEntityClass)) { 55 | return esParamExecuteHandler.executeList(method, args, returnGenericType); 56 | } 57 | 58 | //Repository泛型 BaseResp返回值 59 | if (BaseResp.class.isAssignableFrom(returnType) 60 | && Objects.nonNull(returnGenericType) 61 | && returnGenericType.isAssignableFrom(retEntityClass)) { 62 | return esParamExecuteHandler.execute(method, args, returnGenericType); 63 | } 64 | throw new EsEngineExecuteException(prefix + "方法返回值泛型匹配异常: 返回值必须是 Repository 的泛型类型"); 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/common/proxy/handler/exsql/EsSqlQueryFactory.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.common.proxy.handler.exsql; 2 | 3 | import com.elasticsearch.engine.base.common.factory.FactoryList; 4 | import com.elasticsearch.engine.base.common.proxy.enums.EsSqlQueryEnum; 5 | import com.elasticsearch.engine.base.model.exception.EsEngineExecuteException; 6 | import org.springframework.stereotype.Component; 7 | 8 | import javax.annotation.Resource; 9 | import java.util.List; 10 | 11 | /** 12 | * @author wanghuan 13 | * @description: ROOD 14 | * @date 2022-04-15 19:03 15 | */ 16 | @Component 17 | public class EsSqlQueryFactory implements FactoryList { 18 | 19 | @Resource 20 | private List esSqlQueryHandlers; 21 | 22 | @Override 23 | public EsSqlQueryHandler getBean(EsSqlQueryEnum factory) { 24 | for (EsSqlQueryHandler esAnnotationQueryHandler : esSqlQueryHandlers) { 25 | if (esAnnotationQueryHandler.matching(factory)) { 26 | return esAnnotationQueryHandler; 27 | } 28 | } 29 | throw new EsEngineExecuteException("factory class not found"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/common/proxy/handler/exsql/EsSqlQueryHandler.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.common.proxy.handler.exsql; 2 | 3 | 4 | import com.elasticsearch.engine.base.common.factory.MatchingBean; 5 | import com.elasticsearch.engine.base.common.proxy.enums.EsSqlQueryEnum; 6 | 7 | import java.lang.reflect.Method; 8 | 9 | /** 10 | * @author wanghuan 11 | * @description: ROOD 12 | * @date 2022-04-15 18:15 13 | */ 14 | public interface EsSqlQueryHandler extends MatchingBean { 15 | 16 | Object handle(Object proxy, Method method, Object[] args); 17 | } 18 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/common/proxy/handler/exsql/impl/EsAnnotationSqlQueryHandler.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.common.proxy.handler.exsql.impl; 2 | 3 | import com.elasticsearch.engine.base.common.parse.sql.SqlParamParseHelper; 4 | import com.elasticsearch.engine.base.common.proxy.enums.EsSqlQueryEnum; 5 | import com.elasticsearch.engine.base.common.proxy.handler.exannotation.AnnotationQueryCommon; 6 | import com.elasticsearch.engine.base.common.proxy.handler.exsql.EsSqlQueryHandler; 7 | import com.elasticsearch.engine.base.common.queryhandler.sql.EsSqlExecuteHandler; 8 | import com.elasticsearch.engine.base.common.utils.ThreadLocalUtil; 9 | import com.elasticsearch.engine.base.model.annotion.EsQuery; 10 | import com.elasticsearch.engine.base.model.constant.CommonConstant; 11 | import com.elasticsearch.engine.base.model.emenu.SqlParamParse; 12 | import com.elasticsearch.engine.base.model.exception.EsEngineExecuteException; 13 | import lombok.extern.slf4j.Slf4j; 14 | import org.apache.commons.lang3.StringUtils; 15 | import org.springframework.stereotype.Component; 16 | 17 | import javax.annotation.Resource; 18 | import java.lang.reflect.Method; 19 | import java.util.List; 20 | import java.util.Objects; 21 | 22 | /** 23 | * @author wanghuan 24 | * @description: ROOD 25 | * @date 2022-04-26 23:13 26 | */ 27 | @Slf4j 28 | @Component 29 | public class EsAnnotationSqlQueryHandler implements EsSqlQueryHandler { 30 | 31 | @Resource 32 | private EsSqlExecuteHandler esSqlExecuteHandler; 33 | 34 | @Override 35 | public Boolean matching(EsSqlQueryEnum factory) { 36 | return EsSqlQueryEnum.ANNOTATION_QUERY.equals(factory); 37 | } 38 | 39 | @Override 40 | public Object handle(Object proxy, Method method, Object[] args) { 41 | String prefix = ThreadLocalUtil.get(CommonConstant.INTERFACE_METHOD_NAME); 42 | //方法返回值 43 | Class returnType = method.getReturnType(); 44 | //方法返回值的泛型 45 | Class returnGenericType = AnnotationQueryCommon.getReturnGenericType(method); 46 | EsQuery esQuery = method.getAnnotation(EsQuery.class); 47 | if (Objects.isNull(esQuery) || StringUtils.isEmpty(esQuery.value())) { 48 | throw new EsEngineExecuteException(prefix + "@EsQuery 注解不存在或参数为空"); 49 | } 50 | // 解析sql参数 51 | String sql = SqlParamParseHelper.getMethodArgsSqlAnn(esQuery.value(), method, args, SqlParamParse.ANN_SQL_PARAM); 52 | 53 | List list; 54 | if (List.class.isAssignableFrom(returnType) && Objects.nonNull(returnGenericType)) { 55 | list = esSqlExecuteHandler.queryBySql(sql, returnGenericType, Boolean.FALSE); 56 | } else { 57 | list = esSqlExecuteHandler.queryBySql(sql, returnType, Boolean.FALSE); 58 | } 59 | 60 | if (List.class.isAssignableFrom(returnType)) { 61 | return list; 62 | } else { 63 | if (list.size() > 0) { 64 | return list.get(0); 65 | } 66 | return null; 67 | } 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/common/proxy/handler/impl/EsAnnotationQuery.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.common.proxy.handler.impl; 2 | 3 | import com.elasticsearch.engine.base.common.proxy.enums.EsAnnotationQueryEnum; 4 | import com.elasticsearch.engine.base.common.proxy.enums.EsQueryType; 5 | import com.elasticsearch.engine.base.common.proxy.handler.EsQueryProxyExecuteHandler; 6 | import com.elasticsearch.engine.base.common.proxy.handler.exannotation.EsAnnotationQueryFactory; 7 | import com.elasticsearch.engine.base.common.utils.ReflectionUtils; 8 | import com.elasticsearch.engine.base.common.utils.ThreadLocalUtil; 9 | import com.elasticsearch.engine.base.model.constant.CommonConstant; 10 | import com.elasticsearch.engine.base.model.exception.EsEngineQueryException; 11 | import org.apache.commons.lang3.math.NumberUtils; 12 | import org.springframework.stereotype.Component; 13 | 14 | import javax.annotation.Resource; 15 | import java.lang.reflect.Method; 16 | import java.util.List; 17 | 18 | /** 19 | * @author wanghuan 20 | * @description: es注解查询代理实现逻辑 21 | * @date 2022-04-15 18:01 22 | */ 23 | @Component 24 | public class EsAnnotationQuery implements EsQueryProxyExecuteHandler { 25 | 26 | @Resource 27 | private EsAnnotationQueryFactory esAnnotationQueryFactory; 28 | 29 | @Override 30 | public Boolean matching(EsQueryType factory) { 31 | return EsQueryType.ANNOTATION.equals(factory); 32 | } 33 | 34 | /** 35 | * 代理类的泛型, 或者自定义泛型获取的公共方法 36 | * @param proxy 37 | * @param method 38 | * @param args 39 | * @return 40 | */ 41 | @Override 42 | public Object handle(Object proxy, Method method, Object[] args) { 43 | String prefix = ThreadLocalUtil.get(CommonConstant.INTERFACE_METHOD_NAME); 44 | if (args == null || args.length == 0) { 45 | throw new EsEngineQueryException(prefix + "missing parameters"); 46 | } 47 | EsAnnotationQueryEnum queryEnum; 48 | Class clazz = args[0].getClass(); 49 | //只有一个参数 && 并且参数不是基础类型 && 并且参数不是List 50 | if (args.length == NumberUtils.INTEGER_ONE && !ReflectionUtils.isBaseTypeAndExtend(clazz) && (!List.class.isAssignableFrom(clazz))) { 51 | queryEnum = EsAnnotationQueryEnum.ANNOTATION_MODEL_QUERY; 52 | } else if (args.length > NumberUtils.INTEGER_ZERO && ReflectionUtils.allParamIsBaseType(args)) { 53 | //有一个或多个参数 && 都是基础类型(包括List,LocalDateTime,LocalDate,BigDecimal) 54 | queryEnum = EsAnnotationQueryEnum.ANNOTATION_PARAM_QUERY; 55 | } else { 56 | throw new EsEngineQueryException(prefix + "方法参数异常: 查询参数不被支持,仅支持单个引用类型的参数 or 一个或多个基本类型参数(额外包括 List,LocalDateTime,LocalDate,BigDecimal)"); 57 | } 58 | return esAnnotationQueryFactory.getBean(queryEnum).handle(proxy, method, args); 59 | } 60 | 61 | 62 | } 63 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/common/proxy/handler/impl/EsNativeQuery.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.common.proxy.handler.impl; 2 | 3 | import com.elasticsearch.engine.base.common.proxy.enums.EsQueryType; 4 | import com.elasticsearch.engine.base.common.proxy.handler.EsQueryProxyExecuteHandler; 5 | import org.springframework.stereotype.Component; 6 | 7 | import java.lang.reflect.Method; 8 | 9 | /** 10 | * @author wanghuan 11 | * @description: es原生语句查询代理实现逻辑 12 | * @date 2022-04-15 18:11 13 | */ 14 | @Component 15 | public class EsNativeQuery implements EsQueryProxyExecuteHandler { 16 | @Override 17 | public Boolean matching(EsQueryType factory) { 18 | return EsQueryType.ES_NATIVE.equals(factory); 19 | } 20 | 21 | @Override 22 | public Object handle(Object proxy, Method method, Object[] args) { 23 | return null; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/common/proxy/handler/impl/EsSqlQuery.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.common.proxy.handler.impl; 2 | 3 | import com.elasticsearch.engine.base.common.proxy.enums.EsQueryType; 4 | import com.elasticsearch.engine.base.common.proxy.enums.EsSqlQueryEnum; 5 | import com.elasticsearch.engine.base.common.proxy.handler.EsQueryProxyExecuteHandler; 6 | import com.elasticsearch.engine.base.common.proxy.handler.exsql.EsSqlQueryFactory; 7 | import lombok.extern.slf4j.Slf4j; 8 | import org.springframework.stereotype.Component; 9 | 10 | import javax.annotation.Resource; 11 | import java.lang.reflect.Method; 12 | 13 | /** 14 | * @author wanghuan 15 | * @description: es sql查询代理实现逻辑 16 | * @date 2022-04-15 18:10 17 | */ 18 | @Slf4j 19 | @Component 20 | public class EsSqlQuery implements EsQueryProxyExecuteHandler { 21 | 22 | @Resource 23 | private EsSqlQueryFactory esSqlQueryFactory; 24 | 25 | @Override 26 | public Boolean matching(EsQueryType factory) { 27 | return EsQueryType.SQL.equals(factory); 28 | } 29 | 30 | @Override 31 | public Object handle(Object proxy, Method method, Object[] args) { 32 | // String prefix = ThreadLocalUtil.get(CommonConstant.INTERFACE_METHOD_NAME); 33 | // if (args != null && args.length > 0) { 34 | // //参数类型校验 35 | // if (!ReflectionUtils.allParamIsBaseType(args)) { 36 | // throw new EsEngineQueryException(prefix + "方法参数异常: 查询参数不被支持,仅支持多个基本类型参数 或 者单个引用类型的参数并标记@EsQueryIndex注解"); 37 | // } 38 | // } 39 | 40 | return esSqlQueryFactory.getBean(EsSqlQueryEnum.ANNOTATION_QUERY).handle(proxy, method, args); 41 | 42 | } 43 | 44 | 45 | } 46 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/common/queryhandler/ann/model/AbstractEsBaseExecuteHandle.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.common.queryhandler.ann.model; 2 | 3 | import com.elasticsearch.engine.base.common.utils.ReflectionUtils; 4 | import com.elasticsearch.engine.base.holder.AbstractEsRequestHolder; 5 | import com.elasticsearch.engine.base.hook.RequestHook; 6 | import com.elasticsearch.engine.base.hook.ResponseHook; 7 | import com.elasticsearch.engine.base.model.domain.BaseResp; 8 | import com.elasticsearch.engine.base.model.exception.EsEngineConfigException; 9 | import org.apache.commons.lang3.StringUtils; 10 | import org.apache.commons.lang3.math.NumberUtils; 11 | import org.elasticsearch.action.search.SearchResponse; 12 | import org.springframework.core.env.Environment; 13 | 14 | import javax.annotation.Resource; 15 | import java.util.ArrayList; 16 | import java.util.List; 17 | import java.util.Objects; 18 | 19 | /** 20 | * @author wanghuan 21 | * @description: ROOD 22 | * @date 2022-05-06 18:30 23 | */ 24 | @Resource 25 | public abstract class AbstractEsBaseExecuteHandle { 26 | 27 | @Resource 28 | private Environment environment; 29 | 30 | /** 31 | * 前置处理扩展 32 | * 33 | * @param param 34 | * @param esHolder 35 | */ 36 | public abstract void executePostProcessorBefore(Object param, AbstractEsRequestHolder esHolder); 37 | 38 | /** 39 | * 后置处理扩展 嵌套扩展处理 40 | * @param param 41 | * @param resp 42 | * @param result 43 | * @param 44 | */ 45 | public abstract void executePostProcessorAfter(Object param, SearchResponse resp, BaseResp result); 46 | 47 | /** 48 | * 索引名动态配置解析 49 | * 50 | * @param esHolder 51 | */ 52 | protected void resetIndexName(AbstractEsRequestHolder esHolder) { 53 | String[] indices = esHolder.getRequest().indices(); 54 | if (Objects.isNull(indices) || indices.length != NumberUtils.INTEGER_ONE) { 55 | 56 | } 57 | String indexName = indices[0]; 58 | if (StringUtils.contains(indexName, "${") && StringUtils.contains(indexName, "}")) { 59 | String parseIndexName = indexName.replace("${", "").replace("}", ""); 60 | String envProperty = parseIndexName; 61 | //包含默认值 62 | if (StringUtils.contains(parseIndexName, ":")) { 63 | String[] index = StringUtils.split(parseIndexName, ":"); 64 | envProperty = index[0]; 65 | indexName = index[1]; 66 | } 67 | //读取配置的索引名 68 | String configIndex = environment.getProperty(envProperty); 69 | //配置的是读取配置中心的参数, 没有读到,并且没有设置默认值, 则抛出异常 70 | if (StringUtils.isEmpty(configIndex) && !parseIndexName.contains(":")) { 71 | throw new EsEngineConfigException("index name is empty"); 72 | } 73 | //优先使用配置中心配置的索引名 74 | if (StringUtils.isNotEmpty(configIndex)) { 75 | indexName = configIndex; 76 | } 77 | } 78 | esHolder.getRequest().indices(indexName); 79 | } 80 | 81 | /** 82 | * 自定义扩展查询处理 83 | * 84 | * @param param 85 | * @return 86 | */ 87 | protected List checkRequestHook(Object param) { 88 | List requestHooks = new ArrayList<>(); 89 | List> superClass = ReflectionUtils.getSuperClass(param.getClass()); 90 | superClass.add(param.getClass()); 91 | for (Class clazz : superClass) { 92 | if (RequestHook.class.isAssignableFrom(clazz)) { 93 | try { 94 | requestHooks.add((RequestHook) clazz.newInstance()); 95 | } catch (Exception e) { 96 | e.printStackTrace(); 97 | } 98 | } 99 | } 100 | return requestHooks; 101 | } 102 | 103 | /** 104 | * 自定义结果解析扩展处理 105 | * 106 | * @param param 107 | * @return 108 | */ 109 | protected ResponseHook checkResponseHook(Object param) { 110 | if (ResponseHook.class.isAssignableFrom(param.getClass())) { 111 | return (ResponseHook) param; 112 | } 113 | return null; 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/common/utils/AnnotationUtils.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.common.utils; 2 | 3 | import com.google.common.collect.Maps; 4 | import com.google.common.collect.Sets; 5 | 6 | import java.lang.annotation.Annotation; 7 | import java.lang.reflect.Method; 8 | import java.util.Arrays; 9 | import java.util.HashSet; 10 | import java.util.List; 11 | import java.util.Map; 12 | import java.util.stream.Collectors; 13 | 14 | /** 15 | * @author wanghuan 16 | * @description AnnotationUtils 17 | * @mail 958721894@qq.com 18 | * @date 2022/6/9 14:11 19 | */ 20 | public class AnnotationUtils { 21 | 22 | private static final HashSet OBJECT_METHOD_FILTER = Sets.newHashSet( 23 | Arrays.stream(Annotation.class.getMethods()).map(Method::getName).collect(Collectors.toSet()) 24 | ); 25 | 26 | public static Map toMap(Annotation ann) { 27 | List annMethods = Arrays.stream(ann.getClass().getDeclaredMethods()) 28 | .filter(m -> !OBJECT_METHOD_FILTER.contains(m.getName())) 29 | .collect(Collectors.toList()); 30 | Map res = Maps.newHashMap(); 31 | for (Method m : annMethods) { 32 | String key = m.getName(); 33 | Object val = ReflectionUtils.methodInvoke(ann, m); 34 | res.put(key, val); 35 | } 36 | return res; 37 | } 38 | 39 | 40 | } 41 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/common/utils/CaseFormatUtils.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.common.utils; 2 | 3 | import com.google.common.base.CaseFormat; 4 | import org.apache.commons.lang3.StringUtils; 5 | 6 | /** 7 | * @author wanghuan 8 | * @description CaseFormatUtils 9 | * @mail 958721894@qq.com 10 | * @date 2022-06-03 22:12 11 | */ 12 | public class CaseFormatUtils { 13 | 14 | /** 15 | * 下划线转驼峰 16 | * 17 | * @param columnName 18 | * @return 19 | */ 20 | public static String underscoreToCamel(String columnName) { 21 | if (StringUtils.isNotEmpty(columnName) && columnName.contains("_")) { 22 | return CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, columnName); 23 | } 24 | return columnName; 25 | } 26 | 27 | /** 28 | * 驼峰转下划线 29 | * 30 | * @param columnName 31 | * @return 32 | */ 33 | public static String camelToUnderscore(String columnName) { 34 | if (StringUtils.isNotEmpty(columnName) && isContainUpperCase(columnName)) { 35 | return CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, columnName); 36 | } 37 | return columnName; 38 | } 39 | 40 | /** 41 | * 判断string中是否包含大写字母 42 | * 43 | * @param str 44 | * @return 45 | */ 46 | public static boolean isContainUpperCase(String str) { 47 | StringBuffer buf = new StringBuffer(str); 48 | for (int i = 0; i < buf.length(); i++) { 49 | if (Character.isUpperCase(buf.charAt(i))) { 50 | return true; 51 | } 52 | } 53 | return false; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/common/utils/ClassPathResourceReaderUtils.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.common.utils; 2 | 3 | import org.springframework.core.io.ClassPathResource; 4 | 5 | import java.io.BufferedReader; 6 | import java.io.IOException; 7 | import java.io.InputStreamReader; 8 | import java.util.stream.Collectors; 9 | 10 | /** 11 | * @author wanghuan 12 | * @description: 读取classpath下的文件支持jar 13 | * @date 2022-05-30 18:41 14 | */ 15 | public class ClassPathResourceReaderUtils { 16 | 17 | public static String getContent(String path) { 18 | String content; 19 | try { 20 | ClassPathResource resource = new ClassPathResource(path); 21 | BufferedReader reader = new BufferedReader(new InputStreamReader(resource.getInputStream())); 22 | content = reader.lines().collect(Collectors.joining("\n")); 23 | reader.close(); 24 | } catch (IOException ex) { 25 | 26 | throw new RuntimeException(ex); 27 | } 28 | return content; 29 | 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/common/utils/ExtAnnBeanMapUtils.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.common.utils; 2 | 3 | import java.lang.annotation.Annotation; 4 | import java.lang.reflect.Field; 5 | import java.util.Map; 6 | 7 | /** 8 | * @author wanghuan 9 | * @description ExtAnnBeanMapUtils 10 | * @mail 958721894@qq.com 11 | * @date 2022/6/9 14:11 12 | */ 13 | public class ExtAnnBeanMapUtils { 14 | 15 | 16 | /** 17 | * phrase annotation to JavaBean 18 | * 19 | * @param annotation target Annotation 20 | * @param clazz mapping class 21 | * return target JavaBean(T) 22 | */ 23 | public static Object mapping(Annotation annotation, Class clazz) { 24 | Field[] extBeanFields = clazz.getDeclaredFields(); 25 | Object extBean = ReflectionUtils.newInstance(clazz); 26 | Map annMapping = AnnotationUtils.toMap(annotation); 27 | for (Field field : extBeanFields) { 28 | field.setAccessible(true); 29 | String key = field.getName(); 30 | Object val = annMapping.get(key); 31 | ReflectionUtils.setFieldValue(extBean, field, val, false); 32 | } 33 | return extBean; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/common/utils/LocalStringUtils.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.common.utils; 2 | 3 | /** 4 | * @author wanghuan 5 | * @description StringUtils 6 | * @mail 958721894@qq.com 7 | * @date 2022-07-15 22:24 8 | */ 9 | public class LocalStringUtils { 10 | 11 | /** 12 | * 替换string中的'`' 13 | * 14 | * @param str 15 | * @return 16 | */ 17 | public static String replaceSlightPauseMark(String str) { 18 | return str.replaceAll("`", ""); 19 | } 20 | 21 | /** 22 | * 替换string中的'.' 23 | * 24 | * @param str 25 | * @return 26 | */ 27 | public static String replaceSpot(String str) { 28 | return str.replaceAll("\\.", ""); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/common/utils/ThreadLocalUtil.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.common.utils; 2 | 3 | import org.apache.commons.lang3.StringUtils; 4 | 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | /** 9 | * @author wanghuan 10 | * @description ThreadLocalUtil 11 | * @mail 958721894@qq.com 12 | * @date 2022/6/17 15:30 13 | */ 14 | public class ThreadLocalUtil { 15 | 16 | private static final ThreadLocal> THREAD_LOCAL = ThreadLocal.withInitial(() -> new HashMap(4)); 17 | 18 | public static Map getThreadLocal() { 19 | return THREAD_LOCAL.get(); 20 | } 21 | 22 | public static T get(String key) { 23 | Map map = (Map) THREAD_LOCAL.get(); 24 | return (T) map.get(key); 25 | } 26 | 27 | public static T get(String key, T defaultValue) { 28 | Map map = (Map) THREAD_LOCAL.get(); 29 | return (T) map.get(key) == null ? defaultValue : (T) map.get(key); 30 | } 31 | 32 | public static void set(String key, Object value) { 33 | Map map = (Map) THREAD_LOCAL.get(); 34 | map.put(key, value); 35 | } 36 | 37 | public static void set(Map keyValueMap) { 38 | Map map = (Map) THREAD_LOCAL.get(); 39 | map.putAll(keyValueMap); 40 | } 41 | 42 | public static void remove() { 43 | THREAD_LOCAL.remove(); 44 | } 45 | 46 | public static T remove(String key) { 47 | if (StringUtils.isNotEmpty(key)) { 48 | Map map = (Map) THREAD_LOCAL.get(); 49 | return (T) map.remove(key); 50 | 51 | } 52 | return null; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/common/utils/serializer/LocalDateDeserializer.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.common.utils.serializer; 2 | 3 | import com.fasterxml.jackson.databind.DeserializationContext; 4 | import com.fasterxml.jackson.databind.JsonDeserializer; 5 | 6 | import java.io.IOException; 7 | import java.time.LocalDate; 8 | import java.time.format.DateTimeFormatter; 9 | 10 | /** 11 | * @author Tong Li 12 | * @since JDK1.8 13 | * Created on 2021/6/30. 14 | */ 15 | public class LocalDateDeserializer extends JsonDeserializer { 16 | private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd"); 17 | 18 | @Override 19 | public LocalDate deserialize(com.fasterxml.jackson.core.JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException { 20 | String value = jsonParser.getValueAsString(); 21 | return LocalDate.parse(value, FORMATTER); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/common/utils/serializer/LocalDateSerializer.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.common.utils.serializer; 2 | 3 | import com.fasterxml.jackson.core.JsonGenerator; 4 | import com.fasterxml.jackson.databind.JsonSerializer; 5 | import com.fasterxml.jackson.databind.SerializerProvider; 6 | 7 | import java.io.IOException; 8 | import java.time.LocalDate; 9 | import java.time.format.DateTimeFormatter; 10 | 11 | /** 12 | * @author Tong Li 13 | * @since JDK1.8 14 | * Created on 2021/6/30. 15 | */ 16 | public class LocalDateSerializer extends JsonSerializer { 17 | private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd"); 18 | 19 | @Override 20 | public void serialize(LocalDate localDate, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { 21 | jsonGenerator.writeString(localDate.format(DATE_FORMATTER)); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/common/utils/serializer/LocalDateTimeDeserializer.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.common.utils.serializer; 2 | 3 | import com.elasticsearch.engine.base.common.utils.DateUtils; 4 | import com.fasterxml.jackson.core.JsonParser; 5 | import com.fasterxml.jackson.databind.DeserializationContext; 6 | import com.fasterxml.jackson.databind.JsonDeserializer; 7 | 8 | import java.io.IOException; 9 | import java.time.LocalDateTime; 10 | import java.time.format.DateTimeFormatter; 11 | import java.util.regex.Matcher; 12 | import java.util.regex.Pattern; 13 | 14 | /** 15 | * @author wanghuan 16 | * @description LocalDateTimeDeserializer 17 | * @mail 958721894@qq.com 18 | * @date 2022/6/18 09:54 19 | */ 20 | public class LocalDateTimeDeserializer extends JsonDeserializer { 21 | private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); 22 | private static final Pattern NUMERIC_PATTERN = Pattern.compile("[0-9]*"); 23 | private static final Pattern TIME_LEGAL_PATTERN = Pattern.compile("^((\\d{2}(([02468][048])|([13579][26]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])))))|(\\d{2}(([02468][1235679])|([13579][01345789]))[\\-\\/\\s]?((((0?[13578])|(1[02]))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(3[01])))|(((0?[469])|(11))[\\-\\/\\s]?((0?[1-9])|([1-2][0-9])|(30)))|(0?2[\\-\\/\\s]?((0?[1-9])|(1[0-9])|(2[0-8]))))))(\\s((([0-1][0-9])|(2?[0-3]))\\:([0-5]?[0-9])((\\s)|(\\:([0-5]?[0-9])))))?$"); 24 | 25 | 26 | @Override 27 | public LocalDateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException { 28 | String value = jsonParser.getValueAsString(); 29 | if (isTimeLegal(value)) { 30 | return LocalDateTime.parse(value, DATE_TIME_FORMATTER); 31 | } else if (isNumeric(value)) { 32 | return DateUtils.dateTimeToLong(Long.parseLong(value)); 33 | } else { 34 | throw new RuntimeException("LocalDateTime Format error"); 35 | } 36 | } 37 | 38 | /** 39 | * 利用正则表达式判断字符串是否是数字 40 | * 41 | * @param str 42 | * @return 43 | */ 44 | private boolean isNumeric(String str) { 45 | Matcher isNum = NUMERIC_PATTERN.matcher(str); 46 | return isNum.matches(); 47 | } 48 | 49 | /** 50 | * 判断输入的字符串是否满足时间格式 : yyyy-MM-dd HH:mm:ss 51 | * 52 | * @param patternString 需要验证的字符串 53 | * @return 合法返回 true ; 不合法返回false 54 | */ 55 | private boolean isTimeLegal(String patternString) { 56 | Matcher b = TIME_LEGAL_PATTERN.matcher(patternString); 57 | return b.matches(); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/common/utils/serializer/LocalDateTimeSerializer.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.common.utils.serializer; 2 | 3 | import com.fasterxml.jackson.core.JsonGenerator; 4 | import com.fasterxml.jackson.databind.JsonSerializer; 5 | import com.fasterxml.jackson.databind.SerializerProvider; 6 | 7 | import java.io.IOException; 8 | import java.time.LocalDateTime; 9 | import java.time.format.DateTimeFormatter; 10 | 11 | /** 12 | * @author wanghuan 13 | * @description LocalDateTimeSerializer 14 | * @mail 958721894@qq.com 15 | * @date 2022/6/18 09:54 16 | */ 17 | public class LocalDateTimeSerializer extends JsonSerializer { 18 | private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); 19 | 20 | @Override 21 | public void serialize(LocalDateTime localDateTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { 22 | jsonGenerator.writeString(localDateTime.format(DATE_TIME_FORMATTER)); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/common/utils/serializer/LocalDateTimeUtils.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.common.utils.serializer; 2 | 3 | import java.time.Instant; 4 | import java.time.LocalDateTime; 5 | import java.time.ZoneId; 6 | import java.time.ZonedDateTime; 7 | import java.util.Date; 8 | 9 | /** 10 | * @author wanghuan 11 | * @description LocalDateTimeUtils 12 | * @mail 958721894@qq.com 13 | * @date 2022/6/18 09:54 14 | */ 15 | public class LocalDateTimeUtils { 16 | public static LocalDateTime fromDate(Date date) { 17 | if (date == null) { 18 | return null; 19 | } 20 | 21 | Instant instant = date.toInstant(); 22 | ZoneId zoneId = ZoneId.systemDefault(); 23 | return instant.atZone(zoneId).toLocalDateTime(); 24 | } 25 | 26 | public static LocalDateTime fromTimeStamp(Long timestamp) { 27 | if (timestamp == null) { 28 | return null; 29 | } 30 | 31 | Instant instant = Instant.ofEpochMilli(timestamp); 32 | ZoneId zone = ZoneId.systemDefault(); 33 | return LocalDateTime.ofInstant(instant, zone); 34 | } 35 | 36 | public static Long toTimeStamp(LocalDateTime localDateTime) { 37 | if (localDateTime == null) { 38 | return null; 39 | } 40 | 41 | 42 | return toDate(localDateTime).getTime(); 43 | } 44 | 45 | 46 | public static Date toDate(LocalDateTime localDateTime) { 47 | if (localDateTime == null) { 48 | return null; 49 | } 50 | 51 | ZoneId zoneId = ZoneId.systemDefault(); 52 | ZonedDateTime zdt = localDateTime.atZone(zoneId); 53 | return Date.from(zdt.toInstant()); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/common/utils/serializer/LocalTimeDeserializer.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.common.utils.serializer; 2 | 3 | import com.fasterxml.jackson.databind.DeserializationContext; 4 | import com.fasterxml.jackson.databind.JsonDeserializer; 5 | 6 | import java.io.IOException; 7 | import java.time.LocalTime; 8 | import java.time.format.DateTimeFormatter; 9 | 10 | /** 11 | * @author Tong Li 12 | * @since JDK1.8 13 | * Created on 2021/6/30. 14 | */ 15 | public class LocalTimeDeserializer extends JsonDeserializer { 16 | private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm:ss"); 17 | 18 | @Override 19 | public LocalTime deserialize(com.fasterxml.jackson.core.JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException { 20 | String value = jsonParser.getValueAsString(); 21 | return LocalTime.parse(value, TIME_FORMATTER); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/common/utils/serializer/LocalTimeSerializer.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.common.utils.serializer; 2 | 3 | import com.fasterxml.jackson.core.JsonGenerator; 4 | import com.fasterxml.jackson.databind.JsonSerializer; 5 | import com.fasterxml.jackson.databind.SerializerProvider; 6 | 7 | import java.io.IOException; 8 | import java.time.LocalTime; 9 | import java.time.format.DateTimeFormatter; 10 | 11 | /** 12 | * @author Tong Li 13 | * @since JDK1.8 14 | * Created on 2021/6/30. 15 | */ 16 | public class LocalTimeSerializer extends JsonSerializer { 17 | private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm:ss"); 18 | 19 | @Override 20 | public void serialize(LocalTime localTime, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException { 21 | jsonGenerator.writeString(localTime.format(TIME_FORMATTER)); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/config/ElasticSearchProperties.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.config; 2 | 3 | import com.elasticsearch.engine.base.model.constant.CommonConstant; 4 | import joptsimple.internal.Strings; 5 | import lombok.Data; 6 | import org.springframework.boot.context.properties.ConfigurationProperties; 7 | 8 | /** 9 | * @author wanghuan 10 | * @description: ElasticsearchConfig 11 | * @date 2022-01-26 11:28 12 | */ 13 | @ConfigurationProperties(prefix = "elasticsearch") 14 | @Data 15 | public class ElasticSearchProperties { 16 | 17 | /** 18 | * elasticsearch hots配置,多台机器配置格式如下: 19 | * es-c1.enmonster.org:9200,es-c2.enmonster.org:9200 20 | */ 21 | private String hosts = CommonConstant.DEFAULT_ES_HOST; 22 | 23 | /** 24 | * elasticsearch 认证用户名 25 | */ 26 | private String username = Strings.EMPTY; 27 | 28 | /** 29 | * elasticsearch 认证密码 30 | */ 31 | private String password = Strings.EMPTY; 32 | 33 | } 34 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/config/ElasticsearchConfig.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.config; 2 | 3 | import com.elasticsearch.engine.base.model.exception.EsEngineConfigException; 4 | import org.apache.commons.lang3.ArrayUtils; 5 | import org.apache.commons.lang3.StringUtils; 6 | import org.apache.http.HttpHost; 7 | import org.apache.http.auth.AuthScope; 8 | import org.apache.http.auth.UsernamePasswordCredentials; 9 | import org.apache.http.client.CredentialsProvider; 10 | import org.apache.http.impl.client.BasicCredentialsProvider; 11 | import org.elasticsearch.client.RestClient; 12 | import org.elasticsearch.client.RestClientBuilder; 13 | import org.elasticsearch.client.RestHighLevelClient; 14 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 15 | import org.springframework.context.annotation.Bean; 16 | import org.springframework.context.annotation.Configuration; 17 | 18 | import javax.annotation.Resource; 19 | import java.util.Arrays; 20 | import java.util.Objects; 21 | 22 | /** 23 | * @author wanghuan 24 | * @description: ElasticsearchConfig 25 | * @date 2022-01-26 11:28 26 | */ 27 | @EnableConfigurationProperties(ElasticSearchProperties.class) 28 | @Configuration 29 | public class ElasticsearchConfig { 30 | 31 | @Resource 32 | private ElasticSearchProperties elasticSearchProperties; 33 | 34 | 35 | public static HttpHost[] hostGen(String[] elasticsearchHost) { 36 | if (ArrayUtils.isEmpty(elasticsearchHost)) { 37 | throw new IllegalArgumentException("elasticsearch host must not empty"); 38 | } 39 | return Arrays.stream(elasticsearchHost).map( 40 | HttpHost::create 41 | ).toArray(HttpHost[]::new); 42 | } 43 | 44 | @Bean(destroyMethod = "close") 45 | public RestHighLevelClient restHighLevelClient() { 46 | String hosts = elasticSearchProperties.getHosts(); 47 | RestClientBuilder builder; 48 | configCheck(); 49 | if (StringUtils.isAnyEmpty(elasticSearchProperties.getUsername(), elasticSearchProperties.getPassword())) { 50 | /** ps: 创建非认证客户端*/ 51 | builder = RestClient.builder(hostGen(hosts.split(","))); 52 | } else { 53 | /** ps: 创建认证客户端*/ 54 | CredentialsProvider credentials = credentials(); 55 | builder = RestClient.builder(hostGen(hosts.split(","))).setHttpClientConfigCallback(httpAsyncClientBuilder -> httpAsyncClientBuilder.setDefaultCredentialsProvider(credentials)); 56 | } 57 | return new RestHighLevelClient(builder); 58 | } 59 | 60 | @Bean(destroyMethod = "close") 61 | public RestClient getRestClient() { 62 | String hosts = elasticSearchProperties.getHosts(); 63 | configCheck(); 64 | if (StringUtils.isAnyEmpty(elasticSearchProperties.getUsername(), elasticSearchProperties.getPassword())) { 65 | /** ps: 创建非认证客户端*/ 66 | return RestClient.builder(hostGen(hosts.split(","))).build(); 67 | } else { 68 | /** ps: 创建认证客户端*/ 69 | CredentialsProvider credentials = credentials(); 70 | return RestClient.builder(hostGen(hosts.split(","))).setHttpClientConfigCallback(httpAsyncClientBuilder -> httpAsyncClientBuilder.setDefaultCredentialsProvider(credentials)).build(); 71 | } 72 | } 73 | 74 | /** 75 | * 构建客户端认证信息 76 | * 77 | * @return 78 | */ 79 | private CredentialsProvider credentials() { 80 | // 阿里云ES集群需要basic auth验证。 81 | CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); 82 | //访问用户名和密码为您创建阿里云Elasticsearch实例时设置的用户名和密码,也是Kibana控制台的登录用户名和密码。 83 | credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(elasticSearchProperties.getUsername(), elasticSearchProperties.getPassword())); 84 | return credentialsProvider; 85 | } 86 | 87 | /** 88 | * 检查配置项 89 | */ 90 | private void configCheck() { 91 | if (Objects.isNull(elasticSearchProperties)) { 92 | throw new EsEngineConfigException("elasticSearch config hosts is null"); 93 | } 94 | 95 | if (StringUtils.isEmpty(elasticSearchProperties.getHosts())) { 96 | throw new EsEngineConfigException("elasticSearch config hosts is empty"); 97 | } 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/config/EsEngineConfigProperties.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.config; 2 | 3 | import lombok.Data; 4 | import org.springframework.boot.context.properties.ConfigurationProperties; 5 | 6 | import java.util.HashSet; 7 | import java.util.Set; 8 | 9 | /** 10 | * @author wanghuan 11 | * @description EsEngineConfigProperties 12 | * @mail 958721894@qq.com 13 | * @date 2022-06-11 21:45 14 | */ 15 | @ConfigurationProperties(prefix = "es.engine.config") 16 | @Data 17 | public class EsEngineConfigProperties { 18 | /** 19 | * elasticSearch version 20 | */ 21 | private Integer elasticVersion = 6; 22 | 23 | /** 24 | * 对没有添加注解的字段 默然按照trem/trems查询 25 | */ 26 | private boolean isBuildDefault = Boolean.TRUE; 27 | 28 | /** 29 | * 查询参及响应参数数解析是否是下划线 true解析成下划线 false按照参数名驼峰 默认值false 30 | */ 31 | private boolean namingStrategy = Boolean.FALSE; 32 | 33 | /** 34 | * 是否解析param 继承的类中的属性 35 | */ 36 | private boolean visitQueryBeanParent = Boolean.TRUE; 37 | 38 | /** 39 | * es查询超时时间 单位:TimeUnit.SECONDS 40 | */ 41 | private Integer queryTimeOut = 10; 42 | 43 | /** 44 | * 默认查询size,查询没有设置size时默认的size 45 | */ 46 | private Integer defaultQuerySize = 1000; 47 | 48 | /** 49 | * es extend(mybatis,jpa,jooq)查询 全局开关, true表示查询es, false表示查询mysql 50 | */ 51 | private boolean esQuery = Boolean.TRUE; 52 | 53 | /** 54 | * es extend(mybatis,jpa,jooq) sql转换日志开关 55 | */ 56 | private boolean sqlTraceLog = Boolean.FALSE; 57 | 58 | /** 59 | * es query json log 日志开关 60 | */ 61 | private boolean queryJsonLog = Boolean.FALSE; 62 | 63 | /** 64 | * es extend(mybatis,jpa,jooq)查询降级 包含的接口,仅再esQuery=false时才生效 65 | * item 为接口名 66 | */ 67 | private Set esQueryInclude = new HashSet<>(); 68 | 69 | /** 70 | * es extend(mybatis,jpa,jooq)查询降级 排除的接口,仅再esQuery=true时才生效 71 | * item 为接口名 72 | */ 73 | private Set esQueryExclude = new HashSet<>(); 74 | 75 | /** 76 | * 查询字段前缀列表 解析字段名时会使用去除后缀后的值解析 77 | */ 78 | private Set queryParamPrefix = new HashSet() { 79 | private static final long serialVersionUID = -7716606177924143554L; 80 | 81 | { 82 | add("list"); 83 | add("start"); 84 | add("end"); 85 | add("begin"); 86 | } 87 | }; 88 | 89 | /** 90 | * 查询字段后缀列表, 解析字段名时会使用去除后缀后的值解析 91 | */ 92 | private Set queryParamSuffix = new HashSet() { 93 | private static final long serialVersionUID = 6255704971422131027L; 94 | 95 | { 96 | add("List"); 97 | add("Start"); 98 | add("End"); 99 | add("Begin"); 100 | } 101 | }; 102 | 103 | /** 104 | * 默认查询需要忽略的字段(注意 轻易不要修改该参数) 105 | */ 106 | private Set queryIgnoreParam = new HashSet() { 107 | private static final long serialVersionUID = -5794700187017984887L; 108 | 109 | { 110 | add("log"); 111 | add("page"); 112 | add("pageSize"); 113 | add("size"); 114 | add("sort"); 115 | } 116 | }; 117 | } 118 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/config/LoadFactory.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.config; 2 | 3 | import com.elasticsearch.engine.base.common.utils.ClassPathResourceReaderUtils; 4 | import com.elasticsearch.engine.base.model.constant.CommonConstant; 5 | /** 6 | * @author wanghuan 7 | * @description: LoadFactory 8 | * 加载一些初始化的配置 9 | * @date 2022-04-09 16:15 10 | */ 11 | public class LoadFactory { 12 | 13 | public static String readBanner() { 14 | try { 15 | //获取文件的URL 16 | String banner = ClassPathResourceReaderUtils.getContent(CommonConstant.BANNER_PATH); 17 | String version = ClassPathResourceReaderUtils.getContent(CommonConstant.VERSION_PATH); 18 | banner = String.format(banner, version); 19 | return banner; 20 | } catch (Exception e) { 21 | return ""; 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/holder/BoolEsRequestHolder.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.holder; 2 | 3 | import com.elasticsearch.engine.base.model.emenu.EsConnector; 4 | import org.elasticsearch.index.query.BoolQueryBuilder; 5 | import org.elasticsearch.index.query.QueryBuilders; 6 | 7 | /** 8 | * @author wanghuan 9 | * @description: bool query builder holder 10 | * @date 2022-01-26 11:28 11 | */ 12 | public class BoolEsRequestHolder extends AbstractEsRequestHolder { 13 | 14 | /** 15 | * 默认使用must连接 16 | */ 17 | @Override 18 | protected void defineDefaultLogicConnector() { 19 | super.setCurrentQueryBuilderList(super.getQueryBuilder().must()); 20 | } 21 | 22 | @Override 23 | protected void defineQueryBuilder() { 24 | super.setQueryBuilder(QueryBuilders.boolQuery()); 25 | } 26 | 27 | @Override 28 | public AbstractEsRequestHolder changeLogicConnector(EsConnector logicKey) { 29 | if (logicKey == null) { 30 | return this; 31 | } 32 | if (EsConnector.MUST.equals(logicKey)) { 33 | super.setCurrentQueryBuilderList(super.getQueryBuilder().must()); 34 | } 35 | if (EsConnector.FILTER.equals(logicKey)) { 36 | super.setCurrentQueryBuilderList(super.getQueryBuilder().filter()); 37 | } 38 | if (EsConnector.MUST_NOT.equals(logicKey)) { 39 | super.setCurrentQueryBuilderList(super.getQueryBuilder().mustNot()); 40 | } 41 | if (EsConnector.SHOULD.equals(logicKey)) { 42 | super.setCurrentQueryBuilderList(super.getQueryBuilder().should()); 43 | } 44 | return this; 45 | } 46 | 47 | 48 | } 49 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/holder/DisMaxEsRequestHolder.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.holder; 2 | 3 | import com.elasticsearch.engine.base.model.emenu.EsConnector; 4 | import org.elasticsearch.index.query.DisMaxQueryBuilder; 5 | 6 | /** 7 | * @author wanghuan 8 | * @description: DisMaxEsRequestHolder 9 | * @date 2022-01-26 11:28 10 | */ 11 | public class DisMaxEsRequestHolder extends AbstractEsRequestHolder { 12 | 13 | @Override 14 | public AbstractEsRequestHolder changeLogicConnector(EsConnector connector) { 15 | return this; 16 | } 17 | 18 | @Override 19 | protected void defineDefaultLogicConnector() { 20 | 21 | } 22 | 23 | @Override 24 | protected void defineQueryBuilder() { 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/hook/EsHookReedits.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.hook; 2 | 3 | import com.elasticsearch.engine.base.holder.AbstractEsRequestHolder; 4 | import com.elasticsearch.engine.base.model.exception.EsEngineConfigException; 5 | import com.google.common.collect.Maps; 6 | import org.elasticsearch.action.search.SearchResponse; 7 | 8 | import java.lang.reflect.Field; 9 | import java.util.Map; 10 | import java.util.Objects; 11 | 12 | /** 13 | * @author wanghuan 14 | * @description EsHookReedits 15 | * @mail 958721894@qq.com 16 | * @date 2022/6/9 14:11 17 | */ 18 | public class EsHookReedits { 19 | 20 | public static final Map REP_FUNC_REGEDIT = Maps.newHashMap(); 21 | 22 | public static final Map RESP_FUNC_REGEDIT = Maps.newHashMap(); 23 | 24 | public static void addReqHook(String key, RequestHook requestHook) { 25 | RequestHook checkBean = REP_FUNC_REGEDIT.get(key); 26 | if (Objects.nonNull(checkBean)) { 27 | throw new EsEngineConfigException("Duplicated RequestHook-Func Key define!!!"); 28 | } 29 | REP_FUNC_REGEDIT.put(key, requestHook); 30 | } 31 | 32 | public static void addRespHook(String key, ResponseHook responseHook) { 33 | ResponseHook checkBean = RESP_FUNC_REGEDIT.get(key); 34 | if (Objects.nonNull(checkBean)) { 35 | throw new EsEngineConfigException("Duplicated ResponseHook-Func Key define!!!"); 36 | } 37 | RESP_FUNC_REGEDIT.put(key, responseHook); 38 | } 39 | 40 | public static

AbstractEsRequestHolder useReqHook(String key, AbstractEsRequestHolder helper, P param) { 41 | return REP_FUNC_REGEDIT.get(key).handleRequest(helper, param); 42 | } 43 | 44 | public static R useRespHook(String key, SearchResponse resp) { 45 | return (R) RESP_FUNC_REGEDIT.get(key).handleResponse(resp); 46 | } 47 | 48 | public static void loadHooksFromTargetInterface(Class targetInterface) { 49 | Field[] allFields = targetInterface.getDeclaredFields(); 50 | for (Field currentField : allFields) { 51 | Class type = currentField.getType(); 52 | try { 53 | if (type.equals(RequestHook.class)) { 54 | String name = currentField.getName(); 55 | RequestHook currentReqHook = (RequestHook) currentField.get(targetInterface); 56 | EsHookReedits.addReqHook(name, currentReqHook); 57 | } 58 | if (type.equals(ResponseHook.class)) { 59 | String name = currentField.getName(); 60 | ResponseHook currentRespHook = (ResponseHook) currentField.get(targetInterface); 61 | EsHookReedits.addRespHook(name, currentRespHook); 62 | } 63 | } catch (IllegalAccessException e) { 64 | throw new Error("Hook-Func has a illegal access, please define it as #public static final"); 65 | } 66 | } 67 | } 68 | 69 | 70 | } 71 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/hook/RequestHook.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.hook; 2 | 3 | 4 | import com.elasticsearch.engine.base.holder.AbstractEsRequestHolder; 5 | 6 | /** 7 | * @author wanghuan 8 | * @description RequestHook 9 | * @mail 958721894@qq.com 10 | * @date 2022/6/9 14:10 11 | */ 12 | @FunctionalInterface 13 | public interface RequestHook { 14 | 15 | /** 16 | * user define the operation of request 17 | * you can extend-define Es-request or 18 | * define aggregation 19 | * 20 | * @param holder 21 | * @param param return 22 | */ 23 | AbstractEsRequestHolder handleRequest(AbstractEsRequestHolder holder, PARAM param); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/hook/ResponseHook.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.hook; 2 | 3 | import org.elasticsearch.action.search.SearchResponse; 4 | 5 | /** 6 | * @author wanghuan 7 | * @description ResponseHook 8 | * @mail 958721894@qq.com 9 | * @date 2022/6/9 14:10 10 | */ 11 | @FunctionalInterface 12 | public interface ResponseHook { 13 | 14 | /** 15 | * user define the method to handle ElasticSearch-Response 16 | * 17 | * @param resp return 18 | */ 19 | RESULT handleResponse(SearchResponse resp); 20 | 21 | } 22 | 23 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/hook/UserHooks.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.hook; 2 | 3 | /** 4 | * @author wanghuan 5 | * @description UserHooks 6 | * @mail 958721894@qq.com 7 | * @date 2022/6/9 14:09 8 | */ 9 | public interface UserHooks { 10 | 11 | 12 | } 13 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/mapping/annotation/Aggs.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.mapping.annotation; 2 | 3 | 4 | import com.elasticsearch.engine.base.model.annotion.Base; 5 | import com.elasticsearch.engine.base.model.annotion.Query; 6 | import com.elasticsearch.engine.base.model.annotion.Sign; 7 | 8 | import java.lang.annotation.*; 9 | 10 | /** 11 | * @author wanghuan 12 | * @description: 标记注解 Aggs 13 | * @date 2022-01-26 11:28 14 | */ 15 | @Sign 16 | @Query 17 | @Inherited 18 | @Documented 19 | @Target({ElementType.FIELD, ElementType.PARAMETER}) 20 | @Retention(RetentionPolicy.RUNTIME) 21 | public @interface Aggs { 22 | 23 | /** 24 | * 按照分组的key 正序排序 25 | */ 26 | String KEY_ASC = "KEY_ASC"; 27 | /** 28 | * 按照分组的key 倒序排序 29 | */ 30 | String KEY_DESC = "KEY_DESC"; 31 | /** 32 | * 按照分组的count 正序排序 按count排序时默认会加上 key asc 33 | * "order":[{"_count":"desc"},{"_key":"asc"}] 34 | */ 35 | String COUNT_ASC = "COUNT_ASC"; 36 | /** 37 | * 按照分组的count 倒序排序 按count排序时默认会加上 key asc 38 | * "order":[{"_count":"desc"},{"_key":"asc"}] 39 | */ 40 | String COUNT_DESC = "COUNT_DESC"; 41 | 42 | /** 43 | * es分组查询返回的size 44 | * ES分组查询不设置size,默认只返回10条数据 45 | */ 46 | Base value() default @Base; 47 | 48 | /** 49 | * ES分组查询不设置size,默认只返回10条数据 50 | */ 51 | int size() default 1000; 52 | 53 | /** 54 | * 排序类型 55 | * 56 | * @return 57 | */ 58 | String type() default KEY_ASC; 59 | } 60 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/mapping/annotation/Collapse.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.mapping.annotation; 2 | 3 | 4 | import com.elasticsearch.engine.base.model.annotion.Base; 5 | import com.elasticsearch.engine.base.model.annotion.Query; 6 | import com.elasticsearch.engine.base.model.annotion.Sign; 7 | 8 | import java.lang.annotation.*; 9 | 10 | /** 11 | * @author wanghuan 12 | * @description: 标记注解 Collapse 13 | * @date 2022-01-26 11:28 14 | */ 15 | @Sign 16 | @Query 17 | @Inherited 18 | @Documented 19 | @Target({ElementType.FIELD, ElementType.PARAMETER}) 20 | @Retention(RetentionPolicy.RUNTIME) 21 | public @interface Collapse { 22 | 23 | Base value() default @Base; 24 | 25 | /** 26 | * ES分组查询不设置size,默认只返回10条数据 27 | */ 28 | int size() default 1000; 29 | } 30 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/mapping/annotation/Exist.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.mapping.annotation; 2 | 3 | 4 | import com.elasticsearch.engine.base.model.annotion.Base; 5 | import com.elasticsearch.engine.base.model.annotion.Query; 6 | import com.elasticsearch.engine.base.model.annotion.Sign; 7 | 8 | import java.lang.annotation.*; 9 | 10 | /** 11 | * @author wanghuan 12 | * @description: 标记注解 Exist 13 | * exists 查询可以用于查找文档中是否包含指定字段或没有某个字段,或判断某个字段是否为null/或者不为null , 类似于SQL语句中的 is null/is not null 14 | * EsConnector.MUST 查找文档中是否包含指定字段 is not null (查询field != null的记录) 15 | * EsConnector.NOT_MUST 查找文档中是否包含指定字段 is null (查询field == null的记录) 16 | * @date 2022-02-11 17:37 17 | */ 18 | @Sign 19 | @Query 20 | @Inherited 21 | @Documented 22 | @Target({ElementType.FIELD, ElementType.PARAMETER}) 23 | @Retention(RetentionPolicy.RUNTIME) 24 | public @interface Exist { 25 | 26 | Base value() default @Base; 27 | } 28 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/mapping/annotation/From.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.mapping.annotation; 2 | 3 | 4 | import com.elasticsearch.engine.base.model.annotion.Base; 5 | import com.elasticsearch.engine.base.model.annotion.Query; 6 | 7 | import java.lang.annotation.*; 8 | 9 | /** 10 | * @author wanghuan 11 | * @description: From 12 | * @date 2022-01-26 11:28 13 | */ 14 | @Query 15 | @Inherited 16 | @Documented 17 | @Target({ElementType.FIELD, ElementType.PARAMETER}) 18 | @Retention(RetentionPolicy.RUNTIME) 19 | public @interface From { 20 | 21 | 22 | Base value() default @Base; 23 | 24 | /** 25 | * es7 格式化 26 | * 27 | * @return 28 | */ 29 | String format() default ""; 30 | 31 | String timeZone() default ""; 32 | 33 | /** 34 | * 多个range时, 使用 group标识一对匹配的 from和to 35 | * 36 | * @return 37 | */ 38 | int group() default 0; 39 | } 40 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/mapping/annotation/PageAndOrder.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.mapping.annotation; 2 | 3 | 4 | import com.elasticsearch.engine.base.model.annotion.Base; 5 | import com.elasticsearch.engine.base.model.annotion.Query; 6 | 7 | import java.lang.annotation.*; 8 | 9 | /** 10 | * @author wanghuan 11 | * @description: PageAndOrder 12 | * @date 2022-01-26 11:28 13 | */ 14 | @Query 15 | @Inherited 16 | @Documented 17 | @Target({ElementType.FIELD, ElementType.PARAMETER}) 18 | @Retention(RetentionPolicy.RUNTIME) 19 | public @interface PageAndOrder { 20 | 21 | Base value() default @Base; 22 | } 23 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/mapping/annotation/Prefix.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.mapping.annotation; 2 | 3 | 4 | import com.elasticsearch.engine.base.model.annotion.Base; 5 | import com.elasticsearch.engine.base.model.annotion.Query; 6 | 7 | import java.lang.annotation.*; 8 | 9 | /** 10 | * @author wanghuan 11 | * @description: Prefix 12 | * @date 2022-01-26 11:28 13 | */ 14 | @Query 15 | @Inherited 16 | @Documented 17 | @Target({ElementType.FIELD, ElementType.PARAMETER}) 18 | @Retention(RetentionPolicy.RUNTIME) 19 | public @interface Prefix { 20 | 21 | Base value() default @Base; 22 | 23 | } 24 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/mapping/annotation/Range.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.mapping.annotation; 2 | 3 | 4 | import com.elasticsearch.engine.base.model.annotion.Base; 5 | import com.elasticsearch.engine.base.model.annotion.Query; 6 | 7 | import java.lang.annotation.*; 8 | 9 | /** 10 | * @author wanghuan 11 | * @description: Range 12 | * @date 2022-01-26 11:28 13 | */ 14 | @Query 15 | @Inherited 16 | @Documented 17 | @Target({ElementType.FIELD, ElementType.PARAMETER}) 18 | @Retention(RetentionPolicy.RUNTIME) 19 | public @interface Range { 20 | 21 | /** 22 | * 表示左右包含 >= L and <= G 23 | */ 24 | String LE_GE = "[L,G]"; 25 | /** 26 | * 表示左右都不包含 >L and < G 27 | */ 28 | String L_G = "(L,G)"; 29 | /** 30 | * 表示左右都不包含 >=L and < G 31 | */ 32 | String LE_G = "[L,G)"; 33 | /** 34 | * 表示左右都不包含 >L and <= G 35 | */ 36 | String L_GE = "(L,G]"; 37 | /** 38 | * 表示 from to 39 | */ 40 | String F_T = "F_T"; 41 | 42 | Base value() default @Base; 43 | 44 | /** 45 | * range-query both side relation 46 | * {@value LE_GE} 47 | * {@value L_G} 48 | * {@value LE_G} 49 | * {@value L_GE} 50 | * {@value F_T} 51 | * return 52 | */ 53 | String tag() default L_G; 54 | 55 | String format() default ""; 56 | 57 | String timeZone() default ""; 58 | 59 | //within、contains。intersects 60 | String relation() default ""; 61 | 62 | boolean includeLower() default false; 63 | 64 | boolean includeUpper() default false; 65 | } 66 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/mapping/annotation/Sort.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.mapping.annotation; 2 | 3 | import com.elasticsearch.engine.base.model.annotion.Base; 4 | import com.elasticsearch.engine.base.model.annotion.Query; 5 | import com.elasticsearch.engine.base.model.annotion.Sign; 6 | import org.elasticsearch.search.sort.SortOrder; 7 | 8 | import java.lang.annotation.*; 9 | 10 | /** 11 | * @author wanghuan 12 | * @description: 标记注解 Sort 13 | * @date 2022-01-26 11:28 14 | */ 15 | @Sign 16 | @Query 17 | @Inherited 18 | @Documented 19 | @Target({ElementType.FIELD, ElementType.PARAMETER}) 20 | @Retention(RetentionPolicy.RUNTIME) 21 | public @interface Sort { 22 | 23 | Base value() default @Base; 24 | 25 | SortOrder type() default SortOrder.ASC; 26 | } 27 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/mapping/annotation/Term.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.mapping.annotation; 2 | 3 | 4 | import com.elasticsearch.engine.base.model.annotion.Base; 5 | import com.elasticsearch.engine.base.model.annotion.Query; 6 | 7 | import java.lang.annotation.*; 8 | 9 | /** 10 | * @author wanghuan 11 | * @description: Term 12 | * @date 2022-01-26 11:28 13 | */ 14 | @Query 15 | @Inherited 16 | @Documented 17 | @Target({ElementType.FIELD, ElementType.PARAMETER}) 18 | @Retention(RetentionPolicy.RUNTIME) 19 | public @interface Term { 20 | 21 | Base value() default @Base; 22 | 23 | } 24 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/mapping/annotation/Terms.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.mapping.annotation; 2 | 3 | 4 | import com.elasticsearch.engine.base.model.annotion.Base; 5 | import com.elasticsearch.engine.base.model.annotion.Query; 6 | 7 | import java.lang.annotation.*; 8 | 9 | /** 10 | * @author wanghuan 11 | * @description: Terms 12 | * @date 2022-01-26 11:28 13 | */ 14 | @Query 15 | @Inherited 16 | @Documented 17 | @Target({ElementType.FIELD, ElementType.PARAMETER}) 18 | @Retention(RetentionPolicy.RUNTIME) 19 | public @interface Terms { 20 | 21 | Base value() default @Base; 22 | 23 | } 24 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/mapping/annotation/To.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.mapping.annotation; 2 | 3 | 4 | import com.elasticsearch.engine.base.model.annotion.Base; 5 | import com.elasticsearch.engine.base.model.annotion.Query; 6 | 7 | import java.lang.annotation.*; 8 | 9 | /** 10 | * @author wanghuan 11 | * @description: To 12 | * @date 2022-01-26 11:28 13 | */ 14 | @Query 15 | @Inherited 16 | @Documented 17 | @Target({ElementType.FIELD, ElementType.PARAMETER}) 18 | @Retention(RetentionPolicy.RUNTIME) 19 | public @interface To { 20 | 21 | Base value() default @Base; 22 | 23 | /** 24 | * es7格式化 25 | * 26 | * @return 27 | */ 28 | String format() default ""; 29 | 30 | String timeZone() default ""; 31 | 32 | /** 33 | * 多个range时, 使用 group标识一对匹配的 from和to 34 | * 35 | * @return 36 | */ 37 | int group() default 0; 38 | } 39 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/mapping/annotation/WildCard.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.mapping.annotation; 2 | 3 | 4 | import com.elasticsearch.engine.base.model.annotion.Base; 5 | import com.elasticsearch.engine.base.model.annotion.Query; 6 | 7 | import java.lang.annotation.*; 8 | 9 | /** 10 | * WildCard 11 | * real-fuzzy for elasticsearch, un-use analyzer, similar mysql's like %holder% 12 | * WildCard query's value tag: 13 | * '*': multi-words holder 14 | * '?': single-words holder 15 | * 16 | * @author wanghuan 17 | * @date 2022-01-26 11:28 18 | */ 19 | @Query 20 | @Inherited 21 | @Documented 22 | @Target({ElementType.FIELD, ElementType.PARAMETER}) 23 | @Retention(RetentionPolicy.RUNTIME) 24 | public @interface WildCard { 25 | 26 | /** 27 | * like %${param} 28 | */ 29 | String BEFORE_MATCH = "*%s"; 30 | /** 31 | * 表示 like ${param}% 32 | */ 33 | String AFTER_MATCH = "%s*"; 34 | /** 35 | * 表示 like %${param}% 36 | */ 37 | String INCLUDE_MATCH = "*%s*"; 38 | 39 | Base value() default @Base; 40 | 41 | /** 42 | * 匹配类型 (required) 43 | * 44 | * @return 45 | */ 46 | String tag() default INCLUDE_MATCH; 47 | 48 | } 49 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/mapping/annotation/hook/UseRequestHook.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.mapping.annotation.hook; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * @author wanghuan 7 | * @description UseRequestHook 8 | * @mail 958721894@qq.com 9 | * @date 2022/6/9 14:11 10 | */ 11 | @Documented 12 | @Retention(RetentionPolicy.RUNTIME) 13 | @Target({ElementType.METHOD, ElementType.TYPE}) 14 | public @interface UseRequestHook { 15 | 16 | String value(); 17 | 18 | } 19 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/mapping/annotation/hook/UseResponseHook.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.mapping.annotation.hook; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * @author wanghuan 7 | * @description UseResponseHook 8 | * @mail 958721894@qq.com 9 | * @date 2022/6/9 14:13 10 | */ 11 | @Documented 12 | @Retention(RetentionPolicy.RUNTIME) 13 | @Target({ElementType.METHOD, ElementType.TYPE}) 14 | public @interface UseResponseHook { 15 | 16 | String value(); 17 | 18 | } 19 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/mapping/annotation/method/Exclude.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.mapping.annotation.method; 2 | 3 | 4 | import com.elasticsearch.engine.base.model.annotion.MethodQuery; 5 | 6 | import java.lang.annotation.*; 7 | 8 | /** 9 | * @author wanghuan 10 | * @description Exclude 11 | * @mail 958721894@qq.com 12 | * @date 2022/6/15 00:00 13 | */ 14 | @MethodQuery 15 | @Inherited 16 | @Documented 17 | @Target({ElementType.METHOD}) 18 | @Retention(RetentionPolicy.RUNTIME) 19 | public @interface Exclude { 20 | 21 | String[] value() default {}; 22 | } 23 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/mapping/annotation/method/Include.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.mapping.annotation.method; 2 | 3 | 4 | import com.elasticsearch.engine.base.model.annotion.MethodQuery; 5 | 6 | import java.lang.annotation.*; 7 | 8 | /** 9 | * @author wanghuan 10 | * @description Include 11 | * @mail 958721894@qq.com 12 | * @date 2022/6/15 00:00 13 | */ 14 | @MethodQuery 15 | @Inherited 16 | @Documented 17 | @Target({ElementType.METHOD}) 18 | @Retention(RetentionPolicy.RUNTIME) 19 | public @interface Include { 20 | 21 | String[] value() default {}; 22 | 23 | } 24 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/mapping/annotation/method/Order.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.mapping.annotation.method; 2 | 3 | import com.elasticsearch.engine.base.model.annotion.MethodQuery; 4 | import org.elasticsearch.search.sort.SortOrder; 5 | 6 | import java.lang.annotation.*; 7 | 8 | /** 9 | * @author wanghuan 10 | * @description Order 11 | * @mail 958721894@qq.com 12 | * @date 2022-06-15 09:59 13 | */ 14 | @MethodQuery 15 | @Inherited 16 | @Documented 17 | @Target({ElementType.METHOD}) 18 | @Retention(RetentionPolicy.RUNTIME) 19 | public @interface Order { 20 | 21 | /** 22 | * 排序的字段 23 | * @return 24 | */ 25 | String value() ; 26 | 27 | /** 28 | * 排序的顺序 29 | * @return 30 | */ 31 | SortOrder type() default SortOrder.ASC; 32 | } 33 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/mapping/annotation/method/Size.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.mapping.annotation.method; 2 | 3 | 4 | import com.elasticsearch.engine.base.model.annotion.MethodQuery; 5 | 6 | import java.lang.annotation.*; 7 | 8 | /** 9 | * @author wanghuan 10 | * @description Size 11 | * @mail 958721894@qq.com 12 | * @date 2022/6/14 23:58 13 | */ 14 | @MethodQuery 15 | @Inherited 16 | @Documented 17 | @Target({ElementType.METHOD}) 18 | @Retention(RetentionPolicy.RUNTIME) 19 | public @interface Size { 20 | 21 | int value() default 1000; 22 | } 23 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/mapping/handler/AbstractQueryHandler.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.mapping.handler; 2 | 3 | import com.elasticsearch.engine.base.common.utils.ExtAnnBeanMapUtils; 4 | import com.elasticsearch.engine.base.holder.AbstractEsRequestHolder; 5 | import com.elasticsearch.engine.base.model.domain.AbstractQueryBean; 6 | import com.elasticsearch.engine.base.model.domain.EsQueryFieldBean; 7 | import com.elasticsearch.engine.base.model.exception.EsEngineConfigException; 8 | import org.elasticsearch.index.query.QueryBuilder; 9 | 10 | import java.lang.reflect.ParameterizedType; 11 | import java.lang.reflect.Type; 12 | import java.util.Objects; 13 | 14 | /** 15 | * @author wanghuan 16 | * @description: AbstractQueryHandler 17 | * @date 2021-09-29 18 | * @time 10:33 19 | */ 20 | public abstract class AbstractQueryHandler { 21 | 22 | /** 23 | * 查询注解解析拼接查询语句 24 | * 25 | * @param queryDes 26 | * @param searchHelper return 27 | */ 28 | public abstract QueryBuilder handle(EsQueryFieldBean queryDes, AbstractEsRequestHolder searchHelper); 29 | 30 | /** 31 | * execute param-explain 32 | * 33 | * @param queryDes 34 | * @param searchHelper return 35 | */ 36 | public final AbstractEsRequestHolder execute(EsQueryFieldBean queryDes, AbstractEsRequestHolder searchHelper) { 37 | //拼接查询连接 38 | searchHelper.changeLogicConnector(queryDes.getLogicConnector()); 39 | //构建扩展查询类 40 | handleExtBean(queryDes); 41 | //拼接查询语句 42 | QueryBuilder queryBuilder = handle(queryDes, searchHelper); 43 | if (Objects.nonNull(queryBuilder)) { 44 | queryDes.getExtBean().configQueryBuilder(queryDes,queryBuilder); 45 | handleExtConfig(queryDes, queryBuilder); 46 | } 47 | return searchHelper; 48 | } 49 | 50 | /** 51 | * explain the extend-params 52 | * final handle-process of query-field-reader 53 | * TODO 扩展点 54 | * 55 | * @param queryDes return 56 | */ 57 | protected void handleExtConfig(EsQueryFieldBean queryDes, QueryBuilder queryBuilder) { 58 | // do nothing, if need translate QueryDes.extendDefine, you need implement this method 59 | } 60 | 61 | /** 62 | * mapping the annotation 63 | * 64 | * @param queryDes return 65 | */ 66 | protected final EsQueryFieldBean handleExtBean(EsQueryFieldBean queryDes) { 67 | try { 68 | Type[] actualTypeArguments = ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments(); 69 | if (actualTypeArguments.length == 0) { 70 | return queryDes; 71 | } 72 | String fullClassPath = actualTypeArguments[0].getTypeName(); 73 | Class aClass = Class.forName(fullClassPath); 74 | T extBean = (T) ExtAnnBeanMapUtils.mapping(queryDes.getExtAnnotation(), aClass); 75 | queryDes.setExtBean(extBean); 76 | return queryDes; 77 | } catch (ClassNotFoundException e) { 78 | throw new EsEngineConfigException("queryHandle-actualType class not found, cause:", e); 79 | } 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/mapping/handler/AggsQueryHandler.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.mapping.handler; 2 | 3 | import com.elasticsearch.engine.base.holder.AbstractEsRequestHolder; 4 | import com.elasticsearch.engine.base.mapping.annotation.Aggs; 5 | import com.elasticsearch.engine.base.mapping.model.AggsQueryBean; 6 | import com.elasticsearch.engine.base.model.annotion.EsQueryHandle; 7 | import com.elasticsearch.engine.base.model.constant.EsConstant; 8 | import com.elasticsearch.engine.base.model.domain.EsQueryFieldBean; 9 | import org.apache.commons.lang3.math.NumberUtils; 10 | import org.elasticsearch.index.query.QueryBuilder; 11 | import org.elasticsearch.search.aggregations.AggregationBuilders; 12 | import org.elasticsearch.search.aggregations.BucketOrder; 13 | import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder; 14 | import org.elasticsearch.search.builder.SearchSourceBuilder; 15 | 16 | /** 17 | * @author wanghuan 18 | * @description: AggsQueryHandler 19 | * @date 2022-01-26 11:28 20 | */ 21 | @EsQueryHandle(Aggs.class) 22 | public class AggsQueryHandler extends AbstractQueryHandler { 23 | 24 | @Override 25 | public QueryBuilder handle(EsQueryFieldBean queryDes, AbstractEsRequestHolder searchHelper) { 26 | SearchSourceBuilder source = searchHelper.getSource(); 27 | AggsQueryBean extBean = queryDes.getExtBean(); 28 | TermsAggregationBuilder aggs = AggregationBuilders 29 | .terms(EsConstant.AGG) 30 | .field(queryDes.getField()) 31 | .size(extBean.getSize()); 32 | source.aggregation(aggs) 33 | .size(NumberUtils.INTEGER_ZERO); 34 | //设置排序 35 | switch (extBean.getType()) { 36 | case Aggs.KEY_ASC: 37 | //按照key排序 true 为 asc 38 | aggs.order(BucketOrder.key(true)); 39 | break; 40 | case Aggs.KEY_DESC: 41 | aggs.order(BucketOrder.key(false)); 42 | break; 43 | case Aggs.COUNT_ASC: 44 | aggs.order(BucketOrder.count(true)); 45 | break; 46 | case Aggs.COUNT_DESC: 47 | aggs.order(BucketOrder.count(false)); 48 | break; 49 | default: 50 | } 51 | return null; 52 | } 53 | 54 | } 55 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/mapping/handler/CollapseQueryHandler.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.mapping.handler; 2 | 3 | import com.elasticsearch.engine.base.holder.AbstractEsRequestHolder; 4 | import com.elasticsearch.engine.base.mapping.annotation.Collapse; 5 | import com.elasticsearch.engine.base.mapping.model.CollapseQueryBean; 6 | import com.elasticsearch.engine.base.model.annotion.EsQueryHandle; 7 | import com.elasticsearch.engine.base.model.domain.EsQueryFieldBean; 8 | import org.elasticsearch.index.query.QueryBuilder; 9 | import org.elasticsearch.search.builder.SearchSourceBuilder; 10 | import org.elasticsearch.search.collapse.CollapseBuilder; 11 | 12 | /** 13 | * @author wanghuan 14 | * @description: CollapseQueryHandler 15 | * @date 2022-01-26 11:28 16 | */ 17 | @EsQueryHandle(Collapse.class) 18 | public class CollapseQueryHandler extends AbstractQueryHandler { 19 | 20 | @Override 21 | public QueryBuilder handle(EsQueryFieldBean queryDes, AbstractEsRequestHolder searchHelper) { 22 | SearchSourceBuilder source = searchHelper.getSource(); 23 | CollapseQueryBean extBean = queryDes.getExtBean(); 24 | source.collapse(new CollapseBuilder(queryDes.getField())) 25 | .size(extBean.getSize()); 26 | return null; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/mapping/handler/EsConditionHandle.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.mapping.handler; 2 | 3 | /** 4 | * @author wanghuan 5 | * @description EsConditionHandle 6 | * @mail 958721894@qq.com 7 | * @date 2022/6/9 14:11 8 | */ 9 | public interface EsConditionHandle { 10 | 11 | /** 12 | * if The val is useful 13 | * 14 | * @param val return 15 | */ 16 | boolean test(T val); 17 | 18 | } 19 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/mapping/handler/ExistQueryHandler.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.mapping.handler; 2 | 3 | import com.elasticsearch.engine.base.holder.AbstractEsRequestHolder; 4 | import com.elasticsearch.engine.base.mapping.annotation.Exist; 5 | import com.elasticsearch.engine.base.mapping.model.ExistQueryBean; 6 | import com.elasticsearch.engine.base.model.annotion.EsQueryHandle; 7 | import com.elasticsearch.engine.base.model.domain.EsQueryFieldBean; 8 | import org.elasticsearch.index.query.ExistsQueryBuilder; 9 | import org.elasticsearch.index.query.QueryBuilder; 10 | import org.elasticsearch.index.query.QueryBuilders; 11 | 12 | /** 13 | * @author wanghuan 14 | * @description: ExistQueryHandler 15 | * @date 2022-02-11 17:40 16 | */ 17 | @EsQueryHandle(Exist.class) 18 | public class ExistQueryHandler extends AbstractQueryHandler { 19 | /** 20 | * 查询注解解析拼接查询语句 21 | * 22 | * @param queryDes 23 | * @param searchHelper 24 | */ 25 | @Override 26 | public QueryBuilder handle(EsQueryFieldBean queryDes, AbstractEsRequestHolder searchHelper) { 27 | ExistsQueryBuilder existsQueryBuilder = QueryBuilders.existsQuery(queryDes.getField()); 28 | searchHelper.chain(existsQueryBuilder); 29 | return existsQueryBuilder; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/mapping/handler/FromQueryHandler.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.mapping.handler; 2 | 3 | import com.elasticsearch.engine.base.holder.AbstractEsRequestHolder; 4 | import com.elasticsearch.engine.base.mapping.annotation.From; 5 | import com.elasticsearch.engine.base.mapping.model.FromQueryBean; 6 | import com.elasticsearch.engine.base.model.annotion.EsQueryHandle; 7 | import com.elasticsearch.engine.base.model.domain.EsQueryFieldBean; 8 | import org.elasticsearch.index.query.QueryBuilder; 9 | import org.elasticsearch.index.query.QueryBuilders; 10 | import org.elasticsearch.index.query.RangeQueryBuilder; 11 | 12 | import java.util.Map; 13 | 14 | /** 15 | * @author wanghuan 16 | * @description: from 查询Handler 17 | * @date 2022-02-07 10:11 18 | */ 19 | @EsQueryHandle(From.class) 20 | public class FromQueryHandler extends AbstractQueryHandler { 21 | 22 | 23 | /** 24 | * 查询注解解析拼接查询语句 25 | * 26 | * @param queryDes 27 | * @param searchHelper 28 | */ 29 | @Override 30 | public QueryBuilder handle(EsQueryFieldBean queryDes, AbstractEsRequestHolder searchHelper) { 31 | Map map = searchHelper.getRange(); 32 | FromQueryBean fromQueryBean = queryDes.getExtBean(); 33 | Integer group = fromQueryBean.getGroup(); 34 | RangeQueryBuilder range; 35 | if (map.containsKey(group)) { 36 | range = map.get(group); 37 | } else { 38 | range = QueryBuilders.rangeQuery(queryDes.getField()); 39 | } 40 | range.from(queryDes.getValue()); 41 | map.put(group, range); 42 | return range; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/mapping/handler/PageAndOrderQueryHandler.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.mapping.handler; 2 | 3 | import com.elasticsearch.engine.base.holder.AbstractEsRequestHolder; 4 | import com.elasticsearch.engine.base.mapping.annotation.PageAndOrder; 5 | import com.elasticsearch.engine.base.mapping.model.PageQueryBean; 6 | import com.elasticsearch.engine.base.mapping.model.extend.PageParam; 7 | import com.elasticsearch.engine.base.model.annotion.EsQueryHandle; 8 | import com.elasticsearch.engine.base.model.domain.EsQueryFieldBean; 9 | import com.elasticsearch.engine.base.model.exception.EsEngineQueryException; 10 | import org.apache.commons.collections4.MapUtils; 11 | import org.elasticsearch.index.query.QueryBuilder; 12 | import org.elasticsearch.search.builder.SearchSourceBuilder; 13 | import org.elasticsearch.search.sort.SortOrder; 14 | 15 | import java.util.LinkedHashMap; 16 | import java.util.Map; 17 | import java.util.Objects; 18 | 19 | /** 20 | * @author wanghuan 21 | * @description: PageAndOrderQueryHandler 22 | * @date 2022-01-26 11:28 23 | */ 24 | @EsQueryHandle(PageAndOrder.class) 25 | public class PageAndOrderQueryHandler extends AbstractQueryHandler { 26 | 27 | @Override 28 | public QueryBuilder handle(EsQueryFieldBean queryDes, AbstractEsRequestHolder searchHelper) { 29 | Object value = queryDes.getValue(); 30 | if (!value.getClass().equals(PageParam.class)) { 31 | throw new EsEngineQueryException("@PageAndOrder have to define as PageParam.class"); 32 | } 33 | PageParam pageParam = (PageParam) value; 34 | SearchSourceBuilder source = searchHelper.getSource(); 35 | source.from(pageParam.getExclude()).size(pageParam.getPageSize()); 36 | LinkedHashMap orderMap = pageParam.getOrderMap(); 37 | if (MapUtils.isNotEmpty(orderMap)) { 38 | for (Map.Entry entry : orderMap.entrySet()) { 39 | source.sort(entry.getKey(), Objects.nonNull(entry.getValue()) ? entry.getValue() : SortOrder.ASC); 40 | } 41 | } 42 | return null; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/mapping/handler/PrefixQueryHandler.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.mapping.handler; 2 | 3 | import com.elasticsearch.engine.base.holder.AbstractEsRequestHolder; 4 | import com.elasticsearch.engine.base.mapping.annotation.Prefix; 5 | import com.elasticsearch.engine.base.mapping.model.PrefixQueryBean; 6 | import com.elasticsearch.engine.base.model.annotion.EsQueryHandle; 7 | import com.elasticsearch.engine.base.model.domain.EsQueryFieldBean; 8 | import org.elasticsearch.index.query.QueryBuilder; 9 | import org.elasticsearch.index.query.QueryBuilders; 10 | 11 | /** 12 | * @author wanghuan 13 | * @description: PrefixQueryHandler 14 | * @date 2022-01-26 11:28 15 | */ 16 | @EsQueryHandle(Prefix.class) 17 | public class PrefixQueryHandler extends AbstractQueryHandler { 18 | 19 | @Override 20 | public QueryBuilder handle(EsQueryFieldBean queryDes, AbstractEsRequestHolder searchHelper) { 21 | String value = queryDes.getValue().toString(); 22 | QueryBuilder prefixQueryBuilder = QueryBuilders.prefixQuery(queryDes.getField(), value); 23 | searchHelper.chain(prefixQueryBuilder); 24 | return prefixQueryBuilder; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/mapping/handler/RangeQueryHandler.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.mapping.handler; 2 | 3 | import com.elasticsearch.engine.base.holder.AbstractEsRequestHolder; 4 | import com.elasticsearch.engine.base.mapping.annotation.Range; 5 | import com.elasticsearch.engine.base.mapping.model.RangeQueryBean; 6 | import com.elasticsearch.engine.base.mapping.model.extend.RangeParam; 7 | import com.elasticsearch.engine.base.model.annotion.EsQueryHandle; 8 | import com.elasticsearch.engine.base.model.domain.EsQueryFieldBean; 9 | import org.elasticsearch.index.query.QueryBuilder; 10 | import org.elasticsearch.index.query.QueryBuilders; 11 | import org.elasticsearch.index.query.RangeQueryBuilder; 12 | 13 | import java.util.Objects; 14 | import java.util.Optional; 15 | 16 | /** 17 | * @author wanghuan 18 | * @description: RangeQueryHandler 19 | * @date 2022-01-26 11:28 20 | */ 21 | @EsQueryHandle(Range.class) 22 | public class RangeQueryHandler extends AbstractQueryHandler { 23 | 24 | @Override 25 | public QueryBuilder handle(EsQueryFieldBean queryDes, AbstractEsRequestHolder searchHelper) { 26 | RangeParam rangeParam = (RangeParam) queryDes.getValue(); 27 | if (Objects.isNull(rangeParam.getLeft()) && Objects.isNull(rangeParam.getRight())) { 28 | return null; 29 | } 30 | final RangeQueryBuilder rangeQuery = QueryBuilders.rangeQuery(queryDes.getField()); 31 | RangeQueryBean rangeBean = queryDes.getExtBean(); 32 | switch (rangeBean.getTag()) { 33 | case Range.LE_GE: 34 | Optional.ofNullable(rangeParam.getLeft()).ifPresent(rangeQuery::gte); 35 | Optional.ofNullable(rangeParam.getRight()).ifPresent(rangeQuery::lte); 36 | break; 37 | case Range.L_G: 38 | Optional.ofNullable(rangeParam.getLeft()).ifPresent(rangeQuery::gt); 39 | Optional.ofNullable(rangeParam.getRight()).ifPresent(rangeQuery::lt); 40 | break; 41 | case Range.LE_G: 42 | Optional.ofNullable(rangeParam.getLeft()).ifPresent(rangeQuery::gte); 43 | Optional.ofNullable(rangeParam.getRight()).ifPresent(rangeQuery::lt); 44 | break; 45 | case Range.L_GE: 46 | Optional.ofNullable(rangeParam.getLeft()).ifPresent(rangeQuery::gt); 47 | Optional.ofNullable(rangeParam.getRight()).ifPresent(rangeQuery::lte); 48 | break; 49 | case Range.F_T: 50 | Optional.ofNullable(rangeParam.getLeft()).ifPresent(rangeQuery::from); 51 | Optional.ofNullable(rangeParam.getRight()).ifPresent(rangeQuery::to); 52 | break; 53 | default: 54 | } 55 | searchHelper.chain(rangeQuery); 56 | return rangeQuery; 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/mapping/handler/SortQueryHandler.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.mapping.handler; 2 | 3 | import com.elasticsearch.engine.base.holder.AbstractEsRequestHolder; 4 | import com.elasticsearch.engine.base.mapping.annotation.Sort; 5 | import com.elasticsearch.engine.base.mapping.model.SortQueryBean; 6 | import com.elasticsearch.engine.base.model.annotion.EsQueryHandle; 7 | import com.elasticsearch.engine.base.model.domain.EsQueryFieldBean; 8 | import org.elasticsearch.index.query.QueryBuilder; 9 | import org.elasticsearch.search.builder.SearchSourceBuilder; 10 | 11 | /** 12 | * @author wanghuan 13 | * @description: SortQueryHandler 14 | * @date 2022-01-26 11:28 15 | */ 16 | @EsQueryHandle(Sort.class) 17 | public class SortQueryHandler extends AbstractQueryHandler { 18 | 19 | @Override 20 | public QueryBuilder handle(EsQueryFieldBean queryDes, AbstractEsRequestHolder searchHelper) { 21 | SearchSourceBuilder source = searchHelper.getSource(); 22 | SortQueryBean extBean = queryDes.getExtBean(); 23 | source.sort(queryDes.getField(), extBean.getType()); 24 | return null; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/mapping/handler/TermQueryHandler.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.mapping.handler; 2 | 3 | import com.elasticsearch.engine.base.holder.AbstractEsRequestHolder; 4 | import com.elasticsearch.engine.base.mapping.annotation.Term; 5 | import com.elasticsearch.engine.base.mapping.model.TermQueryBean; 6 | import com.elasticsearch.engine.base.model.annotion.EsQueryHandle; 7 | import com.elasticsearch.engine.base.model.domain.EsQueryFieldBean; 8 | import org.elasticsearch.index.query.QueryBuilder; 9 | import org.elasticsearch.index.query.QueryBuilders; 10 | import org.elasticsearch.index.query.TermQueryBuilder; 11 | 12 | /** 13 | * TermQueryHandle 14 | * 15 | * @author wanghuan 16 | * @EsQueryIndex(index = "test_index", model = QueryModel.bool) 17 | * class Param { 18 | * @EsQueryField(name = "user_name", logicConnector = EsConnector.SHOULD, meta = EsMeta.KEYWORD, boost = 2.0) 19 | * private String userName; 20 | *

21 | * } 22 | * @date 2022-01-26 11:28 23 | */ 24 | @EsQueryHandle(Term.class) 25 | public class TermQueryHandler extends AbstractQueryHandler { 26 | 27 | /** 28 | * @param queryDes 29 | * @param searchHelper return 30 | */ 31 | @Override 32 | public QueryBuilder handle(EsQueryFieldBean queryDes, AbstractEsRequestHolder searchHelper) { 33 | TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery(queryDes.getField(), queryDes.getValue()); 34 | searchHelper.chain(termQueryBuilder); 35 | return termQueryBuilder; 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/mapping/handler/TermsQueryHandler.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.mapping.handler; 2 | 3 | import com.elasticsearch.engine.base.common.utils.ReflectionUtils; 4 | import com.elasticsearch.engine.base.holder.AbstractEsRequestHolder; 5 | import com.elasticsearch.engine.base.mapping.annotation.Terms; 6 | import com.elasticsearch.engine.base.mapping.model.TermsQueryBean; 7 | import com.elasticsearch.engine.base.model.annotion.EsQueryHandle; 8 | import com.elasticsearch.engine.base.model.domain.EsQueryFieldBean; 9 | import org.elasticsearch.index.query.QueryBuilder; 10 | import org.elasticsearch.index.query.QueryBuilders; 11 | import org.elasticsearch.index.query.TermsQueryBuilder; 12 | 13 | import java.util.Collection; 14 | 15 | /** 16 | * @author wanghuan 17 | * @description: TermsQueryHandler 18 | * @date 2022-01-26 11:28 19 | */ 20 | @EsQueryHandle(Terms.class) 21 | public class TermsQueryHandler extends AbstractQueryHandler { 22 | 23 | @Override 24 | public QueryBuilder handle(EsQueryFieldBean queryDes, AbstractEsRequestHolder searchHelper) { 25 | Collection value = ReflectionUtils.transArrayOrCollection(queryDes.getValue()); 26 | TermsQueryBuilder queryBuilder = QueryBuilders.termsQuery(queryDes.getField(), value); 27 | searchHelper.chain(queryBuilder); 28 | return queryBuilder; 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/mapping/handler/ToQueryHandler.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.mapping.handler; 2 | 3 | import com.elasticsearch.engine.base.holder.AbstractEsRequestHolder; 4 | import com.elasticsearch.engine.base.mapping.annotation.To; 5 | import com.elasticsearch.engine.base.mapping.model.ToQueryBean; 6 | import com.elasticsearch.engine.base.model.annotion.EsQueryHandle; 7 | import com.elasticsearch.engine.base.model.domain.EsQueryFieldBean; 8 | import org.elasticsearch.index.query.QueryBuilder; 9 | import org.elasticsearch.index.query.QueryBuilders; 10 | import org.elasticsearch.index.query.RangeQueryBuilder; 11 | 12 | import java.util.Map; 13 | 14 | /** 15 | * @author wanghuan 16 | * @description: from 查询Handler 17 | * @date 2022-02-07 10:11 18 | */ 19 | @EsQueryHandle(To.class) 20 | public class ToQueryHandler extends AbstractQueryHandler { 21 | 22 | 23 | /** 24 | * 查询注解解析拼接查询语句 25 | * 26 | * @param queryDes 27 | * @param searchHelper 28 | */ 29 | @Override 30 | public QueryBuilder handle(EsQueryFieldBean queryDes, AbstractEsRequestHolder searchHelper) { 31 | Map map = searchHelper.getRange(); 32 | ToQueryBean toQueryBean = queryDes.getExtBean(); 33 | Integer group = toQueryBean.getGroup(); 34 | RangeQueryBuilder range; 35 | if (map.containsKey(group)) { 36 | range = map.get(group); 37 | } else { 38 | range = QueryBuilders.rangeQuery(queryDes.getField()); 39 | } 40 | map.put(group, range); 41 | range.to(queryDes.getValue()); 42 | return range; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/mapping/handler/WildCardQueryHandler.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.mapping.handler; 2 | 3 | import com.elasticsearch.engine.base.holder.AbstractEsRequestHolder; 4 | import com.elasticsearch.engine.base.mapping.annotation.WildCard; 5 | import com.elasticsearch.engine.base.mapping.model.WildCardQueryBean; 6 | import com.elasticsearch.engine.base.model.annotion.EsQueryHandle; 7 | import com.elasticsearch.engine.base.model.domain.EsQueryFieldBean; 8 | import org.elasticsearch.index.query.QueryBuilder; 9 | import org.elasticsearch.index.query.QueryBuilders; 10 | import org.elasticsearch.index.query.WildcardQueryBuilder; 11 | 12 | /** 13 | * @author wanghuan 14 | * @description: WildCardQueryHandler 15 | * @date 2022-01-26 11:28 16 | */ 17 | @EsQueryHandle(WildCard.class) 18 | public class WildCardQueryHandler extends AbstractQueryHandler { 19 | 20 | @Override 21 | public QueryBuilder handle(EsQueryFieldBean queryDes, AbstractEsRequestHolder searchHelper) { 22 | String value = queryDes.getValue().toString(); 23 | WildCardQueryBean wildCardQueryBean = queryDes.getExtBean(); 24 | String tag = wildCardQueryBean.getTag(); 25 | WildcardQueryBuilder queryBuilder = QueryBuilders.wildcardQuery(queryDes.getField(), String.format(tag, value)); 26 | searchHelper.chain(queryBuilder); 27 | return queryBuilder; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/mapping/model/AggsQueryBean.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.mapping.model; 2 | 3 | import com.elasticsearch.engine.base.model.domain.AbstractQueryBean; 4 | import com.elasticsearch.engine.base.model.domain.EsQueryFieldBean; 5 | import lombok.Data; 6 | import org.elasticsearch.index.query.QueryBuilder; 7 | 8 | /** 9 | * @author wanghuan 10 | * @description: AggsQueryBean 11 | * @date 2022-01-26 11:28 12 | */ 13 | @Data 14 | public class AggsQueryBean extends AbstractQueryBean { 15 | 16 | private String type; 17 | 18 | private int size; 19 | 20 | @Override 21 | public void configQueryBuilder(EsQueryFieldBean queryDes, QueryBuilder queryBuilder) { 22 | 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/mapping/model/CollapseQueryBean.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.mapping.model; 2 | 3 | import com.elasticsearch.engine.base.model.domain.AbstractQueryBean; 4 | import com.elasticsearch.engine.base.model.domain.EsQueryFieldBean; 5 | import lombok.Data; 6 | import org.elasticsearch.index.query.QueryBuilder; 7 | 8 | /** 9 | * @author wanghuan 10 | * @description: CollapseQueryBean 11 | * @date 2022-01-26 11:28 12 | */ 13 | @Data 14 | public class CollapseQueryBean extends AbstractQueryBean { 15 | 16 | private int size; 17 | 18 | @Override 19 | public void configQueryBuilder(EsQueryFieldBean queryDes, QueryBuilder queryBuilder) { 20 | 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/mapping/model/ExistQueryBean.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.mapping.model; 2 | 3 | import com.elasticsearch.engine.base.model.domain.AbstractQueryBean; 4 | import com.elasticsearch.engine.base.model.domain.EsQueryFieldBean; 5 | import org.elasticsearch.index.query.ExistsQueryBuilder; 6 | 7 | /** 8 | * @author wanghuan 9 | * @description: ExistQueryBean 10 | * @date 2022-02-11 17:38 11 | */ 12 | public class ExistQueryBean extends AbstractQueryBean { 13 | 14 | /** 15 | * use this extend-config-bean to config given @QueryBuilder 16 | * 17 | * @param queryBuilder (ex: MatchQueryBuilder, MultiMatchQuery ...) 18 | */ 19 | @Override 20 | public void configQueryBuilder(EsQueryFieldBean queryDes, ExistsQueryBuilder queryBuilder) { 21 | 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/mapping/model/FromQueryBean.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.mapping.model; 2 | 3 | import com.elasticsearch.engine.base.model.constant.CommonConstant; 4 | import com.elasticsearch.engine.base.model.domain.AbstractQueryBean; 5 | import com.elasticsearch.engine.base.model.domain.EsQueryFieldBean; 6 | import lombok.Data; 7 | import org.apache.commons.lang3.StringUtils; 8 | import org.elasticsearch.index.query.RangeQueryBuilder; 9 | 10 | import java.time.LocalDateTime; 11 | 12 | /** 13 | * @author wanghuan 14 | * @description: FromQueryBean 15 | * @date 2022-02-07 10:12 16 | */ 17 | @Data 18 | public class FromQueryBean extends AbstractQueryBean { 19 | 20 | private String format; 21 | private String relation; 22 | private String timeZone; 23 | 24 | private int group; 25 | 26 | @Override 27 | public void configQueryBuilder(EsQueryFieldBean queryDes, RangeQueryBuilder queryBuilder) { 28 | boolean isLocalDateTime = LocalDateTime.class.isAssignableFrom(queryDes.getValue().getClass()); 29 | if (StringUtils.isNotBlank(format)) { 30 | queryBuilder.format(format); 31 | } else { 32 | if (isLocalDateTime) { 33 | queryBuilder.format(CommonConstant.DEFAULT_DATE_FORMAT); 34 | } 35 | } 36 | if (StringUtils.isNotBlank(relation)) { 37 | queryBuilder.relation(relation); 38 | } 39 | if (StringUtils.isNotBlank(timeZone)) { 40 | queryBuilder.timeZone(timeZone); 41 | } else { 42 | if (isLocalDateTime) { 43 | queryBuilder.timeZone(CommonConstant.DEFAULT_TIME_ZONE); 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/mapping/model/PageQueryBean.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.mapping.model; 2 | 3 | import com.elasticsearch.engine.base.model.domain.AbstractQueryBean; 4 | import com.elasticsearch.engine.base.model.domain.EsQueryFieldBean; 5 | import lombok.Data; 6 | import org.elasticsearch.index.query.QueryBuilder; 7 | 8 | /** 9 | * @author wanghuan 10 | * @description: PageQueryBean 11 | * @date 2022-01-26 11:28 12 | */ 13 | @Data 14 | public class PageQueryBean extends AbstractQueryBean { 15 | 16 | @Override 17 | public void configQueryBuilder(EsQueryFieldBean queryDes, QueryBuilder queryBuilder) { 18 | 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/mapping/model/PrefixQueryBean.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.mapping.model; 2 | 3 | import com.elasticsearch.engine.base.model.domain.AbstractQueryBean; 4 | import com.elasticsearch.engine.base.model.domain.EsQueryFieldBean; 5 | import org.elasticsearch.index.query.PrefixQueryBuilder; 6 | 7 | /** 8 | * @author wanghuan 9 | * @description: PrefixQueryBean 10 | * @date 2022-01-26 11:28 11 | */ 12 | public class PrefixQueryBean extends AbstractQueryBean { 13 | 14 | @Override 15 | public void configQueryBuilder(EsQueryFieldBean queryDes, PrefixQueryBuilder queryBuilder) { 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/mapping/model/RangeQueryBean.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.mapping.model; 2 | 3 | import com.elasticsearch.engine.base.mapping.model.extend.RangeParam; 4 | import com.elasticsearch.engine.base.model.constant.CommonConstant; 5 | import com.elasticsearch.engine.base.model.domain.AbstractQueryBean; 6 | import com.elasticsearch.engine.base.model.domain.EsQueryFieldBean; 7 | import lombok.Data; 8 | import org.apache.commons.lang3.StringUtils; 9 | import org.elasticsearch.index.query.RangeQueryBuilder; 10 | 11 | import java.time.LocalDateTime; 12 | import java.util.Objects; 13 | 14 | /** 15 | * @author wanghuan 16 | * @description: RangeQueryBean 17 | * @date 2022-01-26 11:28 18 | */ 19 | @Data 20 | public class RangeQueryBean extends AbstractQueryBean { 21 | 22 | /** 23 | * { 24 | * 25 | * @link com.example.springbootelasticsearch.common.engine.mapping.annotation.Range#LE_GE 26 | * } 27 | */ 28 | private String tag; 29 | private String format; 30 | private String relation; 31 | private String timeZone; 32 | 33 | @Override 34 | public void configQueryBuilder(EsQueryFieldBean queryDes, RangeQueryBuilder queryBuilder) { 35 | RangeParam rangeParam = (RangeParam) queryDes.getValue(); 36 | boolean leftIsLocalDateTime = Objects.nonNull(rangeParam.getLeft()) && LocalDateTime.class.isAssignableFrom(rangeParam.getLeft().getClass()); 37 | boolean rightIsLocalDateTime = Objects.nonNull(rangeParam.getRight()) && LocalDateTime.class.isAssignableFrom(rangeParam.getRight().getClass()); 38 | boolean isLocalDateTime = leftIsLocalDateTime || rightIsLocalDateTime; 39 | if (StringUtils.isNotBlank(format)) { 40 | queryBuilder.format(format); 41 | } else { 42 | if (isLocalDateTime) { 43 | queryBuilder.format(CommonConstant.DEFAULT_DATE_FORMAT); 44 | } 45 | } 46 | if (StringUtils.isNotBlank(relation)) { 47 | queryBuilder.relation(relation); 48 | } 49 | if (StringUtils.isNotBlank(timeZone)) { 50 | queryBuilder.timeZone(timeZone); 51 | } else { 52 | if (isLocalDateTime) { 53 | queryBuilder.timeZone(CommonConstant.DEFAULT_TIME_ZONE); 54 | } 55 | } 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/mapping/model/SortQueryBean.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.mapping.model; 2 | 3 | import com.elasticsearch.engine.base.model.domain.AbstractQueryBean; 4 | import com.elasticsearch.engine.base.model.domain.EsQueryFieldBean; 5 | import lombok.Data; 6 | import org.elasticsearch.index.query.QueryBuilder; 7 | import org.elasticsearch.search.sort.SortOrder; 8 | 9 | /** 10 | * @author wanghuan 11 | * @description: SortQueryBean 12 | * @date 2022-01-26 11:28 13 | */ 14 | @Data 15 | public class SortQueryBean extends AbstractQueryBean { 16 | 17 | private SortOrder type; 18 | 19 | private int order; 20 | 21 | 22 | @Override 23 | public void configQueryBuilder(EsQueryFieldBean queryDes, QueryBuilder queryBuilder) { 24 | 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/mapping/model/TermQueryBean.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.mapping.model; 2 | 3 | import com.elasticsearch.engine.base.model.domain.AbstractQueryBean; 4 | import com.elasticsearch.engine.base.model.domain.EsQueryFieldBean; 5 | import org.elasticsearch.index.query.TermQueryBuilder; 6 | 7 | /** 8 | * @author wanghuan 9 | * @description: TermQueryBean 10 | * @date 2022-01-26 11:28 11 | */ 12 | public class TermQueryBean extends AbstractQueryBean { 13 | 14 | @Override 15 | public void configQueryBuilder(EsQueryFieldBean queryDes, TermQueryBuilder queryBuilder) { 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/mapping/model/TermsQueryBean.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.mapping.model; 2 | 3 | import com.elasticsearch.engine.base.model.domain.AbstractQueryBean; 4 | import com.elasticsearch.engine.base.model.domain.EsQueryFieldBean; 5 | import org.elasticsearch.index.query.TermsQueryBuilder; 6 | 7 | /** 8 | * @author wanghuan 9 | * @description: TermsQueryBean 10 | * @date 2022-01-26 11:28 11 | */ 12 | public class TermsQueryBean extends AbstractQueryBean { 13 | 14 | @Override 15 | public void configQueryBuilder(EsQueryFieldBean queryDes, TermsQueryBuilder queryBuilder) { 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/mapping/model/ToQueryBean.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.mapping.model; 2 | 3 | import com.elasticsearch.engine.base.model.constant.CommonConstant; 4 | import com.elasticsearch.engine.base.model.domain.AbstractQueryBean; 5 | import com.elasticsearch.engine.base.model.domain.EsQueryFieldBean; 6 | import lombok.Data; 7 | import org.apache.commons.lang3.StringUtils; 8 | import org.elasticsearch.index.query.RangeQueryBuilder; 9 | 10 | import java.time.LocalDateTime; 11 | 12 | /** 13 | * @author wanghuan 14 | * @description: FromQueryBean 15 | * @date 2022-02-07 10:12 16 | */ 17 | @Data 18 | public class ToQueryBean extends AbstractQueryBean { 19 | 20 | private String format; 21 | private String relation; 22 | private String timeZone; 23 | 24 | private int group; 25 | 26 | @Override 27 | public void configQueryBuilder(EsQueryFieldBean queryDes, RangeQueryBuilder queryBuilder) { 28 | boolean isLocalDateTime = LocalDateTime.class.isAssignableFrom(queryDes.getValue().getClass()); 29 | if (StringUtils.isNotBlank(format)) { 30 | queryBuilder.format(format); 31 | } else { 32 | if (isLocalDateTime) { 33 | queryBuilder.format(CommonConstant.DEFAULT_DATE_FORMAT); 34 | } 35 | } 36 | if (StringUtils.isNotBlank(relation)) { 37 | queryBuilder.relation(relation); 38 | } 39 | if (StringUtils.isNotBlank(timeZone)) { 40 | queryBuilder.timeZone(timeZone); 41 | } else { 42 | if (isLocalDateTime) { 43 | queryBuilder.timeZone(CommonConstant.DEFAULT_TIME_ZONE); 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/mapping/model/WildCardQueryBean.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.mapping.model; 2 | 3 | import com.elasticsearch.engine.base.model.domain.AbstractQueryBean; 4 | import com.elasticsearch.engine.base.model.domain.EsQueryFieldBean; 5 | import lombok.Data; 6 | import org.elasticsearch.index.query.WildcardQueryBuilder; 7 | 8 | /** 9 | * @author wanghuan 10 | * @description: WildCardQueryBean 11 | * @date 2022-01-26 11:28 12 | */ 13 | @Data 14 | public class WildCardQueryBean extends AbstractQueryBean { 15 | 16 | /** 17 | * 匹配类型 18 | * 19 | * @see com.example.springbootelasticsearch.common.engine.mapping.annotation.WildCard 20 | */ 21 | private String tag; 22 | 23 | @Override 24 | public void configQueryBuilder(EsQueryFieldBean queryDes, WildcardQueryBuilder queryBuilder) { 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/mapping/model/extend/PageParam.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.mapping.model.extend; 2 | 3 | import com.elasticsearch.engine.base.model.domain.EsComplexParam; 4 | import lombok.Data; 5 | import org.elasticsearch.search.sort.SortOrder; 6 | 7 | import java.util.LinkedHashMap; 8 | 9 | /** 10 | * @author wanghuan 11 | * @description: PageParam 12 | * @date 2022-01-26 11:28 13 | */ 14 | @Data 15 | public class PageParam implements EsComplexParam { 16 | 17 | /** 18 | * 当前页码 19 | */ 20 | private int currentPage = 1; 21 | 22 | private int pageSize = 10; 23 | 24 | private LinkedHashMap orderMap; 25 | 26 | public static PageBuilder builderPage() { 27 | return new PageBuilder(); 28 | } 29 | 30 | public static OrderBuilder builderOrder() { 31 | return new OrderBuilder(); 32 | } 33 | 34 | public int getExclude() { 35 | return Math.max((currentPage - 1), 0) * pageSize; 36 | } 37 | 38 | public static class PageBuilder { 39 | 40 | private int currentPage; 41 | 42 | private int pageSize; 43 | 44 | private LinkedHashMap orderMap = new LinkedHashMap<>(); 45 | 46 | public PageBuilder currentPage(int currentPage) { 47 | this.currentPage = currentPage; 48 | return this; 49 | } 50 | 51 | public PageBuilder pageSize(int pageSize) { 52 | this.pageSize = pageSize; 53 | return this; 54 | } 55 | 56 | public PageBuilder order(OrderBuilder order) { 57 | this.orderMap.put(order.orderFiled, order.orderType); 58 | return this; 59 | } 60 | 61 | public PageParam build() { 62 | PageParam param = new PageParam(); 63 | param.setCurrentPage(this.currentPage); 64 | param.setPageSize(this.pageSize); 65 | param.setOrderMap(orderMap); 66 | return param; 67 | } 68 | } 69 | 70 | public static class OrderBuilder { 71 | 72 | private String orderFiled; 73 | 74 | private SortOrder orderType; 75 | 76 | public OrderBuilder orderFiled(String orderFiled) { 77 | this.orderFiled = orderFiled; 78 | return this; 79 | } 80 | 81 | public OrderBuilder orderType(SortOrder orderType) { 82 | this.orderType = orderType; 83 | return this; 84 | } 85 | 86 | public OrderBuilder build() { 87 | OrderBuilder param = new OrderBuilder(); 88 | param.orderFiled(this.orderFiled); 89 | param.orderType(this.orderType); 90 | return param; 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/mapping/model/extend/RangeParam.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.mapping.model.extend; 2 | 3 | 4 | import com.elasticsearch.engine.base.model.domain.EsComplexParam; 5 | import lombok.Data; 6 | 7 | import javax.annotation.Nullable; 8 | 9 | /** 10 | * @author wanghuan 11 | * @description: RangeParam 12 | * @date 2022-01-26 11:28 13 | */ 14 | @Data 15 | public class RangeParam implements EsComplexParam { 16 | /** 17 | * from 18 | */ 19 | @Nullable 20 | private Object left; 21 | 22 | /** 23 | * to 24 | */ 25 | @Nullable 26 | private Object right; 27 | 28 | public static RangeBuilder builder() { 29 | return new RangeBuilder(); 30 | } 31 | 32 | public static class RangeBuilder { 33 | 34 | private Object left; 35 | 36 | private Object right; 37 | 38 | public RangeBuilder left(Object left) { 39 | this.left = left; 40 | return this; 41 | } 42 | 43 | public RangeBuilder right(Object right) { 44 | this.right = right; 45 | return this; 46 | } 47 | 48 | public RangeParam build() { 49 | RangeParam param = new RangeParam(); 50 | param.setLeft(this.left); 51 | param.setRight(this.right); 52 | return param; 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/mapping/model/extend/SignParam.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.mapping.model.extend; 2 | 3 | 4 | import com.elasticsearch.engine.base.model.domain.EsComplexParam; 5 | 6 | /** 7 | * @author wanghuan 8 | * @description: SignParam 标记字段可设置的类型 9 | * @date 2022-03-29 14:29 10 | */ 11 | public class SignParam implements EsComplexParam { 12 | public static SignParam builder() { 13 | return new SignParam(); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/model/annotion/Base.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.model.annotion; 2 | 3 | 4 | import com.elasticsearch.engine.base.model.emenu.EsConnector; 5 | 6 | import java.lang.annotation.*; 7 | 8 | 9 | /** 10 | * @author wanghuan 11 | * @description: Base 12 | * @date 2022-01-26 11:28 13 | */ 14 | @Inherited 15 | @Documented 16 | @Target(ElementType.FIELD) 17 | @Retention(RetentionPolicy.RUNTIME) 18 | public @interface Base { 19 | 20 | /** 21 | * filed name 22 | * return 23 | */ 24 | String value() default ""; 25 | 26 | /** 27 | * filed pase order 28 | * 可以用于多排序时指定字段排序顺序 29 | * 30 | * @return 31 | */ 32 | int order() default 0; 33 | 34 | /** 35 | * connector (boolQuery: must,must_not,should,filter) 36 | * return 37 | */ 38 | EsConnector connect() default EsConnector.FILTER; 39 | 40 | 41 | } 42 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/model/annotion/ESColumn.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.model.annotion; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * @author wanghuan 7 | * @description ESColumn 8 | * @date 2022/7/15 17:03 9 | */ 10 | @Retention(RetentionPolicy.RUNTIME) 11 | @Target({ElementType.FIELD, ElementType.ANNOTATION_TYPE}) 12 | @Documented 13 | public @interface ESColumn { 14 | 15 | String table() default ""; 16 | 17 | String sqlColumn() default ""; 18 | 19 | String esColumn() default ""; 20 | } 21 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/model/annotion/EsHelperProxy.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.model.annotion; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * @author wanghuan 7 | * @description EsHelperProxy 8 | * @mail 958721894@qq.com 9 | * @date 2022/6/9 14:09 10 | */ 11 | @Inherited 12 | @Documented 13 | @Retention(RetentionPolicy.RUNTIME) 14 | @Target({ElementType.TYPE}) 15 | public @interface EsHelperProxy { 16 | 17 | /** 18 | * When phrase query-Define bean will visit it's parent 19 | */ 20 | boolean visitParent() default true; 21 | 22 | } 23 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/model/annotion/EsQuery.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.model.annotion; 2 | 3 | 4 | import com.elasticsearch.engine.base.common.proxy.enums.EsQueryType; 5 | 6 | import java.lang.annotation.*; 7 | 8 | 9 | /** 10 | * @author wanghuan 11 | * @description: EsQuery 12 | * @date 2022-01-26 11:28 13 | */ 14 | @Retention(RetentionPolicy.RUNTIME) 15 | @Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE}) 16 | @Documented 17 | public @interface EsQuery { 18 | 19 | /** 20 | * 查询语句 21 | * 22 | * @return 23 | */ 24 | String value() default ""; 25 | 26 | /** 27 | * 查询类型 28 | * 29 | * @return 30 | */ 31 | EsQueryType queryType() default EsQueryType.SQL; 32 | 33 | } 34 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/model/annotion/EsQueryHandle.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.model.annotion; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * @author wanghuan 7 | * @date 2022-01-26 11:28 8 | */ 9 | @Inherited 10 | @Documented 11 | @Target(ElementType.TYPE) 12 | @Retention(RetentionPolicy.RUNTIME) 13 | public @interface EsQueryHandle { 14 | 15 | String queryType() default ""; 16 | 17 | Class value() default Annotation.class; 18 | } 19 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/model/annotion/EsQueryIndex.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.model.annotion; 2 | 3 | 4 | import com.elasticsearch.engine.base.model.emenu.QueryModel; 5 | 6 | import java.lang.annotation.*; 7 | 8 | /** 9 | * Define the esQueryHolder's index-name, queryModel ... information 10 | * 11 | * @author wanghuan 12 | * @date 2022-01-26 11:28 13 | */ 14 | @Documented 15 | @Target(ElementType.TYPE) 16 | @Retention(RetentionPolicy.RUNTIME) 17 | public @interface EsQueryIndex { 18 | 19 | /** 20 | * 查询索引 21 | * 支持直接声明索引名机配置中心配置 22 | * 例如: 23 | * 24 | * @EsQueryIndex(index = "supplier_item_spare") 25 | * @EsQueryIndex(index = "${es.index.name}") 26 | * @EsQueryIndex(index = "${es.index.name:supplier_item_spare}") 27 | */ 28 | String value(); 29 | 30 | /** 31 | * 查询方式 默认bool 32 | * query model {@link QueryModel} (required) 33 | * 34 | * @see QueryModel 35 | * return 36 | */ 37 | QueryModel model() default QueryModel.BOOL; 38 | 39 | /** 40 | * exclude unuseful fields from ES 41 | * return 42 | */ 43 | String[] include() default {}; 44 | 45 | /** 46 | * exclude unuseful fields from ES 47 | * return 48 | */ 49 | String[] exclude() default {}; 50 | 51 | 52 | } 53 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/model/annotion/Ignore.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.model.annotion; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * @author wanghuan 7 | * @description: Ignore 8 | * 表示忽略某个字段 ,被忽略的字段 无论属性值是否为空, 查询时都不会被解析 9 | * @date 2022-01-26 11:28 10 | */ 11 | @Inherited 12 | @Documented 13 | @Target(ElementType.FIELD) 14 | @Retention(RetentionPolicy.RUNTIME) 15 | public @interface Ignore { 16 | } 17 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/model/annotion/MethodQuery.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.model.annotion; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * @author wanghuan 7 | * @description MethodQuery 8 | * @mail 958721894@qq.com 9 | * @date 2022/6/15 08:54 10 | */ 11 | @Inherited 12 | @Documented 13 | @Target({ElementType.ANNOTATION_TYPE}) 14 | @Retention(RetentionPolicy.RUNTIME) 15 | public @interface MethodQuery { 16 | } 17 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/model/annotion/Nested.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.model.annotion; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * @author wanghuan 7 | * @description: 解析嵌套实体类需要添加该注解 8 | * @date 2022-02-10 11:09 9 | */ 10 | @Inherited 11 | @Documented 12 | @Target(ElementType.FIELD) 13 | @Retention(RetentionPolicy.RUNTIME) 14 | public @interface Nested { 15 | } 16 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/model/annotion/Query.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.model.annotion; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * @author wanghuan 7 | * @description: Query 8 | * @date 2022-01-26 11:28 9 | */ 10 | @Inherited 11 | @Documented 12 | @Target({ElementType.ANNOTATION_TYPE}) 13 | @Retention(RetentionPolicy.RUNTIME) 14 | public @interface Query { 15 | } 16 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/model/annotion/Sign.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.model.annotion; 2 | 3 | import java.lang.annotation.*; 4 | import java.time.LocalDate; 5 | import java.time.LocalDateTime; 6 | 7 | /** 8 | * @author wanghuan 9 | * @description: Sign 标记注解 10 | * 标记注解不解析value,只解析注解值 11 | * 需要设置 value值不为空,查询条件才会生效, 但是设置的value不会被解析,仅仅标记是否添加该条件 12 | * 所以value可以任意设置, 但是注意 string 不能为空串,数组类型不能为null 13 | * @date 2022-01-26 11:28 14 | */ 15 | @Inherited 16 | @Documented 17 | @Target({ElementType.ANNOTATION_TYPE}) 18 | @Retention(RetentionPolicy.RUNTIME) 19 | public @interface Sign { 20 | 21 | /** 22 | * Integer default value 23 | */ 24 | Integer DEFAULT_INTER = 1; 25 | /** 26 | * Long default value 27 | */ 28 | Long DEFAULT_LONG = 1L; 29 | /** 30 | * String default value 31 | */ 32 | String DEFAULT_STRING = "1"; 33 | /** 34 | * LocalDateTime default value 35 | */ 36 | LocalDateTime DEFAULT_LOCAL_DATE_TIME = LocalDateTime.now(); 37 | /** 38 | * LocalDate default value 39 | */ 40 | LocalDate DEFAULT_LOCAL_DATE = LocalDate.now(); 41 | } 42 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/model/constant/CommonConstant.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.model.constant; 2 | 3 | /** 4 | * @author wanghuan 5 | * @description: es content 6 | * @date 2021-09-29 7 | * @time 10:21 8 | */ 9 | public class CommonConstant { 10 | 11 | /** 12 | * string里面的特殊字符 13 | */ 14 | public static final String SPECIAL_CHAR = "\\p{C}"; 15 | 16 | /** 17 | * 记录代理类的名称 18 | */ 19 | public static final String INTERFACE_METHOD_NAME = "method"; 20 | 21 | /** 22 | * banner文件路径 23 | */ 24 | public final static String BANNER_PATH = "engine-banner.txt"; 25 | 26 | /** 27 | * version文件路径 28 | */ 29 | public final static String VERSION_PATH = "elasticseach-engine.properties"; 30 | 31 | /** 32 | * 查询sql 33 | */ 34 | public static final String BACK_QUERY_SQL = "back_sql"; 35 | 36 | /** 37 | * 存储jpa未绑定参数前的sql 38 | */ 39 | public static final String JPA_NATIVE_SQL = "jpa_native_sql"; 40 | 41 | /** 42 | * 查询sql前缀 小写 43 | */ 44 | public static final String SELECT_SQL_PREFIX_LOWER = "select"; 45 | 46 | /** 47 | * 查询sql前缀 大写 48 | */ 49 | public static final String SELECT_SQL_PREFIX_UPPER = "SELECT"; 50 | 51 | /** 52 | * es查询标记 53 | */ 54 | public static final String IS_ES_QUERY = "is_es_query"; 55 | 56 | /** 57 | * es默认连接 58 | */ 59 | public static final String DEFAULT_ES_HOST = "127.0.0.1:9200"; 60 | 61 | /** 62 | * 没有设置排序时 默认的 preference 参数防止分片时多次查询返回结果排序不一致的问题 63 | */ 64 | public static final String DEFAULT_PREFERENCE = "elasticseach-engine"; 65 | 66 | /** 67 | * es客户端版本为7, es版本为6的格式为 yyyy-MM-dd'T'HH:mm:ss.SSS 68 | * 日期查询默认的format时间格式 69 | */ 70 | public static final String DEFAULT_DATE_FORMAT = "8uuuu-MM-dd'T'HH:mm:ss.SSS'Z'"; 71 | 72 | /** 73 | * es客户端版本为7, es版本为6的格式为 GMT+8 74 | * 日期查询默认的时间时区 75 | */ 76 | public static final String DEFAULT_TIME_ZONE = "+08:00"; 77 | 78 | /** 79 | * jooq BETWEEN 格式 80 | */ 81 | public static final String JOOQ_SQL_BETWEEN = "between {ts"; 82 | 83 | /** 84 | * jooq BETWEEN 前缀 85 | */ 86 | public static final String JOOQ_SQL_BETWEEN_PREFIX = "\\{ts"; 87 | 88 | /** 89 | * jooq BETWEEN 后缀 90 | */ 91 | public static final String JOOQ_SQL_BETWEEN_SUFFIX = "\\}"; 92 | 93 | } 94 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/model/constant/EsConstant.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.model.constant; 2 | 3 | /** 4 | * @author wanghuan 5 | * @description: es content 6 | * @date 2021-09-29 7 | * @time 10:21 8 | */ 9 | public interface EsConstant { 10 | 11 | /** 12 | * es 分组桶返回size 13 | */ 14 | Integer ES_AGG_BUCKETS_SIZE = 2000; 15 | 16 | /** 17 | * es 通用 查询分组别名 18 | */ 19 | String AGG = "es_agg"; 20 | String SUM = "es_sum"; 21 | String ES_VARIANCE = "es_variance"; 22 | String ES_SQUARE = "es_square"; 23 | 24 | /** 25 | * 字符串0 26 | */ 27 | String STRING_ZERO = "0"; 28 | 29 | 30 | } 31 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/model/domain/AbstractQueryBean.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.model.domain; 2 | 3 | /** 4 | * @author wanghuan 5 | * @description: Define base-query-information 6 | * @date 2022-01-26 11:28 7 | */ 8 | 9 | import org.elasticsearch.index.query.QueryBuilder; 10 | 11 | public abstract class AbstractQueryBean { 12 | 13 | 14 | /** 15 | * use this extend-config-bean to config given @QueryBuilder 16 | * 17 | * @param queryBuilder (ex: MatchQueryBuilder, MultiMatchQuery ...) 18 | */ 19 | public abstract void configQueryBuilder(EsQueryFieldBean queryDes, T queryBuilder); 20 | 21 | 22 | } 23 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/model/domain/BackDto.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.model.domain; 2 | 3 | import lombok.AllArgsConstructor; 4 | import lombok.Builder; 5 | import lombok.Data; 6 | import lombok.NoArgsConstructor; 7 | 8 | /** 9 | * @author wanghuan 10 | * @description BackDto 11 | * @mail 958721894@qq.com 12 | * @date 2022-06-05 15:44 13 | */ 14 | @Data 15 | @Builder 16 | @AllArgsConstructor 17 | @NoArgsConstructor 18 | public class BackDto { 19 | 20 | private String tableName; 21 | private String backColumn; 22 | private Class backColumnTyp; 23 | 24 | } 25 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/model/domain/BaseEsRepository.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.model.domain; 2 | 3 | /** 4 | * @author wanghuan 5 | * @description: BaseESRepository 6 | * @date 2022-04-10 10:05 7 | */ 8 | public interface BaseEsRepository { 9 | } 10 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/model/domain/BaseHit.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.model.domain; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.List; 6 | import java.util.Map; 7 | 8 | /** 9 | * @author wanghuan 10 | * @description: //处理通用参数, doc_id, 深度分页id,高亮显示等 11 | * @date 2022-02-11 17:00 12 | */ 13 | @Data 14 | public class BaseHit { 15 | 16 | private String docId; 17 | 18 | private Float hitScore; 19 | 20 | private Map> highLightMap; 21 | } 22 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/model/domain/BaseResp.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.model.domain; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | import java.util.List; 7 | 8 | /** 9 | * @author wanghuan 10 | * @description: BaseResp 11 | * @date 2022-01-26 11:28 12 | */ 13 | @Data 14 | public class BaseResp implements Serializable { 15 | 16 | /** 17 | * 查询结果的总记录数 18 | */ 19 | private Long totalHit; 20 | 21 | /** 22 | * 默认返回List 结果 23 | */ 24 | private List records; 25 | 26 | /** 27 | * 自定义的result 28 | * T可以定义为任意Object, List , Map 等 29 | */ 30 | private T result; 31 | } 32 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/model/domain/DefaultAggResp.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.model.domain; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * @author wanghuan 7 | * @description: 默认的分组查询结果 8 | * @date 2022-01-28 15:55 9 | */ 10 | @Data 11 | public class DefaultAggResp implements DefaultResp{ 12 | 13 | private String key; 14 | 15 | private Long count; 16 | } 17 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/model/domain/DefaultQueryModel.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.model.domain; 2 | 3 | import com.elasticsearch.engine.base.mapping.annotation.PageAndOrder; 4 | import com.elasticsearch.engine.base.mapping.annotation.Term; 5 | import com.elasticsearch.engine.base.mapping.annotation.Terms; 6 | import lombok.Data; 7 | 8 | /** 9 | * @author wanghuan 10 | * @description: DefaultQueryModel 11 | * @date 2022-01t20 2:20 12 | */ 13 | @Data 14 | public class DefaultQueryModel { 15 | 16 | @Term 17 | public String term; 18 | 19 | @Terms 20 | public String terms; 21 | 22 | @PageAndOrder 23 | public String pageAndOrder; 24 | 25 | public static DefaultQueryModel build() { 26 | return new DefaultQueryModel(); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/model/domain/DefaultResp.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.model.domain; 2 | 3 | /** 4 | * @author wanghuan 5 | * @description DefaultResp 6 | * @mail 958721894@qq.com 7 | * @date 2022/6/2 12:08 8 | */ 9 | public interface DefaultResp { 10 | } 11 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/model/domain/EsComplexParam.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.model.domain; 2 | 3 | /** 4 | * relate parameter in #extend package 5 | * ex: 6 | * {@link com.example.springbootelasticsearch.common.engine.mapping.model.extend.PageParam} 7 | * define the range param 8 | * 9 | * @author wanghuan 10 | * @date 2022-01-26 11:28 11 | * @email 1078481395@qq.com 12 | */ 13 | public interface EsComplexParam { 14 | 15 | 16 | } 17 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/model/domain/EsQueryFieldBean.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.model.domain; 2 | 3 | import com.elasticsearch.engine.base.model.emenu.EsConnector; 4 | import lombok.Data; 5 | import lombok.extern.slf4j.Slf4j; 6 | 7 | import java.io.Serializable; 8 | import java.lang.annotation.Annotation; 9 | 10 | /** 11 | * @author wanghuan 12 | * @description: EsQueryFieldBean 13 | * @date 2022-01-26 11:28 14 | */ 15 | @Slf4j 16 | @Data 17 | public class EsQueryFieldBean implements Serializable { 18 | 19 | /** 20 | * the field be queried 21 | */ 22 | private String field; 23 | 24 | /** 25 | * the val of query for 26 | */ 27 | private Object value; 28 | 29 | /** 30 | * query Type like Match,Fuzzy,Term ... 31 | */ 32 | private String queryType; 33 | 34 | /** 35 | * connector of multi-query (must, should, must not, filter) 36 | */ 37 | private EsConnector logicConnector; 38 | 39 | /** 40 | * extend query bean 41 | */ 42 | private T extBean; 43 | 44 | /** 45 | * annotation that annotated by @Query 46 | */ 47 | private Annotation extAnnotation; 48 | 49 | /** 50 | * 字段解析顺序 51 | */ 52 | private Integer order = 0; 53 | } 54 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/model/domain/EsQueryIndexBean.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.model.domain; 2 | 3 | 4 | import com.elasticsearch.engine.base.model.emenu.QueryModel; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Data; 7 | 8 | /** 9 | * @author wanghuan 10 | * @description: EsQueryIndexBean 11 | * @date 2022-01-26 11:28 12 | */ 13 | @Data 14 | @AllArgsConstructor 15 | public class EsQueryIndexBean { 16 | 17 | /** 18 | * 索引名称 19 | */ 20 | private String indexName; 21 | 22 | /** 23 | * query 最外层结构体 24 | */ 25 | private QueryModel esQueryModel; 26 | 27 | /** 28 | * 包含的返回字段 29 | */ 30 | private String[] includeFields; 31 | 32 | /** 33 | * 排除的返回字段 34 | */ 35 | private String[] excludeFields; 36 | 37 | } 38 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/model/domain/ParamParserResultModel.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.model.domain; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | /** 9 | * @author wanghuan 10 | * @description: 查询对象解析结果 11 | * @date 2022-04-02 08:06 12 | */ 13 | @Data 14 | public class ParamParserResultModel { 15 | 16 | /** 17 | * 查询注解解析 18 | */ 19 | List queryDesList; 20 | 21 | /** 22 | * 自定义嵌套查询扩展解析 23 | */ 24 | List requestHooks = new ArrayList<>(); 25 | 26 | 27 | } 28 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/model/domain/SqlErrorResponse.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.model.domain; 2 | 3 | import lombok.Data; 4 | 5 | /** 6 | * @author wanghuan 7 | * @description: sql查询异常响应 8 | * @date 2022-05-13 22:24 9 | */ 10 | @Data 11 | public class SqlErrorResponse { 12 | 13 | /** 14 | * 错误信息 15 | */ 16 | private ErrorDTO error; 17 | 18 | /** 19 | * 响应状态 20 | */ 21 | private Integer status; 22 | 23 | 24 | @Data 25 | public static class ErrorDTO{ 26 | String type; 27 | String reason; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/model/domain/SqlResponse.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.model.domain; 2 | 3 | import com.fasterxml.jackson.annotation.JsonProperty; 4 | import lombok.Data; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * @author wanghuan 10 | * @description SqlResponse 11 | * @mail 958721894@qq.com 12 | * @date 2022/6/18 09:54 13 | */ 14 | @Data 15 | public class SqlResponse extends SqlErrorResponse { 16 | @JsonProperty("columns") 17 | private List columns; 18 | @JsonProperty("rows") 19 | private List> rows; 20 | 21 | 22 | @Data 23 | public static class ColumnsDTO { 24 | @JsonProperty("name") 25 | private String name; 26 | @JsonProperty("type") 27 | private String type; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/model/emenu/DataType.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.model.emenu; 2 | 3 | import java.util.Objects; 4 | 5 | /** 6 | * @author wanghuan 7 | * @description DataType 8 | * @mail 958721894@qq.com 9 | * @date 2022/6/18 09:53 10 | */ 11 | public enum DataType { 12 | /** 13 | * 14 | */ 15 | keyword_type, text_type, byte_type, short_type, integer_type, long_type, float_type, double_type, boolean_type, date_type, nested_type, geo_point_type; 16 | 17 | 18 | public static DataType getDataTypeByStr(String str) { 19 | if (Objects.equals(str,"keyword")) { 20 | return keyword_type; 21 | } else if (Objects.equals(str,"text")) { 22 | return text_type; 23 | } else if (Objects.equals(str,"byte")) { 24 | return byte_type; 25 | } else if (Objects.equals(str,"short")) { 26 | return short_type; 27 | } else if (Objects.equals(str,"integer")) { 28 | return integer_type; 29 | } else if (Objects.equals(str,"long")) { 30 | return long_type; 31 | } else if (Objects.equals(str,"float")) { 32 | return float_type; 33 | } else if (Objects.equals(str,"double")) { 34 | return double_type; 35 | } else if (Objects.equals(str,"boolean")) { 36 | return boolean_type; 37 | } else if (Objects.equals(str,"date") || Objects.equals(str,"datetime")) { 38 | return date_type; 39 | } else { 40 | return text_type; 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/model/emenu/EsConnector.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.model.emenu; 2 | 3 | /** 4 | * 描述 ES 涉及的查询逻辑连接符 5 | * 6 | * @author wanghuan 7 | * @date 2022-01-26 11:28 8 | */ 9 | public enum EsConnector { 10 | 11 | /** 12 | * ---- bool query 13 | */ 14 | MUST, 15 | MUST_NOT, 16 | FILTER, 17 | /** 18 | * 不会影响过滤, 只影响文档评分 19 | */ 20 | SHOULD 21 | 22 | } 23 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/model/emenu/EsVersionConstant.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.model.emenu; 2 | 3 | import com.fasterxml.jackson.annotation.JsonCreator; 4 | import com.fasterxml.jackson.annotation.JsonValue; 5 | import lombok.Getter; 6 | import org.apache.commons.lang3.StringUtils; 7 | 8 | import java.util.Arrays; 9 | import java.util.Optional; 10 | 11 | /** 12 | * @author wanghuan 13 | * @description: ROOD 14 | * @date 2022-04-28 17:35 15 | */ 16 | @Getter 17 | public enum EsVersionConstant { 18 | 19 | /** 20 | * GMT+8 21 | */ 22 | ES_VERSION_6(6, "/_xpack/sql?format=", "/_xpack/sql/translate?format="), 23 | ES_VERSION_7(7, "/_sql?format=", "/_sql/translate?format="); 24 | 25 | private Integer version; 26 | private String sqlQueryPrefix; 27 | private String sqlTranslatePrefix; 28 | 29 | EsVersionConstant(Integer version, String sqlQueryPrefix, String sqlTranslatePrefix) { 30 | this.version = version; 31 | this.sqlQueryPrefix = sqlQueryPrefix; 32 | this.sqlTranslatePrefix = sqlTranslatePrefix; 33 | } 34 | 35 | public static String getSqlQueryPrefix(Integer version) { 36 | Optional assetPowerBankItemChangeEnum = Arrays.stream(EsVersionConstant.values()) 37 | .filter(c -> c.getVersion().equals(version)).findFirst(); 38 | return assetPowerBankItemChangeEnum.map(EsVersionConstant::getSqlQueryPrefix).orElse(StringUtils.EMPTY); 39 | } 40 | 41 | @JsonCreator 42 | public static EsVersionConstant of(Integer version) { 43 | Optional assetPowerBankItemChangeEnum = Arrays.stream(EsVersionConstant.values()) 44 | .filter(c -> c.getVersion().equals(version)).findFirst(); 45 | return assetPowerBankItemChangeEnum.orElse(null); 46 | } 47 | 48 | @JsonValue 49 | public Integer getVersion() { 50 | return version; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/model/emenu/JsonNamingStrategy.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.model.emenu; 2 | 3 | /** 4 | * @author wanghuan 5 | * @description: JsonNamingStrategy 6 | * @date 2022-04-28 11:31 7 | */ 8 | public enum JsonNamingStrategy { 9 | 10 | // SNAKE_CASE表示下划线 11 | SNAKE_CASE, 12 | // LOWER_CAMEL_CASE表示首字母小写驼峰 13 | LOWER_CAMEL_CASE 14 | } 15 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/model/emenu/QueryModel.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.model.emenu; 2 | 3 | /** 4 | * query 最外层查询结构 默认BOOL 5 | *

6 | * { 7 | * "query": { 8 | * "bool": {}, 9 | * "exists": {} 10 | * } 11 | * } 12 | * 13 | * @author wanghuan 14 | * @date 2022-01-26 11:28 15 | */ 16 | public enum QueryModel { 17 | 18 | /** 19 | * bool 组合查询 20 | */ 21 | BOOL, 22 | DIS_MAX, 23 | COMMON, 24 | EXISTS, 25 | 26 | } 27 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/model/emenu/SortType.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.model.emenu; 2 | 3 | /** 4 | * @author wanghuan 5 | * @description: 分组排序类型 6 | * @date 2022-01-26 11:28 7 | */ 8 | public enum SortType { 9 | 10 | /** 11 | * 按照分组的key 正序排序 12 | */ 13 | KEY_ASC("KEY_ASC"), 14 | /** 15 | * 按照分组的key 倒序排序 16 | */ 17 | KEY_DESC("KEY_DESC"), 18 | /** 19 | * 按照分组的count 正序排序 20 | */ 21 | COUNT_ASC("COUNT_ASC"), 22 | /** 23 | * 按照分组的count 倒序排序 24 | */ 25 | COUNT_DESC("COUNT_DESC"); 26 | 27 | private String name; 28 | 29 | SortType(String name) { 30 | this.name = name; 31 | } 32 | 33 | public String getName() { 34 | return name; 35 | } 36 | 37 | 38 | } 39 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/model/emenu/SqlFormat.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.model.emenu; 2 | 3 | /** 4 | * @program: esclientrhl 5 | * @description: sql请求返回类型 6 | * @author: X-Pacific zhang 7 | * @create: 2019-10-10 13:02 8 | **/ 9 | public enum SqlFormat { 10 | /** 11 | * 12 | */ 13 | CSV("csv", "text/csv"), 14 | JSON("json", "application/json"), 15 | TSV("tsv", "text/tab-separated-values"), 16 | TXT("txt", "text/plain"), 17 | YAML("yaml", "application/yaml"), 18 | CBOR("cbor", "application/cbor"), 19 | SMILE("smile", "application/smile"); 20 | 21 | 22 | private String format; 23 | private String acceptHttpHeader; 24 | 25 | private SqlFormat(String format, String acceptHttpHeader) { 26 | this.format = format; 27 | this.acceptHttpHeader = acceptHttpHeader; 28 | } 29 | 30 | 31 | @Override 32 | public String toString() { 33 | return this.format; 34 | } 35 | 36 | 37 | public String getFormat() { 38 | return format; 39 | } 40 | 41 | public void setFormat(String format) { 42 | this.format = format; 43 | } 44 | 45 | public String getAcceptHttpHeader() { 46 | return acceptHttpHeader; 47 | } 48 | 49 | public void setAcceptHttpHeader(String acceptHttpHeader) { 50 | this.acceptHttpHeader = acceptHttpHeader; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/model/emenu/SqlParamParse.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.model.emenu; 2 | 3 | import lombok.Getter; 4 | 5 | /** 6 | * @author wanghuan 7 | * @description: ROOD 8 | * @date 2022-05-29 21:36 9 | */ 10 | @Getter 11 | public enum SqlParamParse { 12 | 13 | /** 14 | * 15 | */ 16 | JAP_SQL_PARAM("jpa", "?", "\\?", "", "","?"), 17 | ANN_SQL_PARAM("ann", "#{%s}", "\\#\\{%s\\}", "${%s}","\\$\\{%s\\}", "#{"); 18 | 19 | 20 | private String type; 21 | private String formatStr; 22 | private String regexStr; 23 | private String likeformatStr; 24 | private String likeRegexStr; 25 | private String placeHolder; 26 | 27 | SqlParamParse(String type, String formatStr, String regexStr, String likeformatStr, String likeRegexStr, String placeHolder) { 28 | this.type = type; 29 | this.formatStr = formatStr; 30 | this.regexStr = regexStr; 31 | this.likeformatStr = likeformatStr; 32 | this.likeRegexStr = likeRegexStr; 33 | this.placeHolder = placeHolder; 34 | } 35 | 36 | /** 37 | * 替换字符串中的. 38 | * 39 | * @param regexStr 40 | * @return 41 | */ 42 | public static String getRegex(String regexStr) { 43 | return regexStr.replaceAll("\\.", "\\\\."); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/model/exception/EsEngineConfigException.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.model.exception; 2 | 3 | /** 4 | * @author wanghuan 5 | * @description: EsHelperConfigException 6 | * @date 2022-01-26 11:28 7 | */ 8 | public class EsEngineConfigException extends RuntimeException { 9 | 10 | public EsEngineConfigException() { 11 | } 12 | 13 | public EsEngineConfigException(String message) { 14 | super(message); 15 | } 16 | 17 | public EsEngineConfigException(String message, Throwable cause) { 18 | super(message, cause); 19 | } 20 | 21 | public EsEngineConfigException(Throwable cause) { 22 | super(cause); 23 | } 24 | 25 | public EsEngineConfigException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { 26 | super(message, cause, enableSuppression, writableStackTrace); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/model/exception/EsEngineExecuteException.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.model.exception; 2 | 3 | /** 4 | * @author wanghuan 5 | * @description: EsHelperQueryException 6 | * @date 2022-01-26 11:28 7 | */ 8 | public class EsEngineExecuteException extends RuntimeException { 9 | 10 | public EsEngineExecuteException() { 11 | } 12 | 13 | public EsEngineExecuteException(String message) { 14 | super(message); 15 | } 16 | 17 | public EsEngineExecuteException(String message, Throwable cause) { 18 | super(message, cause); 19 | } 20 | 21 | public EsEngineExecuteException(Throwable cause) { 22 | super(cause); 23 | } 24 | 25 | public EsEngineExecuteException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { 26 | super(message, cause, enableSuppression, writableStackTrace); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/model/exception/EsEngineJpaExecuteException.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.model.exception; 2 | 3 | /** 4 | * @author wanghuan 5 | * @description: EsHelperQueryException 6 | * @date 2022-01-26 11:28 7 | */ 8 | public class EsEngineJpaExecuteException extends RuntimeException { 9 | 10 | public EsEngineJpaExecuteException() { 11 | } 12 | 13 | public EsEngineJpaExecuteException(String message) { 14 | super(message); 15 | } 16 | 17 | public EsEngineJpaExecuteException(String message, Throwable cause) { 18 | super(message, cause); 19 | } 20 | 21 | public EsEngineJpaExecuteException(Throwable cause) { 22 | super(cause); 23 | } 24 | 25 | public EsEngineJpaExecuteException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { 26 | super(message, cause, enableSuppression, writableStackTrace); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/java/com/elasticsearch/engine/base/model/exception/EsEngineQueryException.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base.model.exception; 2 | 3 | /** 4 | * @author wanghuan 5 | * @description: EsHelperQueryException 6 | * @date 2022-01-26 11:28 7 | */ 8 | public class EsEngineQueryException extends RuntimeException { 9 | 10 | public EsEngineQueryException() { 11 | } 12 | 13 | public EsEngineQueryException(String message) { 14 | super(message); 15 | } 16 | 17 | public EsEngineQueryException(String message, Throwable cause) { 18 | super(message, cause); 19 | } 20 | 21 | public EsEngineQueryException(Throwable cause) { 22 | super(cause); 23 | } 24 | 25 | public EsEngineQueryException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) { 26 | super(message, cause, enableSuppression, writableStackTrace); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ 2 | com.elasticsearch.engine.base.ElasticsearchEngineConfiguration 3 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/resources/elasticseach-engine.properties: -------------------------------------------------------------------------------- 1 | 1.0.1-RELEASE -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/main/resources/engine-banner.txt: -------------------------------------------------------------------------------- 1 | 2 | _____ _____ _____ _ _ _____ _____ _ _ _____ 3 | | ___/ ___| | ___| \ | | __ \_ _| \ | || ___| 4 | | |__ \ `--. | |__ | \| | | \/ | | | \| || |__ 5 | | __| `--. \ | __|| . ` | | __ | | | . ` || __| 6 | | |___/\__/ / | |___| |\ | |_\ \_| |_| |\ || |___ 7 | \____/\____/ \____/\_| \_/\____/\___/\_| \_/\____/ 8 | :: elasticsearch engine :: (v %s) 9 | -------------------------------------------------------------------------------- /elasticsearch-engine-base/src/test/java/com/elasticsearch/engine/base/ElasticsearchEngineBaseApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.base; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class ElasticsearchEngineBaseApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /elasticsearch-engine-jooq/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | elasticsearch-engine 6 | com.elasticsearch.engine 7 | 0.0.1-SNAPSHOT 8 | 9 | 4.0.0 10 | 11 | elasticsearch-engine-jooq 12 | 13 | 14 | 15 | com.elasticsearch.engine 16 | elasticsearch-engine-base 17 | 18 | 19 | org.jooq 20 | jooq 21 | ${jooq.version} 22 | 23 | 24 | org.springframework.boot 25 | spring-boot-starter-test 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /elasticsearch-engine-jooq/src/main/java/com/elasticsearch/engine/jooq/ElasticsearchEngineJooqConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.jooq; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.springframework.context.annotation.ComponentScan; 5 | import org.springframework.context.annotation.Configuration; 6 | 7 | /** 8 | * @author wanghuan 9 | * @description: com.elasticsearch.engine.base.ElasticsearchEngineConfiguration 10 | * @date 2022-01-26 11:28 11 | */ 12 | @Slf4j 13 | @Configuration 14 | @ComponentScan(basePackages ={"com.elasticsearch.engine.jooq"} ) 15 | public class ElasticsearchEngineJooqConfiguration { 16 | 17 | } 18 | -------------------------------------------------------------------------------- /elasticsearch-engine-jooq/src/main/java/com/elasticsearch/engine/jooq/annotion/JooqEsQuery.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.jooq.annotion; 2 | 3 | import java.lang.annotation.*; 4 | 5 | 6 | /** 7 | * @author wanghuan 8 | * @description: EsQuery 9 | * @date 2022-01-26 11:28 10 | */ 11 | @Retention(RetentionPolicy.RUNTIME) 12 | @Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE}) 13 | @Documented 14 | public @interface JooqEsQuery { 15 | 16 | /** 17 | * 回表字段所属的表名或别名 18 | * 19 | * @return 20 | */ 21 | String backTable() default ""; 22 | 23 | /** 24 | * 回表字段 25 | * 26 | * @return 27 | */ 28 | String backColumn() default ""; 29 | 30 | /** 31 | * 回表字段类型 32 | * 33 | * @return 34 | */ 35 | Class backColumnType() default Object.class; 36 | 37 | } 38 | -------------------------------------------------------------------------------- /elasticsearch-engine-jooq/src/main/java/com/elasticsearch/engine/jooq/aop/JooqEsQueryAop.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.jooq.aop; 2 | 3 | import com.elasticsearch.engine.base.common.parse.sql.EsSqlQueryHelper; 4 | import com.elasticsearch.engine.jooq.model.JooqBackDto; 5 | import lombok.extern.slf4j.Slf4j; 6 | import org.aspectj.lang.ProceedingJoinPoint; 7 | import org.aspectj.lang.annotation.Around; 8 | import org.aspectj.lang.annotation.Aspect; 9 | import org.aspectj.lang.annotation.Pointcut; 10 | import org.aspectj.lang.reflect.MethodSignature; 11 | import org.springframework.stereotype.Component; 12 | 13 | import javax.annotation.Resource; 14 | 15 | 16 | /** 17 | * @author wanghuan 18 | * @description: LogAop 19 | * @date 2022-05-24 23:17 20 | */ 21 | @Slf4j 22 | @Component 23 | @Aspect 24 | public class JooqEsQueryAop { 25 | 26 | @Resource 27 | private EsSqlQueryHelper esSqlQueryHelper; 28 | 29 | /** 30 | * 拦截添加了注解 @JpaEsQuery 的方法 31 | */ 32 | @Pointcut("@annotation(com.elasticsearch.engine.jooq.annotion.JooqEsQuery)") 33 | public void esQueryCut() { 34 | } 35 | 36 | @Around(value = "esQueryCut()") 37 | public Object retryAdvice(ProceedingJoinPoint pjp) throws Throwable { 38 | MethodSignature signature = (MethodSignature) pjp.getSignature(); 39 | return esSqlQueryHelper.esSqlQueryAopCommon(pjp, JooqBackDto.hasJooqBack(signature.getMethod())); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /elasticsearch-engine-jooq/src/main/java/com/elasticsearch/engine/jooq/model/JooqBackDto.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.jooq.model; 2 | 3 | import com.elasticsearch.engine.base.model.domain.BackDto; 4 | import com.elasticsearch.engine.jooq.annotion.JooqEsQuery; 5 | import org.apache.commons.lang3.StringUtils; 6 | 7 | import java.lang.reflect.Method; 8 | import java.util.Objects; 9 | 10 | /** 11 | * @author wanghuan 12 | * @description MybatisBackDto 13 | * @mail 958721894@qq.com 14 | * @date 2022-06-17 21:11 15 | */ 16 | public class JooqBackDto extends BackDto { 17 | 18 | public static BackDto hasJooqBack(Method method) { 19 | JooqEsQuery esQuery = method.getAnnotation(JooqEsQuery.class); 20 | String backColumn = esQuery.backColumn(); 21 | String tableName = esQuery.backTable(); 22 | Class backColumnTyp = esQuery.backColumnType(); 23 | if (StringUtils.isNotEmpty(backColumn) && Objects.nonNull(backColumnTyp) && !backColumnTyp.equals(Objects.class)) { 24 | return BackDto.builder().tableName(tableName).backColumn(backColumn).backColumnTyp(backColumnTyp).build(); 25 | } 26 | return null; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /elasticsearch-engine-jooq/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ 2 | com.elasticsearch.engine.jooq.ElasticsearchEngineJooqConfiguration -------------------------------------------------------------------------------- /elasticsearch-engine-jooq/src/test/java/com/elasticsearch/engine/jooq/ElasticsearchEngineJooqApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.jooq; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class ElasticsearchEngineJooqApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /elasticsearch-engine-jpa/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | elasticsearch-engine 6 | com.elasticsearch.engine 7 | 0.0.1-SNAPSHOT 8 | 9 | 4.0.0 10 | 11 | elasticsearch-engine-jpa 12 | 13 | 14 | 15 | com.elasticsearch.engine 16 | elasticsearch-engine-base 17 | 18 | 19 | org.springframework.boot 20 | spring-boot-starter-data-jpa 21 | 22 | 23 | org.hibernate 24 | hibernate-core 25 | 26 | 27 | org.springframework.boot 28 | spring-boot-starter-test 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /elasticsearch-engine-jpa/src/main/java/com/elasticsearch/engine/jpa/ElasticsearchEngineJpaConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.jpa; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.springframework.context.annotation.ComponentScan; 5 | import org.springframework.context.annotation.Configuration; 6 | 7 | /** 8 | * @author wanghuan 9 | * @description: com.elasticsearch.engine.base.ElasticsearchEngineConfiguration 10 | * @date 2022-01-26 11:28 11 | */ 12 | @Slf4j 13 | @Configuration 14 | @ComponentScan(basePackages ={"com.elasticsearch.engine.jpa"} ) 15 | public class ElasticsearchEngineJpaConfiguration { 16 | 17 | } 18 | -------------------------------------------------------------------------------- /elasticsearch-engine-jpa/src/main/java/com/elasticsearch/engine/jpa/Inspector/JpaEsQueryStatementInspector.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.jpa.Inspector; 2 | 3 | import com.elasticsearch.engine.base.common.utils.ThreadLocalUtil; 4 | import com.elasticsearch.engine.base.model.constant.CommonConstant; 5 | import org.apache.commons.lang3.StringUtils; 6 | import org.hibernate.resource.jdbc.spi.StatementInspector; 7 | import org.springframework.stereotype.Component; 8 | 9 | import java.util.Objects; 10 | 11 | /** 12 | * @author wanghuan 13 | * @description jpa sql切es查询拦截器 14 | * @mail 958721894@qq.com 15 | * @date 2022/6/9 11:42 16 | */ 17 | @Component 18 | public class JpaEsQueryStatementInspector implements StatementInspector { 19 | private static final long serialVersionUID = -2084992774423895712L; 20 | // @Override 21 | // public String inspect(String sql) { 22 | // Boolean isEsQuery = ThreadLocalUtil.get(CommonConstant.IS_ES_QUERY); 23 | // String backSql = ThreadLocalUtil.get(CommonConstant.BACK_QUERY_SQL); 24 | // if (Objects.nonNull(isEsQuery) && isEsQuery) { 25 | // if (StringUtils.isNotEmpty(backSql)) { 26 | // return backSql; 27 | // } 28 | // throw new EsHelperJpaExecuteException(sql); 29 | // } else { 30 | // return sql; 31 | // } 32 | // } 33 | 34 | // @Override 35 | // public String inspect(String sql) { 36 | // //非select语句直接返回 37 | // if (!sql.startsWith(CommonConstant.SELECT_SQL_PREFIX_LOWER) && !sql.startsWith(CommonConstant.SELECT_SQL_PREFIX_UPPER)) { 38 | // return sql; 39 | // } 40 | // Boolean isEsQuery = ThreadLocalUtil.get(CommonConstant.IS_ES_QUERY); 41 | // String backSql = ThreadLocalUtil.get(CommonConstant.BACK_QUERY_SQL); 42 | // if (Objects.nonNull(isEsQuery) && isEsQuery) { 43 | // ThreadLocalUtil.remove(CommonConstant.IS_ES_QUERY); 44 | // throw new EsEngineJpaExecuteException(sql); 45 | // } else if (StringUtils.isNotEmpty(backSql)) { 46 | // ThreadLocalUtil.remove(CommonConstant.BACK_QUERY_SQL); 47 | // return backSql; 48 | // } else { 49 | // return sql; 50 | // } 51 | // } 52 | 53 | @Override 54 | public String inspect(String sql) { 55 | //非es查询 56 | if (Objects.isNull(ThreadLocalUtil.get(CommonConstant.IS_ES_QUERY))) { 57 | return sql; 58 | } 59 | //非select语句直接返回 60 | if (!sql.startsWith(CommonConstant.SELECT_SQL_PREFIX_LOWER) && !sql.startsWith(CommonConstant.SELECT_SQL_PREFIX_UPPER)) { 61 | return sql; 62 | } 63 | String backSql = ThreadLocalUtil.remove(CommonConstant.BACK_QUERY_SQL); 64 | //处理回表sql用于改写sql , 非回表的直接由BasicBinder处理 65 | if (StringUtils.isNotEmpty(backSql)) { 66 | return backSql; 67 | } else { 68 | ThreadLocalUtil.set(CommonConstant.JPA_NATIVE_SQL, sql); 69 | return sql; 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /elasticsearch-engine-jpa/src/main/java/com/elasticsearch/engine/jpa/annotion/JpaEsQuery.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.jpa.annotion; 2 | 3 | import java.lang.annotation.*; 4 | 5 | 6 | /** 7 | * @author wanghuan 8 | * @description: EsQuery 9 | * @date 2022-01-26 11:28 10 | */ 11 | @Retention(RetentionPolicy.RUNTIME) 12 | @Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE}) 13 | @Documented 14 | public @interface JpaEsQuery { 15 | 16 | /** 17 | * 回表字段所属的表名或别名 18 | * 19 | * @return 20 | */ 21 | String backTable() default ""; 22 | 23 | /** 24 | * 回表字段 25 | * 26 | * @return 27 | */ 28 | String backColumn() default ""; 29 | 30 | /** 31 | * 回表字段类型 32 | * 33 | * @return 34 | */ 35 | Class backColumnType() default Object.class; 36 | 37 | } 38 | -------------------------------------------------------------------------------- /elasticsearch-engine-jpa/src/main/java/com/elasticsearch/engine/jpa/aop/JpaEsQueryAop.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.jpa.aop; 2 | 3 | import com.elasticsearch.engine.base.common.parse.sql.EsSqlQueryHelper; 4 | import com.elasticsearch.engine.jpa.model.JpaBackDto; 5 | import lombok.extern.slf4j.Slf4j; 6 | import org.aspectj.lang.ProceedingJoinPoint; 7 | import org.aspectj.lang.annotation.Around; 8 | import org.aspectj.lang.annotation.Aspect; 9 | import org.aspectj.lang.annotation.Pointcut; 10 | import org.aspectj.lang.reflect.MethodSignature; 11 | import org.springframework.stereotype.Component; 12 | 13 | import javax.annotation.Resource; 14 | 15 | 16 | /** 17 | * @author wanghuan 18 | * @description: LogAop 19 | * @date 2022-05-24 23:17 20 | */ 21 | @Slf4j 22 | @Component 23 | @Aspect 24 | public class JpaEsQueryAop { 25 | 26 | @Resource 27 | private EsSqlQueryHelper esSqlQueryHelper; 28 | 29 | /** 30 | * 拦截添加了注解 @JpaEsQuery 的方法 31 | */ 32 | @Pointcut("@annotation(com.elasticsearch.engine.jpa.annotion.JpaEsQuery)") 33 | public void esQueryCut() { 34 | } 35 | 36 | @Around(value = "esQueryCut()") 37 | public Object retryAdvice(ProceedingJoinPoint pjp) throws Throwable { 38 | MethodSignature signature = (MethodSignature) pjp.getSignature(); 39 | return esSqlQueryHelper.esSqlQueryAopCommon(pjp, JpaBackDto.hasJpaBack(signature.getMethod())); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /elasticsearch-engine-jpa/src/main/java/com/elasticsearch/engine/jpa/model/JpaBackDto.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.jpa.model; 2 | 3 | import com.elasticsearch.engine.base.model.domain.BackDto; 4 | import com.elasticsearch.engine.jpa.annotion.JpaEsQuery; 5 | import org.apache.commons.lang3.StringUtils; 6 | 7 | import java.lang.reflect.Method; 8 | import java.util.Objects; 9 | 10 | /** 11 | * @author wanghuan 12 | * @description MybatisBackDto 13 | * @mail 958721894@qq.com 14 | * @date 2022-06-17 21:11 15 | */ 16 | public class JpaBackDto extends BackDto { 17 | 18 | public static BackDto hasJpaBack(Method method) { 19 | JpaEsQuery esQuery = method.getAnnotation(JpaEsQuery.class); 20 | String backColumn = esQuery.backColumn(); 21 | String tableName = esQuery.backTable(); 22 | Class backColumnTyp = esQuery.backColumnType(); 23 | if (StringUtils.isNotEmpty(backColumn) && Objects.nonNull(backColumnTyp) && !backColumnTyp.equals(Objects.class)) { 24 | return BackDto.builder().tableName(tableName).backColumn(backColumn).backColumnTyp(backColumnTyp).build(); 25 | } 26 | return null; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /elasticsearch-engine-jpa/src/main/java/org/hibernate/type/descriptor/sql/BasicBinder.java: -------------------------------------------------------------------------------- 1 | package org.hibernate.type.descriptor.sql; 2 | 3 | import com.elasticsearch.engine.base.common.utils.ThreadLocalUtil; 4 | import com.elasticsearch.engine.base.model.constant.CommonConstant; 5 | import com.elasticsearch.engine.base.model.exception.EsEngineJpaExecuteException; 6 | import org.hibernate.internal.CoreLogging; 7 | import org.hibernate.type.descriptor.JdbcTypeNameMapper; 8 | import org.hibernate.type.descriptor.ValueBinder; 9 | import org.hibernate.type.descriptor.WrapperOptions; 10 | import org.hibernate.type.descriptor.java.JavaTypeDescriptor; 11 | import org.jboss.logging.Logger; 12 | 13 | import java.sql.PreparedStatement; 14 | import java.sql.SQLException; 15 | import java.util.Objects; 16 | 17 | /** 18 | * @author wanghuan 19 | * @description 重写jpa参数绑定的代码, 实现添加自定义逻辑 20 | *

21 | * 重新需要注意包名要和源码包名一致 22 | * @mail 958721894@qq.com 23 | * @date 2022/6/9 20:45 24 | */ 25 | public abstract class BasicBinder implements ValueBinder { 26 | 27 | private static final Logger log = CoreLogging.logger(BasicBinder.class); 28 | 29 | private static final String BIND_MSG_TEMPLATE = "binding parameter [%s] as [%s] - [%s]"; 30 | private static final String NULL_BIND_MSG_TEMPLATE = "binding parameter [%s] as [%s] - [null]"; 31 | 32 | private final JavaTypeDescriptor javaDescriptor; 33 | private final SqlTypeDescriptor sqlDescriptor; 34 | 35 | public JavaTypeDescriptor getJavaDescriptor() { 36 | return javaDescriptor; 37 | } 38 | 39 | public SqlTypeDescriptor getSqlDescriptor() { 40 | return sqlDescriptor; 41 | } 42 | 43 | public BasicBinder(JavaTypeDescriptor javaDescriptor, SqlTypeDescriptor sqlDescriptor) { 44 | this.javaDescriptor = javaDescriptor; 45 | this.sqlDescriptor = sqlDescriptor; 46 | } 47 | 48 | @Override 49 | public final void bind(PreparedStatement st, J value, int index, WrapperOptions options) throws SQLException { 50 | final boolean traceEnabled = log.isTraceEnabled(); 51 | 52 | if (value == null) { 53 | if (traceEnabled) { 54 | log.trace(String.format(NULL_BIND_MSG_TEMPLATE, index, JdbcTypeNameMapper.getTypeName(getSqlDescriptor().getSqlType()))); 55 | } 56 | st.setNull(index, sqlDescriptor.getSqlType()); 57 | } else { 58 | if (traceEnabled) { 59 | log.trace(String.format(BIND_MSG_TEMPLATE, index, JdbcTypeNameMapper.getTypeName(sqlDescriptor.getSqlType()), getJavaDescriptor().extractLoggableRepresentation(value))); 60 | } 61 | doBind(st, value, index, options); 62 | } 63 | inspect(st); 64 | } 65 | 66 | /** 67 | * Perform the binding. Safe to assume that value is not null. 68 | * 69 | * @param st The prepared statement 70 | * @param value The value to bind (not null). 71 | * @param index The index at which to bind 72 | * @param options The binding options 73 | * @throws SQLException Indicates a problem binding to the prepared statement. 74 | */ 75 | protected abstract void doBind(PreparedStatement st, J value, int index, WrapperOptions options) throws SQLException; 76 | 77 | 78 | /** 79 | * 处理jpa非回表查询 80 | * 获取带参数的sql 去es执行 81 | * 82 | * @param statement 83 | */ 84 | private void inspect(PreparedStatement statement) { 85 | //非es查询 86 | if (Objects.isNull(ThreadLocalUtil.get(CommonConstant.IS_ES_QUERY))) { 87 | return; 88 | } 89 | String st = statement.toString(); 90 | //bind方法会被多次调用,解析一个参数调用一次 91 | //包含 NOT SPECIFIED 说明jpa参数解析还未完成, 直接返回让继续解析. 等全部解析完成再处理后续逻辑 92 | if (st.contains("NOT SPECIFIED")) { 93 | return; 94 | } 95 | String sql = st.substring(st.indexOf(":") + 1); 96 | //非select语句直接返回 97 | if (!sql.trim().startsWith(CommonConstant.SELECT_SQL_PREFIX_LOWER) && !sql.trim().startsWith(CommonConstant.SELECT_SQL_PREFIX_UPPER)) { 98 | return; 99 | } 100 | Boolean isEsQuery = ThreadLocalUtil.remove(CommonConstant.IS_ES_QUERY); 101 | if (Objects.nonNull(isEsQuery)) { 102 | throw new EsEngineJpaExecuteException(sql); 103 | } 104 | } 105 | 106 | } -------------------------------------------------------------------------------- /elasticsearch-engine-jpa/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ 2 | com.elasticsearch.engine.jpa.ElasticsearchEngineJpaConfiguration -------------------------------------------------------------------------------- /elasticsearch-engine-jpa/src/test/java/com/elasticsearch/engine/jpa/ElasticsearchEngineJpaApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.jpa; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class ElasticsearchEngineJpaApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /elasticsearch-engine-mybatis/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | elasticsearch-engine 6 | com.elasticsearch.engine 7 | 0.0.1-SNAPSHOT 8 | 9 | 4.0.0 10 | 11 | elasticsearch-engine-mybatis 12 | 13 | 14 | 15 | com.elasticsearch.engine 16 | elasticsearch-engine-base 17 | 18 | 19 | org.mybatis 20 | mybatis 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-starter-test 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /elasticsearch-engine-mybatis/src/main/java/com/elasticsearch/engine/mybatis/ElasticsearchEngineMybatisConfiguration.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.mybatis; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.springframework.context.annotation.ComponentScan; 5 | import org.springframework.context.annotation.Configuration; 6 | 7 | /** 8 | * @author wanghuan 9 | * @description: com.elasticsearch.engine.base.ElasticsearchEngineConfiguration 10 | * @date 2022-01-26 11:28 11 | */ 12 | @Slf4j 13 | @Configuration 14 | @ComponentScan(basePackages ={"com.elasticsearch.engine.mybatis"} ) 15 | public class ElasticsearchEngineMybatisConfiguration { 16 | 17 | } 18 | -------------------------------------------------------------------------------- /elasticsearch-engine-mybatis/src/main/java/com/elasticsearch/engine/mybatis/annotion/MybatisEsQuery.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.mybatis.annotion; 2 | 3 | import java.lang.annotation.*; 4 | 5 | /** 6 | * @author wanghuan 7 | * @description MybatisEsQuery 8 | * @mail 958721894@qq.com 9 | * @date 2022-06-15 10:12 10 | */ 11 | @Retention(RetentionPolicy.RUNTIME) 12 | @Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE}) 13 | @Documented 14 | public @interface MybatisEsQuery { 15 | 16 | 17 | /** 18 | * 回表字段所属的表名或别名 19 | * 20 | * @return 21 | */ 22 | String backTable() default ""; 23 | 24 | /** 25 | * 回表字段 26 | * 27 | * @return 28 | */ 29 | String backColumn() default ""; 30 | 31 | /** 32 | * 回表字段类型 33 | * 34 | * @return 35 | */ 36 | Class backColumnType() default Object.class; 37 | } 38 | -------------------------------------------------------------------------------- /elasticsearch-engine-mybatis/src/main/java/com/elasticsearch/engine/mybatis/model/MybatisBackDto.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.mybatis.model; 2 | 3 | import com.elasticsearch.engine.base.model.domain.BackDto; 4 | import com.elasticsearch.engine.mybatis.annotion.MybatisEsQuery; 5 | import org.apache.commons.lang3.StringUtils; 6 | 7 | import java.lang.reflect.Method; 8 | import java.util.Objects; 9 | 10 | /** 11 | * @author wanghuan 12 | * @description MybatisBackDto 13 | * @mail 958721894@qq.com 14 | * @date 2022-06-17 21:11 15 | */ 16 | public class MybatisBackDto extends BackDto { 17 | 18 | public static BackDto hasBack(Method method) { 19 | MybatisEsQuery esQuery = method.getAnnotation(MybatisEsQuery.class); 20 | String backColumn = esQuery.backColumn(); 21 | String tableName = esQuery.backTable(); 22 | Class backColumnTyp = esQuery.backColumnType(); 23 | if (StringUtils.isNotEmpty(backColumn) && Objects.nonNull(backColumnTyp) && !backColumnTyp.equals(Objects.class)) { 24 | return BackDto.builder().tableName(tableName).backColumn(backColumn).backColumnTyp(backColumnTyp).build(); 25 | } 26 | return null; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /elasticsearch-engine-mybatis/src/main/java/com/elasticsearch/engine/mybatis/parse/SqlParamParseMybatisHelper.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.mybatis.parse; 2 | 3 | import com.elasticsearch.engine.base.common.parse.sql.SqlParamParseHelper; 4 | import org.apache.commons.collections4.CollectionUtils; 5 | import org.apache.ibatis.mapping.BoundSql; 6 | import org.apache.ibatis.mapping.ParameterMapping; 7 | import org.apache.ibatis.reflection.MetaObject; 8 | import org.apache.ibatis.session.Configuration; 9 | import org.apache.ibatis.type.TypeHandlerRegistry; 10 | 11 | import java.util.List; 12 | import java.util.regex.Matcher; 13 | 14 | /** 15 | * @author wanghuan 16 | * @description SqlParamParseHelperMybatis 17 | * @mail 958721894@qq.com 18 | * @date 2022-06-17 18:11 19 | */ 20 | public class SqlParamParseMybatisHelper extends SqlParamParseHelper { 21 | /** 22 | * mybatis查询参数解析 sql中的?进行参数替换 23 | * 24 | * @param configuration 25 | * @param boundSql 26 | * @return 27 | */ 28 | public static String paramParse(Configuration configuration, BoundSql boundSql) { 29 | // 获取参数 30 | Object parameterObject = boundSql.getParameterObject(); 31 | List parameterMappings = boundSql 32 | .getParameterMappings(); 33 | // sql语句中多个空格都用一个空格代替 34 | String sql = boundSql.getSql().replaceAll("[\\s]+", " "); 35 | if (!CollectionUtils.isEmpty(parameterMappings) && parameterObject != null) { 36 | // 获取类型处理器注册器,类型处理器的功能是进行java类型和数据库类型的转换
       // 如果根据parameterObject.getClass()可以找到对应的类型,则替换 37 | TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry(); 38 | if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) { 39 | sql = sql.replaceAll("\\?", Matcher.quoteReplacement(getParameterValue(parameterObject))); 40 | } else { 41 | // MetaObject主要是封装了originalObject对象,提供了get和set的方法用于获取和设置originalObject的属性值,主要支持对JavaBean、Collection、Map三种类型对象的操作 42 | MetaObject metaObject = configuration.newMetaObject(parameterObject); 43 | for (ParameterMapping parameterMapping : parameterMappings) { 44 | String propertyName = parameterMapping.getProperty(); 45 | if (metaObject.hasGetter(propertyName)) { 46 | Object obj = metaObject.getValue(propertyName); 47 | sql = sql.replaceFirst("\\?", Matcher.quoteReplacement(getParameterValue(obj))); 48 | } else if (boundSql.hasAdditionalParameter(propertyName)) { 49 | // 该分支是动态sql 50 | Object obj = boundSql.getAdditionalParameter(propertyName); 51 | sql = sql.replaceFirst("\\?", Matcher.quoteReplacement(getParameterValue(obj))); 52 | 53 | } else { 54 | //打印出缺失,提醒该参数缺失并防止错位 55 | sql = sql.replaceFirst("\\?", "缺失"); 56 | } 57 | } 58 | } 59 | } 60 | //like concat处理 61 | return parseLikeConcat(sql); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /elasticsearch-engine-mybatis/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ 2 | com.elasticsearch.engine.mybatis.ElasticsearchEngineMybatisConfiguration -------------------------------------------------------------------------------- /elasticsearch-engine-mybatis/src/test/java/com/elasticsearch/engine/mybatis/ElasticsearchEngineMybatisApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.elasticsearch.engine.mybatis; 2 | 3 | import org.junit.jupiter.api.Test; 4 | import org.springframework.boot.test.context.SpringBootTest; 5 | 6 | @SpringBootTest 7 | class ElasticsearchEngineMybatisApplicationTests { 8 | 9 | @Test 10 | void contextLoads() { 11 | } 12 | 13 | } 14 | -------------------------------------------------------------------------------- /流程图 .jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wanghuan9/elasticsearch-engine/d4e18e98b98187fa79d3912312e554175166db06/流程图 .jpg --------------------------------------------------------------------------------