网站建设合同 模板wordpress page 2
- 作者: 五速梦信息网
- 时间: 2026年04月20日 07:49
当前位置: 首页 > news >正文
网站建设合同 模板,wordpress page 2,凡客诚品简介,wordpress秀恩爱主题一、什么是两级缓存
在项目中。一级缓存用Caffeine#xff0c;二级缓存用Redis#xff0c;查询数据时首先查本地的Caffeine缓存#xff0c;没有命中再通过网络去访问Redis缓存#xff0c;还是没有命中再查数据库。具体流程如下
二、简单的二级缓存实现-v1
目录结构
2…一、什么是两级缓存
在项目中。一级缓存用Caffeine二级缓存用Redis查询数据时首先查本地的Caffeine缓存没有命中再通过网络去访问Redis缓存还是没有命中再查数据库。具体流程如下
二、简单的二级缓存实现-v1
目录结构
2.1 double-cache模块主要文件 pom文件
?xml version1.0 encodingUTF-8?
project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersiongroupIdorg.example/groupIdartifactIddouble-cache/artifactIdversion1.0-SNAPSHOT/versionparentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion2.7.2/versionrelativePath//parentpropertiesmaven.compiler.source8/maven.compiler.sourcemaven.compiler.target8/maven.compiler.targetproject.build.sourceEncodingUTF-8/project.build.sourceEncoding/propertiesdependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactId/dependencydependencygroupIdcom.github.ben-manes.caffeine/groupIdartifactIdcaffeine/artifactIdversion2.9.2/version/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-redis/artifactId/dependency/dependencies/project2.2 测试模块的主要文件 OrderServiceImpl
Slf4j
Service
RequiredArgsConstructor
public class OrderServiceImpl extends ServiceImplOrderMapper, Order implements OrderService {private final OrderMapper orderMapper;private final Cache cache;private final RedisTemplate redisTemplate;Overridepublic Order getOrderById(Long id) {String key CacheConstant.ORDER id;Order order (Order) cache.get(key,k - {//先查询 RedisObject obj redisTemplate.opsForValue().get(k);if (Objects.nonNull(obj)) {log.info(get data from redis);return obj;}// Redis没有则查询 DBlog.info(get data from database);Order myOrder orderMapper.selectOne(new LambdaQueryWrapperOrder().eq(Order::getId, id));redisTemplate.opsForValue().set(k, myOrder, 120, TimeUnit.SECONDS);return myOrder;});return order;}Overridepublic void updateOrder(Order order) {log.info(update order data);String key CacheConstant.ORDER order.getId();orderMapper.updateById(order);//修改 RedisredisTemplate.opsForValue().set(key, order, 120, TimeUnit.SECONDS);// 修改本地缓存cache.put(key, order);}Overridepublic void deleteOrder(Long id) {log.info(delete order);orderMapper.deleteById(id);String key CacheConstant.ORDER id;redisTemplate.delete(key);cache.invalidate(key);}
}
application.yml
server:port: 8090spring:application:name: test-demodatasource:url: jdbc:mysql://localhost:3306/ktl?useUnicodetruecharacterEncodingUTF-8serverTimezoneUTCusername: rootpassword: rootdriver-class-name: com.mysql.cj.jdbc.Driverredis:host: 192.168.200.131port: 6379database: 0timeout: 10000mslettuce:pool:max-active: 8max-wait: -1msmax-idle: 8min-idle: 0password: rootlogging:level:com.cn.dc: debugorg.springframework: warnpom文件
?xml version1.0 encodingUTF-8?
project xmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersiongroupIdorg.example/groupIdartifactIdtestcache/artifactIdversion1.0-SNAPSHOT/versionparentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion2.7.2/versionrelativePath//parentpropertiesmaven.compiler.source8/maven.compiler.sourcemaven.compiler.target8/maven.compiler.targetproject.build.sourceEncodingUTF-8/project.build.sourceEncodingmybatis-plus.version3.3.2/mybatis-plus.version/propertiesdependenciesdependencygroupIdorg.example/groupIdartifactIddouble-cache/artifactIdversion1.0-SNAPSHOT/version/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-test/artifactId/dependencydependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdscoperuntime/scope/dependencydependencygroupIdorg.apache.commons/groupIdartifactIdcommons-pool2/artifactIdversion2.8.1/version/dependencydependencygroupIdcom.baomidou/groupIdartifactIdmybatis-plus-boot-starter/artifactIdversion${mybatis-plus.version}/version/dependencydependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdversion1.18.12/versionscopeprovided/scope/dependency/dependencies
/project2.3 测试
测试get/{id}接口的时候会把从db查出来的数据放入到redis和Caffeine中在有效期内不需要再次从数据库查询
三、二级缓存实现-v2
v1的代码入侵性很强因此加入了注解CacheableCachePutCacheEvict
3.1 double-cache模块 3.2 测试模块
OrderServiceImpl
Slf4j
Service
RequiredArgsConstructor
public class OrderServiceImpl extends ServiceImplOrderMapper, Order implements OrderService {private final OrderMapper orderMapper;private final RedisTemplate redisTemplate;OverrideCacheable(value order,key #id)
//Cacheable(cacheNames order,key #p0)public Order getOrderById(Long id) {String key CacheConstant.ORDER id;//先查询 RedisObject obj redisTemplate.opsForValue().get(key);if (Objects.nonNull(obj)){log.info(get data from redis);return (Order) obj;}// Redis没有则查询 DBlog.info(get data from database);Order myOrder orderMapper.selectOne(new LambdaQueryWrapperOrder().eq(Order::getId, id));redisTemplate.opsForValue().set(key,myOrder,120, TimeUnit.SECONDS);return myOrder;}OverrideCachePut(cacheNames order,key #order.id)public Order updateOrder(Order order) {log.info(update order data);orderMapper.updateById(order);//修改 RedisredisTemplate.opsForValue().set(CacheConstant.ORDER order.getId(),order, 120, TimeUnit.SECONDS);return order;}OverrideCacheEvict(cacheNames order,key #id)public void deleteOrder(Long id) {log.info(delete order);orderMapper.deleteById(id);redisTemplate.delete(CacheConstant.ORDER id);}
}四、二级缓存实现-v3
模仿spring通过注解管理缓存的方式我们也可以选择自定义注解然后在切面中处理缓存从而将对业务代码的入侵降到最低。
首先定义一个注解用于添加在需要操作缓存的方法上
Target(ElementType.METHOD)
Retention(RetentionPolicy.RUNTIME)
Documented
public interface DoubleCache {String cacheName();String key(); //支持springEl表达式long l2TimeOut() default 120;CacheType type() default CacheType.FULL;
}我们使用cacheName key作为缓存的真正key仅存在一个Cache中不做CacheName隔离l2TimeOut为可以设置的二级缓存Redis的过期时间type是一个枚举类型的变量表示操作缓存的类型枚举类型定义如下
public enum CacheType {FULL, //存取PUT, //只存DELETE //删除
}因为要使key支持springEl表达式所以需要写一个方法使用表达式解析器解析参数
public class ElParser {public static String parse(String elString, TreeMapString,Object map){elStringString.format(#{%s},elString);//创建表达式解析器ExpressionParser parser new SpelExpressionParser();//通过evaluationContext.setVariable可以在上下文中设定变量。EvaluationContext context new StandardEvaluationContext();map.entrySet().forEach(entry-context.setVariable(entry.getKey(),entry.getValue()));//解析表达式Expression expression parser.parseExpression(elString, new TemplateParserContext());//使用Expression.getValue()获取表达式的值这里传入了Evaluation上下文String value expression.getValue(context, String.class);return value;}
}至于Cache相关参数的配置我们沿用V1版本中的配置即可。准备工作做完了下面我们定义切面在切面中操作Cache来读写Caffeine的缓存操作RedisTemplate读写Redis缓存。
Slf4j
Component
Aspect
AllArgsConstructor
public class CacheAspect {private final Cache cache;private final RedisTemplate redisTemplate;private final String COLON :;Pointcut(annotation(org.example.doublecache.annotation.DoubleCache))public void cacheAspect() {}Around(cacheAspect())public Object doAround(ProceedingJoinPoint point) throws Throwable {MethodSignature signature (MethodSignature) point.getSignature();Method method signature.getMethod();// if (!method.isAnnotationPresent(DoubleCache.class))
// return null;//拼接解析springEl表达式的mapString[] paramNames signature.getParameterNames();Object[] args point.getArgs();TreeMapString, Object treeMap new TreeMap();for (int i 0; i paramNames.length; i) {treeMap.put(paramNames[i],args[i]);}DoubleCache annotation method.getAnnotation(DoubleCache.class);String elResult ElParser.parse(annotation.key(), treeMap);String realKey annotation.cacheName() COLON elResult;//强制更新if (annotation.type() CacheType.PUT){Object object point.proceed();redisTemplate.opsForValue().set(realKey, object,annotation.l2TimeOut(), TimeUnit.SECONDS);cache.put(realKey, object);return object;}//删除else if (annotation.type() CacheType.DELETE){redisTemplate.delete(realKey);cache.invalidate(realKey);return point.proceed();}//读写查询CaffeineObject caffeineCache cache.getIfPresent(realKey);if (Objects.nonNull(caffeineCache)) {log.info(get data from caffeine);return caffeineCache;}//查询RedisObject redisCache redisTemplate.opsForValue().get(realKey);if (Objects.nonNull(redisCache)) {log.info(get data from redis);cache.put(realKey, redisCache);return redisCache;}log.info(get data from database);Object object point.proceed();if (Objects.nonNull(object)){//写回RedisredisTemplate.opsForValue().set(realKey, object,annotation.l2TimeOut(), TimeUnit.SECONDS);//写入Caffeinecache.put(realKey, object);}return object;}
}4.1 double-cache模块 4.2 测试模块 OrderServiceImpl修改如下
Slf4j
Service
RequiredArgsConstructor
public class OrderServiceImpl extends ServiceImplOrderMapper, Order implements OrderService {private final OrderMapper orderMapper;OverrideDoubleCache(cacheName order, key #id,type CacheType.FULL)public Order getOrderById(Long id) {Order myOrder orderMapper.selectOne(new LambdaQueryWrapperOrder().eq(Order::getId, id));return myOrder;}OverrideDoubleCache(cacheName order,key #order.id,type CacheType.PUT)public Order updateOrder(Order order) {orderMapper.updateById(order);return order;}OverrideDoubleCache(cacheName order,key #id,type CacheType.DELETE)public void deleteOrder(Long id) {orderMapper.deleteById(id);}OverrideDoubleCache(cacheName order,key #id)public Order getOrderByIdAndStatus(Long id,Integer status) {Order myOrder orderMapper.selectOne(new LambdaQueryWrapperOrder().eq(Order::getId, id).eq(Order::getStatus,status));return myOrder;}在TestApplication上加EnableCaching
4.3 测试
从数据库10ms生产中会走网络通信会更长。 从Caffeine平均4ms
相关文章
-
网站建设合同 技术合同wordpress tag name slug or id
网站建设合同 技术合同wordpress tag name slug or id
- 技术栈
- 2026年04月20日
-
网站建设合肥公司国内广告公司排行
网站建设合肥公司国内广告公司排行
- 技术栈
- 2026年04月20日
-
网站建设好评语游戏代理平台
网站建设好评语游戏代理平台
- 技术栈
- 2026年04月20日
-
网站建设合同 域名如何在头条上做网站推广
网站建设合同 域名如何在头条上做网站推广
- 技术栈
- 2026年04月20日
-
网站建设合同的主要内容手机网速
网站建设合同的主要内容手机网速
- 技术栈
- 2026年04月20日
-
网站建设合同范本做互联网公司网站谈单模拟视频教学
网站建设合同范本做互联网公司网站谈单模拟视频教学
- 技术栈
- 2026年04月20日
