1. 前言
上一篇文章整合了springboot+spring mvc+mybatis,基于三层架构搭建了一个接口平台。这篇文章主要整合一下springboot和redis的框架,redis也是目前使用较多的nosql数据库。
这篇文章的整个项目框架都是基于上一篇文章的,所以很多配置或者代码不会写完。
2. redis简介与环境搭建
2.1 redis简介
redis是一个key-value。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set --有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。(来自百度百科)
Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets)与范围查询, bitmaps, hyperloglogs和 地理空间(geospatial)索引半径查询。 Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions)和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。(来自redis中文官方网站)
这里贴上redis中文网地址,很好的一个redis学习网站。redis中文官方网站
2.2. redis特点
- Redis将其数据库完全保存在内存中,仅使用磁盘进行持久化。
- 与其它键值数据存储相比,Redis有一组相对丰富的数据类型。
- Redis可以将数据复制到任意数量的从机中。
2.3. redis优点
- 异常快 - Redis非常快,每秒可执行大约110000次的设置(SET)操作,每秒大约可执行81000次的读取/获取(GET)操作。
- 支持丰富的数据类型 - Redis支持开发人员常用的大多数数据类型,例如列表,集合,排序集和散列等等。这使得Redis很容易被用来解决各种问题,因为我们知道哪些问题可以更好使用地哪些数据类型来处理解决。
- 操作具有原子性 - 所有Redis操作都是原子操作,这确保如果两个客户端并发访问,Redis服务器能接收更新的值。
- 多实用工具 - Redis是一个多实用工具,可用于多种用例,如:缓存,消息队列(Redis本地支持发布/订阅),应用程序中的任何短期数据,例如,web应用程序中的会话,网页命中计数等。
2.4 redis安装
因为电脑是Windows系统,这里就介绍一下Windows系统下的安装。linux系统下的安装请另行百度。redis在Windows下的安装十分简单。
- 下载redis:Redis 没有官方的Windows版本,但是微软开源技术团队(Microsoft Open Tech group)开发和维护着这个 Win64 的版本。所以可以在这里下载releases版本的。https://github.com/MicrosoftArchive/redis/releases。
解压出来的目录:
- 启动redis:在这个目录下cmd,然后直接redis-server.exe redis.windows.conf,即可启动redis。
- 修改密码:在使用之前,先修改一下redis的密码。在先前那个解压目录下,打开redis-cli.exe。
- 输入config get requirepass可查看当前密码,这里是我已经改过密码之后的。
- 然后输入 config set requirepass "yourpassword" 可修改redis的密码。
- 连接redis:这里我是使用的RedisDesktopManager进行连接,这个是一个可视化管理redis的界面工具,下载windows版本的就行。https://redisdesktop.com/download
然后在这个工具里可使用redis基本操作,这里有一些我已经添加进去的数据:
3. springboot中redis相关配置
- 在pom中配置redis的相关依赖包:
org.springframework.boot
spring-boot-starter-redis
1.3.8.RELEASE
- 上一篇文章中已经写道,springboot的习惯优于配置。也在项目中使用了application.yml文件配置mysql的基本配置项。这里也在application.yml里面配置redis的配置项。
spring:
datasource:
# 驱动配置信息
url: jdbc:mysql://localhost:3306/spring_boot?useUnicode=true&characterEncoding=utf8
username: root
password: root
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
# 连接池的配置信息
filters: stat
maxActive: 20
initialSize: 1
maxWait: 60000
minIdle: 1
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: select 'x'
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
maxOpenPreparedStatements: 20
redis:
host: 127.0.0.1
port: 6379
password: pass1234
pool:
max-active: 100
max-idle: 10
max-wait: 100000
timeout: 0
比上一篇文章中多的就是redis下面的几个,分别是主机,端口和密码,其他还有很多配置项,具体可另在网上搜索了解。
4. springboot中redis相关类
- 项目操作redis是使用的RedisTemplate方式,另外还可以完全使用JedisPool和Jedis来操作redis。整合的内容也是从网上收集整合而来,网上整合的方式和方法非常的多,有使用注解形式的,有使用Jackson2JsonRedisSerializer来序列化和反序列化key value的值等等,很多很多。这里使用的是我认为比较容易理解和掌握的,基于JedisPool配置,使用RedisTemplate来操作redis的方式。
- redis单独放在一个包redis里,在包里先创建RedisConfig.java文件。
RedisConfig.java
@Configuration
@EnableAutoConfiguration
public class RedisConfig {
@Bean
@ConfigurationProperties(prefix = "spring.redis.pool")
public JedisPoolConfig getRedisConfig(){
JedisPoolConfig config = new JedisPoolConfig();
return config;
}
@Bean
@ConfigurationProperties(prefix = "spring.redis")
public JedisConnectionFactory getConnectionFactory() {
JedisConnectionFactory factory = new JedisConnectionFactory();
factory.setUsePool(true);
JedisPoolConfig config = getRedisConfig();
factory.setPoolConfig(config);
return factory;
}
@Bean
public RedisTemplate, ?> getRedisTemplate() {
JedisConnectionFactory factory = getConnectionFactory();
RedisTemplate, ?> template = new StringRedisTemplate(factory);
return template;
}
}
以上三个方法分别为获取JedisPoolConfig配置、获取JedisConnectionFactory工厂和获取RedisTemplate模板。
@Configuration 注解是用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法将会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext类进行扫描,并用于构建bean定义,初始化Spring容器。
@EnableAutoConfiguration 注解是启用Spring应用程序上下文的自动配置,尝试猜测和配置您可能需要的bean。自动配置类通常基于类路径和定义的bean应用。
@ConfigurationProperties 注解是用于读取配置文件的信息,在这里是读取配置在yml里的redis的相关配置项。
@Bean 注解用在方法上,告诉Spring容器,你可以从下面这个方法中拿到一个Bean
- 在包里创建RedisService接口,在这个接口定义了一些redis的基本操作。在这里我把所有存取操作都封装成了基于json字符串完成,就没有对于list或者对于object等单独定义方法。所有的数据类型的存储都由代码转换成json字符串方式进行。所以这里就只有四个方法。
RedisService.java
public interface RedisService {
/**
* set存数据
* @param key
* @param value
* @return
*/
boolean set(String key, String value);
/**
* get获取数据
* @param key
* @return
*/
String get(String key);
/**
* 设置有效天数
* @param key
* @param expire
* @return
*/
boolean expire(String key, long expire);
/**
* 移除数据
* @param key
* @return
*/
boolean remove(String key);
}
- 在包里创建RedisService接口的实现类RedisServiceImpl,这个类实现了接口的所有方法。
RedisServiceImpl.java
@Service("redisService")
public class RedisServiceImpl implements RedisService {
@Resource
private RedisTemplate redisTemplate;
@Override
public boolean set(final String key, final String value) {
boolean result = redisTemplate.execute(new RedisCallback() {
@Override
public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
RedisSerializer serializer = redisTemplate.getStringSerializer();
connection.set(serializer.serialize(key), serializer.serialize(value));
return true;
}
});
return result;
}
@Override
public String get(final String key) {
String result = redisTemplate.execute(new RedisCallback() {
@Override
public String doInRedis(RedisConnection connection) throws DataAccessException {
RedisSerializer serializer = redisTemplate.getStringSerializer();
byte[] value = connection.get(serializer.serialize(key));
return serializer.deserialize(value);
}
});
return result;
}
@Override
public boolean expire(final String key, long expire) {
return redisTemplate.expire(key, expire, TimeUnit.SECONDS);
}
@Override
public boolean remove(final String key) {
boolean result = redisTemplate.execute(new RedisCallback() {
@Override
public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
RedisSerializer serializer = redisTemplate.getStringSerializer();
connection.del(key.getBytes());
return true;
}
});
return result;
}
}
在这里execute()方法具体的底层没有去研究,只知道这样能实现对于redis数据的操作。
redis保存的数据会在内存和硬盘上存储,所以需要做序列化;这个里面使用的StringRedisSerializer来做序列化,不过这个方式的泛型指定的是String,只能传String进来。所以项目中采用json字符串做redis的交互。
到此,redis在springboot中的整合已经完毕,下面就来测试使用一下。
5. springboot项目中使用redis
在这里就直接使用springboot项目中自带的单元测试类SpringbootApplicationTests进行测试。
SpringbootApplicationTests.java
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootApplicationTests {
private JSONObject json = new JSONObject();
@Autowired
private RedisService redisService;
@Test
public void contextLoads() throws Exception {
}
/**
* 插入字符串
*/
@Test
public void setString() {
redisService.set("redis_string_test", "springboot redis test");
}
/**
* 获取字符串
*/
@Test
public void getString() {
String result = redisService.get("redis_string_test");
System.out.println(result);
}
/**
* 插入对象
*/
@Test
public void setObject() {
Person person = new Person("person", "male");
redisService.set("redis_obj_test", json.toJSONString(person));
}
/**
* 获取对象
*/
@Test
public void getObject() {
String result = redisService.get("redis_obj_test");
Person person = json.parseObject(result, Person.class);
System.out.println(json.toJSONString(person));
}
/**
* 插入对象List
*/
@Test
public void setList() {
Person person1 = new Person("person1", "male");
Person person2 = new Person("person2", "female");
Person person3 = new Person("person3", "male");
List list = new ArrayList<>();
list.add(person1);
list.add(person2);
list.add(person3);
redisService.set("redis_list_test", json.toJSONString(list));
}
/**
* 获取list
*/
@Test
public void getList() {
String result = redisService.get("redis_list_test");
List list = json.parseArray(result, String.class);
System.out.println(list);
}
@Test
public void remove() {
redisService.remove("redis_test");
}
}
class Person {
private String name;
private String sex;
public Person() {
}
public Person(String name, String sex) {
this.name = name;
this.sex = sex;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
在这里先是用@Autowired注解把redisService注入进来,然后由于是使用json字符串进行交互,所以引入fastjson的JSONObject类。然后为了方便,直接在这个测试类里面加了一个Person的内部类。
一共测试了:对于string类型的存取,对于object类型的存取,对于list类型的存取,其实本质都是转成了json字符串。还有就是根据key来执行remove操作。
获取字符串:
获取对象:
获取list:
redis管理客户端数据:
到此,测试完成,对于常用的一些数据类型的转换存取操作也基本调试通过。所以本文对于springboot整合redis到此结束。
小生水平有限,不喜勿喷。这是我在学习、工作过程中,经历和使用后整合的基础教程,非常简单和基础,只适合新手学习。
有很多不足之处,另外也还有很多其他方式方法,希望各位大大不吝赐教。
目前全部文章列表:
idea整合restful风格的ssm框架(一)
idea整合restful风格的ssm框架(二)
idea整合spring boot+spring mvc+mybatis框架
idea整合springboot+redis
JVM学习之—Java内存区域
JVM学习之—垃圾回收与内存分配策略
专题整理之—不可变对象与String的不可变
专题整理之—String的字符串常量池