关系型数据库在性能上总存在一些这样那样的缺陷,所以大家有时候在使用传统型数据库时,会与具有高效存取功能的缓存系统结合使用,以提高系统的访问性能,如Redis。Redis是一种可以持久存储的缓存系统,是一个高性能的key-value数据库,它使用键值对的方式来存储数据。
1、Redis依赖配置
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-redis</artifactId> </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.2.4</version> </dependency>
</dependencies>
再引用上一篇mysql的模块,
<dependency> <groupId>springboot.db</groupId> <artifactId>mysql</artifactId> <version>${project.version}</version> </dependency>
2、创建Redis服务类
Redis提供了这几种数据类型可以供存取:string、hash、list、set及zset。
在实例中,将使用string进行存取操作。对于Redis,spring boot没有提供像JPA那样相应的资源库接口,所以只能仿照上一节中Repository的定义编写一个实体User的服务类。这个类可以存取对象User及由User组成的列表List,同时还提供了删除方法。所有这些方法都是使用RedisTemplate来实现的。
@Repository public class UserRedis { @Autowired private RedisTemplate<String, String> redisTemplate; public void add(String key, Long time,User user) { Gson gson = new Gson(); redisTemplate.opsForValue().set(key, gson.toJson(user), time, TimeUnit.MINUTES); } public void add(String key, Long time, List<User> users) { Gson gson = new Gson(); redisTemplate.opsForValue().set(key, gson.toJson(users), time, TimeUnit.MINUTES); } public User get(String key) { Gson gson = new Gson(); User user = null; String userJson = redisTemplate.opsForValue().get(key); if(!StringUtils.isEmpty(userJson)) user = gson.fromJson(userJson, User.class); return user; } public List<User> getList(String key) { Gson gson = new Gson(); List<User> ts = null; String listJson = redisTemplate.opsForValue().get(key); if(!StringUtils.isEmpty(listJson)) ts = gson.fromJson(listJson, new TypeToken<List<User>>(){}.getType()); return ts; } public void delete(String key){ redisTemplate.opsForValue().getOperations().delete(key); } }
Redis没有表结构的概念,所以要实现MySQL数据库中表的数据在Redis中存取,必须做一些转换,使用json格式的文本作为Redis与java普通对象交换数据的存储格式。这里使用Gson工具将类对象转换为json格式的文本进行存储,要取出数据时,再将json文本数据转化为Java对象。
因为Redis使用了key-value的方式存储数据,所以存入时要生成一个唯一的key,而要查询或者删除数据时,就可以使用这个唯一的key进行相应的操作。
保存在Redis数据库中的数据默认是永久存储的,可以指定一个时限来确定数据的生命周期,超过指定时限的数据将被Redis自动清除。
另外,为了能正确调用RedisTemplate,必须对其进行一些初始化工作,即主要对它存取的字符串进行一个json格式的系列化初始化配置。
@Configuration public class RedisConfig { @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; } }
3、Redis测试
安装Redis服务器,在application.yml中配置连接Redis的参数。host和port分别表示Redis数据库服务器的IP和端口。
spring: redis: # database: 1 host: 192.168.1.214 port: 6379 pool: max-idle: 8 min-idle: 0 max-active: 8 max-wait: -1
测试:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = {RedisConfig.class, UserRedis.class}) public class RedisTest { private static Logger logger = LoggerFactory.getLogger(RedisTest.class); @Autowired UserRedis userRedis; @Before public void setup(){ User user = new User(); user.setName("user"); user.setCreatedate(new Date()); userRedis.delete(this.getClass().getName()+":userByname:"+user.getName()); userRedis.add(this.getClass().getName()+":userByname:"+user.getName(), 10L, user); } @Test public void get(){ User user = userRedis.get(this.getClass().getName() + ":userByname:user"); Assert.notNull(user); logger.info("======user====== name:{}", user.getName()); } }