本章概要
- 整合Redis
NoSQL 是指非关系型数据库,非关系型数据库和关系型数据库两者存在许多显著的不同点,其中最重要的是 NoSQL 不使用 SQL 作为查询语言。其数据存储可以不需要固定的表格模式,一般都有水平可扩展的特性。NoSQL 主要有如下几种不同的分类:
- Key/Value 键值存储。这种数据存储通常都是无数据结构的,一般被当做字符串或者二进制数据,但是数据加载速度快,典型的使用场景是处理高并发或则用于日志系统等,这一类型的数据库有 Redis 、Tokyo Cabinet 等。
- 列存储数据库。列存储数据库功能相对局限,但是查找速度快,容易进行分布式扩展,一般用于分布式文件系统中,这一类的数据库有 HBase 、 Cassandra 等。
- 文档数据库。和 Key/Value 键值存储类似,文档型数据库也没有严格的数据格式,这既是缺点也是优势,因为不需要预先创建表结构,数据格式更加灵活,一般可用在 Web 应用中,这一类数据库有 MongoDB 、CouchDB 等。
- 图形数据库。图形数据库专注于构建关系图谱,例如社交网络,推荐系统等,这一类的数据库有 Neo4J、DEX等。
NoSQL 种类繁多,Spring Boot 对大多数 NoSQL 都提供了配置支持。
6.1 整合Redis
6.1.1 Redis 简介
Redis 是一个使用 C 编写的基于内存的 NoSQL 数据库,他是目前最流行的键值对存储数据库。Redis 由一个 Key、Value 映射的字典构成,与其他 NoSQL 不同,Redis 中 Value 的类型不局限于字符串,还支持列表、集合、有序集合、散列等。Redis 不仅可以当做缓存使用,也可以配置数据持久化后当作 NoSQL 数据库使用,目前支持两种持久化方式:快照持久化和 AOF 持久化。另一方面,Redis 也可以搭建集群或者主从复制结构,在高并发环境下具有高可用性。
6.1.2 Redis 安装
略(详见Centos安装Redis)
6.1.3 整合 Spring Boot
Redis 的 Java 客户端有很多,例如 Jedis、JRedis、Spring Data Redis 等,Spring Boot 借助 Spring Data Redis 为 Redis 提供了开箱即用自动化配置,开发者只需要添加相关依赖并配置 Redis 连接信息即可。
项目目录结构如下:
1. 创建 Spring Boot 项目
创建 Spring Boot Web 项目,添加如下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
默认情况下,spring-boot-starter-data-redis 使用的 Redis 工具是 Lettuce ,考虑到有的开发者习惯用 Jedis,因此可以从 spring-boot-starter-data-redis 中排除 Lettuce 并引入 Jedis ,修改为如下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<exclusions>
<exclusion>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
2. 配置 Redis
在application.properties 中配置 Redis 连接信息,如下
# ##################配置Redis连接##################
# redis使用第几个库
spring.redis.database=0
# redis地址
spring.redis.host=localhost
# redis端口
spring.redis.port=6379
# redis密码
spring.redis.password=123456
# redis连接池的最大连接数
spring.redis.jedis.pool.max-active=8
# redis连接池中最大空闲连接数
spring.redis.jedis.pool.max-idle=8
# redis连接池的最大阻塞等待时间,默认为-1,表示没有限制
spring.redis.jedis.pool.max-wait=-1ms
# redis连接池中最小空闲连接数
spring.redis.jedis.pool.min-idle=0
在 Spring Boot 的自动化配置类中提供了 RedisAutoConfiguration 进行 Redis 的配置,源码如下:
@AutoConfiguration
@ConditionalOnClass({
RedisOperations.class})
@EnableConfigurationProperties({
RedisProperties.class})
@Import({
LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class})
public class RedisAutoConfiguration {
public RedisAutoConfiguration() {
}
@Bean
@ConditionalOnMissingBean(
name = {
"redisTemplate"}
)
@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<Object, Object> template = new RedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
return template;
}
@Bean
@ConditionalOnMissingBean
@ConditionalOnSingleCandidate(RedisConnectionFactory.class)
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {
return new StringRedisTemplate(redisConnectionFactory);
}
}
由源码可以看到,application.properties 中配置的信息被注入到 RedisProperties 中,如果开发者没有提供 RedisTemplate 或者 StringRedisTemplate 实例,则 Spring Boot 默认会提供这两个实例,RedisProperties 和 StringRedisTemplate 实例则提供了 Redis 的基本操作方法。
3. 创建实体类
创建一个 Book 类,如下
public class Book implements Serializable {
private Integer id;
private String name;
private String author;
@Override
public String toString() {
return "Book{" +
"id=" + id +
", name='" + name + '\'' +
", author='" + author + '\'' +
'}';
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
}
4. 创建 Controller
@RestController
public class BookController {
@Autowired
RedisTemplate redisTemplate;
@Autowired
StringRedisTemplate stringRedisTemplate;
@GetMapping("/test1")
public void test1() {
ValueOperations<String, String> ops1 = stringRedisTemplate.opsForValue();
ops1.set("name", "三国演义");
String name = ops1.get("name");
System.out.println(name);
ValueOperations ops2 = redisTemplate.opsForValue();
Book b1 = new Book();
b1.setId(1);
b1.setName("红楼梦");
b1.setAuthor("曹雪芹");
ops2.set("b1", b1);
Book book = (Book) ops2.get("b1");
System.out.println(book);
}
}
代码解释:
- StringRedisTemplate 是 RedisTemplate 的子类,StringRedisTemplate 中的 Key 和 Value 都是字符串,采用的序列化方案是 StringRedisSerializer,而 RedisTemplate 则可以用来操作对象, RedisTemplate 采用的序列化方案是 JdkSerializationRedisSerializer。无论是 StringRedisTemplate 还是 RedisTemplate ,操作 Redis 的方法都是一致的
- StringRedisTemplate 和 RedisTemplate 都是通过 opsForValue、opsForZSet 或者 opsForSet 等方法首先获取一个操作对象,再使用该操作对象完成数据的读写
- ops1.set(“name”, “三国演义”) 向Redis 中存储一条记录,ops1.get(“name”) 将其取出来,ops2.set(“b1”, b1) 向 Redis 中存储一个对象,(Book) ops2.get(“b1”) 将其取出来
5. 测试
http://localhost:8081/test1,查看日志
三国演义
Book{id=1, name='红楼梦', author='曹雪芹'}