Maklumat berkaitan tentang but spring digunakan
Versi but spring yang digunakan pada masa ini ialah 1.5.2.RELEASE
, 数据库操作使用的是 spring-boot-starter-data-jpa
,redis使用的是spring-boot-starter-data-redis
Untuk operasi pangkalan data, saya menggunakan repositori JPA yang disediakan oleh but spring, dan redis menggunakan Repositori Redis.
Senario biasa ialah menyimpan data ke mysql melalui JPA, dan selepas berjaya, kemas kini objek cincang redis.
Menurut pengenalan dokumen rasmi repositori data spring redis, saya perlu mengkonfigurasi entiti.
2.Kod berkaitan
Ambil simpan pesanan sebagai contoh, hantarkan DTO, panggil kaedah jpa untuk menulis ke pangkalan data, dan tulis ke cache selepas berjaya.
Kod utama adalah seperti berikut:
Gunakan untuk mendayakan caching dalam fail utama
@EnableRedisRepositories(basePackages = {"com.test"})
@EnableCaching
@SpringBootApplication
@EnableJpaRepositories(basePackages = {"com.test"})
@EnableRedisRepositories(basePackages = {"com.test"})
@EnableCaching
@EnableJpaAuditing
@EntityScan(basePackages = {"com.test"})
@ComponentScan(basePackages = {"com.test"} )
public class Application {
private static final Logger LOGGER = LoggerFactory.getLogger(Application.class);
public static void main(String[] args) {
final ApplicationContext applicationContext = SpringApplication.run(Application.class, args);
final String[] activeProfiles = applicationContext.getEnvironment().getActiveProfiles();
for (String profile : activeProfiles) {
LOGGER.info("using profile {}", profile);
}
}
}
RedisConfig menulis semula beberapa fungsi caching
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
@Override
@Bean
public KeyGenerator keyGenerator() {
return new KeyGenerator() {
@Override
public Object generate(Object target, Method method, Object... params) {
StringBuilder sb = new StringBuilder();
sb.append(target.getClass().getName());
sb.append(method.getName());
for (Object obj : params) {
sb.append(obj.toString());
}
System.out.println(sb.toString());
return sb.toString();
}
};
}
@Bean
public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
StringRedisTemplate template = new StringRedisTemplate(factory);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
template.setValueSerializer(jackson2JsonRedisSerializer);
template.afterPropertiesSet();
return template;
}
@Bean
public CacheManager cacheManager(RedisTemplate redisTemplate) {
RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
cacheManager.setDefaultExpiration(300);
return cacheManager;
}
}
OrderService memanggil kaedah simpan untuk menyimpan data ke pangkalan data Borang ini digunakan di sini@CachePut
注解,生成的key的主键是order:100
@CachePut(value = "order", key = "#order.id")
@Override
public void save(OrderDTO orderDTO) {
try {
Order order = BeanMapper.map(orderDTO, Order.class);
order = orderRepository.save(order);
System.out.println(order);
} catch (Exception e) {
e.printStackTrace();
}
}
Tetapan entiti adalah seperti berikut Konfigurasi JPA dan konfigurasi Redis digunakan di sini. Ini agak kabur dan saya tidak tahu sama ada ia betul.
@Entity
@Table(name = "order")
@RedisHash(value = "order")
public class Order {
private Long id;
private Long userId;
@org.springframework.data.annotation.Id
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
Masalah utama yang saya hadapi sekarang ialah: 1) dalam
.Order
实体配置中,如果我在Id
上配置了 redis 的 ID 注解 @org.springframework.data.annotation.Id
, 生成的redis key类似这样 order:1222702657038933405
, 我想要的效果是生成的key直接使用订单id,类似这样 order:100
tetapi ia tidak berkuat kuasa. @CachePut(value = "order", key = "#order.id")
Caused by: org.springframework.expression.spel.SpelEvaluationException: EL1007E: Property or field 'id' cannot be found on null
at org.springframework.expression.spel.ast.PropertyOrFieldReference.readProperty(PropertyOrFieldReference.java:220) ~[spring-expression-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.expression.spel.ast.PropertyOrFieldReference.getValueInternal(PropertyOrFieldReference.java:94) ~[spring-expression-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.expression.spel.ast.PropertyOrFieldReference.accessrrreee0(PropertyOrFieldReference.java:46) ~[spring-expression-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.expression.spel.ast.PropertyOrFieldReference$AccessorLValue.getValue(PropertyOrFieldReference.java:375) ~[spring-expression-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.expression.spel.ast.CompoundExpression.getValueInternal(CompoundExpression.java:88) ~[spring-expression-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.expression.spel.ast.SpelNodeImpl.getValue(SpelNodeImpl.java:120) ~[spring-expression-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.expression.spel.standard.SpelExpression.getValue(SpelExpression.java:242) ~[spring-expression-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.cache.interceptor.CacheOperationExpressionEvaluator.key(CacheOperationExpressionEvaluator.java:117) ~[spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.cache.interceptor.CacheAspectSupport$CacheOperationContext.generateKey(CacheAspectSupport.java:742) ~[spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.cache.interceptor.CacheAspectSupport.generateKey(CacheAspectSupport.java:558) ~[spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.cache.interceptor.CacheAspectSupport.collectPutRequests(CacheAspectSupport.java:529) ~[spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:413) ~[spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:327) ~[spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.cache.interceptor.CacheInterceptor.invoke(CacheInterceptor.java:61) ~[spring-context-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:656) ~[spring-aop-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at com.jiabangou.order.services.impls.OrderServiceImpl$$EnhancerBySpringCGLIB$ceab7f.save(<generated>) ~[classes/:na]
at com.jiabangou.bops.controllers.api.OrderApiController.save(OrderApiController.java:32) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_65]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_65]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_65]
at java.lang.reflect.Method.invoke(Method.java:497) ~[na:1.8.0_65]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205) ~[spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133) ~[spring-web-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:116) ~[spring-webmvc-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) ~[spring-webmvc-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) ~[spring-webmvc-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963) ~[spring-webmvc-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897) ~[spring-webmvc-4.3.7.RELEASE.jar:4.3.7.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) ~[spring-webmvc-4.3.7.RELEASE.jar:4.3.7.RELEASE]
... 95 common frames omitted
3) Mengetepikan masalah bahawa kunci yang dibuat oleh redis tidak betul, kami mendapati objek redis boleh disimpan dengan jayanya, tetapi rekod pangkalan data tidak berjaya dibuat. Jika anda mengalih keluar anotasi pada entiti Pesanan, rekod pangkalan data boleh dibuat dengan jayanya, tetapi cache tidak boleh dibuat dengan jayanya. @RedisHash(value = "order")
Pertama sekali, kuncinya hendaklah nama atribut
Kedua, @RedisHash digunakan untuk mengekalkan objek kepada redis Apa yang anda mahu gunakan di sini ialah cache redis, bukan ketekunan, jadi ia tidak ada kaitan dengan RedisHash.