Spring boot整合redis
公共部分
-
pom.xml
org.springframework.boot spring-boot-starter-data-jpa org.springframework.boot spring-boot-starter-data-redis org.apache.commons commons-pool2 org.projectlombok lombok true mysql mysql-connector-java org.joda joda-money 1.0.1 org.jadira.usertype usertype.core 6.0.1.GA -
定义实体类
@MappedSuperclass @Data @NoArgsConstructor @AllArgsConstructor public abstract class BaseEntity implements Serializable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(updatable = false) @CreationTimestamp private Date createTime; @UpdateTimestamp private Date updateTime; }
@Entity @Table(name = "T_COFFEE") @Builder @Data @ToString(callSuper = true) @NoArgsConstructor @AllArgsConstructor public class CoffeeEntity extends BaseEntity { private String name; @Type(type = "org.jadira.usertype.moneyandcurrency.joda.PersistentMoneyMinorAmount", parameters = {@org.hibernate.annotations.Parameter(name = "currencyCode", value = "CNY")}) private Money price; }
@Entity @Table(name = "T_ORDER") @Data @ToString(callSuper = true) @NoArgsConstructor @AllArgsConstructor @Builder public class CoffeeOrderEntity extends BaseEntity implements Serializable { private String customer; @ManyToMany @JoinTable(name = "T_ORDER_COFFEE") @OrderBy("id") private List
items; @Enumerated @Column(nullable = false) private OrderState state; } public enum OrderState { INIT, PAID, BREWING, BREWED, TAKEN, CANCELLED }
-
定义repository
public interface CoffeeOrderRepository extends JpaRepository
{} public interface CoffeeRepository extends JpaRepository {} -
定义service
@Slf4j @Service @Transactional public class CoffeeOrderServiceImpl implements CoffeeOrderService { @Autowired private CoffeeOrderRepository orderRepository; @Override public CoffeeOrderEntity createOrder(String customer, CoffeeEntity... coffee) { CoffeeOrderEntity order = CoffeeOrderEntity.builder() .customer(customer) .items(Arrays.asList(coffee)) .state(OrderState.INIT) .build(); CoffeeOrderEntity coffeeOrderEntity = orderRepository.save(order); log.info("New Order: {}", coffeeOrderEntity); return coffeeOrderEntity; } @Override public boolean updateState(CoffeeOrderEntity order, OrderState state) { if (state.compareTo(order.getState()) <= 0) { log.warn("Wrong State order: {}, {}", state, order.getState()); return false; } order.setState(state); orderRepository.save(order); log.info("Updated Order: {}", order); return true; } }
-
启动类
@Slf4j @EnableTransactionManagement @SpringBootApplication @EnableJpaRepositories public class RedisApplication{ public static void main(String[] args) { SpringApplication.run(RedisApplication.class, args); } }
yaml
使用RedisTemplate
private static final String CACHE = "coffee";
@Autowired private CoffeeRepository coffeeRepository;
@Autowired private RedisTemplate redisTemplate;
@Override
public List findAllCoffee() {
return coffeeRepository.findAll();
}
@Override
public Optional findOneCoffee(String name) {
HashOperations hashOperations = redisTemplate.opsForHash();
if (redisTemplate.hasKey(CACHE) && hashOperations.hasKey(CACHE, name)) {
log.info("Get coffee {} from Redis.", name);
return Optional.of(hashOperations.get(CACHE, name));
}
ExampleMatcher matcher = ExampleMatcher.matching().withMatcher("name", exact().ignoreCase());
Optional coffee =
coffeeRepository.findOne(Example.of(CoffeeEntity.builder().name(name).build(), matcher));
log.info("Coffee Found: {}", coffee);
if (coffee.isPresent()) {
log.info("Put coffee {} to Redis.", name);
hashOperations.put(CACHE, name, coffee.get());
redisTemplate.expire(CACHE, 1, TimeUnit.MINUTES);
}
return coffee;
}
@Bean
public RedisTemplate redisTemplate(
RedisConnectionFactory redisConnectionFactory) {
RedisTemplate template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
使用RedisRepository
@EnableRedisRepositories
@Bean
public RedisCustomConversions redisCustomConversions() {
return new RedisCustomConversions(
Arrays.asList(new MoneyToBytesConverter(), new BytesToMoneyConverter()));
}
-
实体类
@RedisHash(value = "coffee", timeToLive = 60) @Data @NoArgsConstructor @AllArgsConstructor @Builder public class CoffeeCacheEntity { @Id private Long id; @Indexed private String name; private Money price; }
-
Repository
public interface CoffeeCacheRepository extends CrudRepository
{ Optional findOneByName(String name); } -
Service
@Slf4j @Service public class CoffeeCacheServiceImpl implements CoffeeCacheService { @Autowired private CoffeeRepository coffeeRepository; @Autowired private CoffeeCacheRepository cacheRepository; @Override public List
findAllCoffee() { return coffeeRepository.findAll(); } @Override public Optional findSimpleCoffeeFromCache(String name) { Optional cached = cacheRepository.findOneByName(name); if (cached.isPresent()) { CoffeeCacheEntity coffeeCache = cached.get(); CoffeeEntity coffee = CoffeeEntity.builder().name(coffeeCache.getName()).price(coffeeCache.getPrice()).build(); log.info("Coffee {} found in cache.", coffeeCache); return Optional.of(coffee); } else { Optional raw = findOneCoffee(name); raw.ifPresent( c -> { CoffeeCacheEntity coffeeCache = CoffeeCacheEntity.builder() .id(c.getId()) .name(c.getName()) .price(c.getPrice()) .build(); log.info("Save Coffee {} to cache.", coffeeCache); cacheRepository.save(coffeeCache); }); return raw; } } @Override public Optional findOneCoffee(String name) { ExampleMatcher matcher = ExampleMatcher.matching().withMatcher("name", exact().ignoreCase()); Optional coffee = coffeeRepository.findOne(Example.of(CoffeeEntity.builder().name(name).build(), matcher)); log.info("Coffee Found: {}", coffee); return coffee; } } -
启动类
@Slf4j @EnableTransactionManagement @SpringBootApplication @EnableJpaRepositories @EnableRedisRepositories public class RedisApplication implements ApplicationRunner { @Autowired private CoffeeService coffeeService; @Autowired private CoffeeCacheService cacheService; public static void main(String[] args) { SpringApplication.run(RedisApplication.class, args); } @Bean public RedisTemplate
redisTemplate( RedisConnectionFactory redisConnectionFactory) { RedisTemplate template = new RedisTemplate<>(); template.setConnectionFactory(redisConnectionFactory); return template; } @Bean public JedisClientConfigurationBuilderCustomizer customizer() { return builder -> builder.readTimeout(Duration.ofMinutes(2)); } @Bean public RedisCustomConversions redisCustomConversions() { return new RedisCustomConversions( Arrays.asList(new MoneyToBytesConverter(), new BytesToMoneyConverter())); } @Override public void run(ApplicationArguments args) throws Exception { Optional c = coffeeService.findOneCoffee("mocha"); log.info("Coffee {}", c); for (int i = 0; i < 5; i++) { c = coffeeService.findOneCoffee("mocha"); } log.info("Value from Redis: {}", c); log.info("=====================redis repository==========================="); Optional optional = cacheService.findSimpleCoffeeFromCache("latte"); log.info("Coffee {}", optional); for (int i = 0; i < 5; i++) { optional = cacheService.findSimpleCoffeeFromCache("latte"); } log.info("Value from Redis: {}", optional.get()); } }
使用Jedis
@Bean
public JedisClientConfigurationBuilderCustomizer customizer() {
return builder -> builder.readTimeout(Duration.ofMinutes(2));
}
spring.redis.host: 192.168.1.105
spring.redis.jedis.pool.max-active: 8
spring.redis.jedis.pool.min-idele: 8
使用Lettuce
@Bean
public LettuceClientConfigurationBuilderCustomizer customizer() {
return builder -> builder.readFrom(ReadFrom.MASTER_PREFERRED);
}
spring.redis.host: 192.168.1.105
spring.redis.lettuce.pool.max-active: 8
spring.redis.lettuce.pool.min-idele: 8