diff --git a/orion-ops-framework/orion-ops-common/src/main/java/com/orion/ops/framework/common/constant/FilterOrderConst.java b/orion-ops-framework/orion-ops-common/src/main/java/com/orion/ops/framework/common/constant/FilterOrderConst.java index 6ef542e5..184b1e02 100644 --- a/orion-ops-framework/orion-ops-common/src/main/java/com/orion/ops/framework/common/constant/FilterOrderConst.java +++ b/orion-ops-framework/orion-ops-common/src/main/java/com/orion/ops/framework/common/constant/FilterOrderConst.java @@ -13,4 +13,6 @@ public interface FilterOrderConst { int TRICE_ID_FILTER = Integer.MIN_VALUE + 10; + int MYBATIS_CACHE_CLEAR_FILTER = Integer.MIN_VALUE + 100000; + } diff --git a/orion-ops-framework/orion-ops-common/src/main/java/com/orion/ops/framework/common/filter/FilterCreator.java b/orion-ops-framework/orion-ops-common/src/main/java/com/orion/ops/framework/common/filter/FilterCreator.java new file mode 100644 index 00000000..d3666996 --- /dev/null +++ b/orion-ops-framework/orion-ops-common/src/main/java/com/orion/ops/framework/common/filter/FilterCreator.java @@ -0,0 +1,33 @@ +package com.orion.ops.framework.common.filter; + +import org.springframework.boot.web.servlet.FilterRegistrationBean; + +import javax.servlet.Filter; + +/** + * 过滤器构造器 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023/6/25 15:05 + */ +public class FilterCreator { + + private FilterCreator() { + } + + /** + * 创建过滤器 + * + * @param filter filter + * @param order order + * @param type + * @return filter bean + */ + public static FilterRegistrationBean create(T filter, Integer order) { + FilterRegistrationBean bean = new FilterRegistrationBean<>(filter); + bean.setOrder(order); + return bean; + } + +} diff --git a/orion-ops-framework/orion-ops-spring-boot-starter-mybatis/src/main/java/com/orion/ops/framework/mybatis/cache/CacheQuery.java b/orion-ops-framework/orion-ops-spring-boot-starter-mybatis/src/main/java/com/orion/ops/framework/mybatis/cache/CacheQuery.java new file mode 100644 index 00000000..af88d70c --- /dev/null +++ b/orion-ops-framework/orion-ops-spring-boot-starter-mybatis/src/main/java/com/orion/ops/framework/mybatis/cache/CacheQuery.java @@ -0,0 +1,76 @@ +package com.orion.ops.framework.mybatis.cache; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.orion.lang.define.wrapper.Store; +import com.orion.lang.utils.Valid; + +import java.io.Serializable; + +/** + * 缓存查询器 + *

+ * 查询会存入缓存 + *

+ * TODO test + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023/6/25 13:05 + */ +public class CacheQuery { + + private final BaseMapper dao; + + private Serializable id; + + private CacheQuery(BaseMapper dao, Serializable id) { + this.dao = dao; + this.id = id; + } + + public static CacheQuery of(BaseMapper dao) { + Valid.notNull(dao, "dao is null"); + return new CacheQuery<>(dao, null); + } + + public static CacheQuery of(BaseMapper dao, Serializable id) { + Valid.notNull(dao, "dao is null"); + Valid.notNull(id, "id is null"); + return new CacheQuery<>(dao, id); + } + + /** + * 设置 id + * + * @param id id + * @return this + */ + public CacheQuery id(Serializable id) { + this.id = id; + return this; + } + + @SuppressWarnings("unchecked") + public R get(Class c) { + T row = this.get(); + // TODO FIXME mapstruct + return (R) row; + } + + @SuppressWarnings("unchecked") + public T get() { + Class> mapperClass = (Class>) dao.getClass(); + // 从缓存中获取 + Store store = RowCacheHolder.get(mapperClass, id); + // 设置过缓存 + if (store != null) { + return store.get(); + } + // 查询 + T row = dao.selectById(id); + // 设置缓存 + RowCacheHolder.set(mapperClass, id, row); + return row; + } + +} diff --git a/orion-ops-framework/orion-ops-spring-boot-starter-mybatis/src/main/java/com/orion/ops/framework/mybatis/cache/RowCacheClearFilter.java b/orion-ops-framework/orion-ops-spring-boot-starter-mybatis/src/main/java/com/orion/ops/framework/mybatis/cache/RowCacheClearFilter.java new file mode 100644 index 00000000..3dd51863 --- /dev/null +++ b/orion-ops-framework/orion-ops-spring-boot-starter-mybatis/src/main/java/com/orion/ops/framework/mybatis/cache/RowCacheClearFilter.java @@ -0,0 +1,32 @@ +package com.orion.ops.framework.mybatis.cache; + +import org.springframework.web.filter.OncePerRequestFilter; + +import javax.servlet.FilterChain; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * mybatis 缓存清理过滤器 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023/6/25 15:14 + */ +public class RowCacheClearFilter extends OncePerRequestFilter { + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { + try { + // 执行请求 + filterChain.doFilter(request, response); + } finally { + // 清理缓存 + // TODO test + RowCacheHolder.remove(); + } + } + +} diff --git a/orion-ops-framework/orion-ops-spring-boot-starter-mybatis/src/main/java/com/orion/ops/framework/mybatis/cache/RowCacheHolder.java b/orion-ops-framework/orion-ops-spring-boot-starter-mybatis/src/main/java/com/orion/ops/framework/mybatis/cache/RowCacheHolder.java new file mode 100644 index 00000000..c50e5c00 --- /dev/null +++ b/orion-ops-framework/orion-ops-spring-boot-starter-mybatis/src/main/java/com/orion/ops/framework/mybatis/cache/RowCacheHolder.java @@ -0,0 +1,61 @@ +package com.orion.ops.framework.mybatis.cache; + +import com.baomidou.mybatisplus.core.mapper.BaseMapper; +import com.orion.lang.define.collect.MultiHashMap; +import com.orion.lang.define.wrapper.Store; + +import java.io.Serializable; + +/** + * 缓存行持有者 + * + * @author Jiahang Li + * @version 1.0.0 + * @since 2023/6/25 14:21 + */ +public class RowCacheHolder { + + private RowCacheHolder() { + } + + /** + * 缓存 + *

+ * key: mapperClass + * value: id > row + */ + private static final ThreadLocal>, Serializable, Store>> HOLDER = ThreadLocal.withInitial(MultiHashMap::new); + + /** + * 获取缓存 + * + * @param mapperClass mapperClass + * @param id id + * @param domain + * @return cacheWrapper + */ + @SuppressWarnings("unchecked") + public static Store get(Class> mapperClass, Serializable id) { + return (Store) HOLDER.get().get(mapperClass, id); + } + + /** + * 设置缓存 + * + * @param mapperClass mapperClass + * @param id id + * @param row row + * @param domainClass + */ + public static void set(Class> mapperClass, Serializable id, T row) { + HOLDER.get().put(mapperClass, id, new Store<>(row)); + } + + /** + * 清空缓存 + */ + public static void remove() { + HOLDER.remove(); + } + +} diff --git a/orion-ops-framework/orion-ops-spring-boot-starter-mybatis/src/main/java/com/orion/ops/framework/mybatis/config/OrionMybatisAutoConfiguration.java b/orion-ops-framework/orion-ops-spring-boot-starter-mybatis/src/main/java/com/orion/ops/framework/mybatis/config/OrionMybatisAutoConfiguration.java index 18645e96..463ffd46 100644 --- a/orion-ops-framework/orion-ops-spring-boot-starter-mybatis/src/main/java/com/orion/ops/framework/mybatis/config/OrionMybatisAutoConfiguration.java +++ b/orion-ops-framework/orion-ops-spring-boot-starter-mybatis/src/main/java/com/orion/ops/framework/mybatis/config/OrionMybatisAutoConfiguration.java @@ -1,9 +1,13 @@ package com.orion.ops.framework.mybatis.config; import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; +import com.orion.ops.framework.common.constant.FilterOrderConst; +import com.orion.ops.framework.common.filter.FilterCreator; +import com.orion.ops.framework.mybatis.cache.RowCacheClearFilter; import com.orion.ops.framework.mybatis.handler.FieldFillHandler; import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.autoconfigure.AutoConfiguration; +import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; /** @@ -26,4 +30,12 @@ public class OrionMybatisAutoConfiguration { return new FieldFillHandler(); } + /** + * @return mybatis 缓存清理过滤器 + */ + @Bean + public FilterRegistrationBean rowCacheClearFilterBean() { + return FilterCreator.create(new RowCacheClearFilter(), FilterOrderConst.MYBATIS_CACHE_CLEAR_FILTER); + } + } diff --git a/orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/java/com/orion/ops/framework/web/config/OrionWebAutoConfiguration.java b/orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/java/com/orion/ops/framework/web/config/OrionWebAutoConfiguration.java index b93a90c2..420896d2 100644 --- a/orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/java/com/orion/ops/framework/web/config/OrionWebAutoConfiguration.java +++ b/orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/java/com/orion/ops/framework/web/config/OrionWebAutoConfiguration.java @@ -5,6 +5,7 @@ import com.alibaba.fastjson.support.config.FastJsonConfig; import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; import com.orion.lang.utils.collect.Lists; import com.orion.ops.framework.common.constant.FilterOrderConst; +import com.orion.ops.framework.common.filter.FilterCreator; import com.orion.ops.framework.web.core.filter.TraceIdFilter; import com.orion.ops.framework.web.core.handler.GlobalExceptionHandler; import com.orion.ops.framework.web.core.handler.WrapperResultHandler; @@ -25,7 +26,6 @@ import org.springframework.web.filter.CorsFilter; import org.springframework.web.servlet.config.annotation.PathMatchConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; -import javax.servlet.Filter; import java.util.ArrayList; import java.util.List; @@ -124,7 +124,7 @@ public class OrionWebAutoConfiguration implements WebMvcConfigurer { // 创建 UrlBasedCorsConfigurationSource 对象 UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", config); - return createFilterBean(new CorsFilter(source), FilterOrderConst.CORS_FILTER); + return FilterCreator.create(new CorsFilter(source), FilterOrderConst.CORS_FILTER); } /** @@ -132,21 +132,7 @@ public class OrionWebAutoConfiguration implements WebMvcConfigurer { */ @Bean public FilterRegistrationBean traceIdFilterBean() { - return createFilterBean(new TraceIdFilter(), FilterOrderConst.TRICE_ID_FILTER); - } - - /** - * 创建过滤器 - * - * @param filter filter - * @param order order - * @param type - * @return filter bean - */ - public static FilterRegistrationBean createFilterBean(T filter, Integer order) { - FilterRegistrationBean bean = new FilterRegistrationBean<>(filter); - bean.setOrder(order); - return bean; + return FilterCreator.create(new TraceIdFilter(), FilterOrderConst.TRICE_ID_FILTER); } } diff --git a/orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/java/com/orion/ops/framework/web/core/filter/TraceIdFilter.java b/orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/java/com/orion/ops/framework/web/core/filter/TraceIdFilter.java index 03444136..cdf5d0fa 100644 --- a/orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/java/com/orion/ops/framework/web/core/filter/TraceIdFilter.java +++ b/orion-ops-framework/orion-ops-spring-boot-starter-web/src/main/java/com/orion/ops/framework/web/core/filter/TraceIdFilter.java @@ -32,6 +32,7 @@ public class TraceIdFilter extends OncePerRequestFilter { // 执行请求 filterChain.doFilter(request, response); } finally { + // 清理缓存 TraceIdHolder.remove(); } }