本文的翻译是专门为“ Spring框架开发人员 ”课程的学生准备的。
在本文中,我们将介绍使用Spring Data Redis库通过Spring Boot使用Redis的基础知识。

我们将创建一个应用程序,演示如何通过Web界面执行CRUD操作。 该项目的源代码
可在GitHub上找到 。
什么是Redis?
Redis是用于
键-值数据结构的开源数据仓库,可以用作数据库,缓存和消息代理。 从实现的角度来看,键值存储是NoSQL世界中最大和最古老的代表。 Redis支持带有范围查询的数据结构,例如字符串,哈希,列表,集合和排序集合。
Spring Data Redis框架使编写使用Redis存储的Spring应用程序变得容易,从而提供了数据存储的便捷抽象。
Redis服务器设置
该服务器可在
此处免费使用。
如果您使用的是Mac,则可以使用
homebrew
安装它:
brew install redis
然后启动服务器:
mikes-MacBook-Air:~ mike$ redis-server 10699:C 23 Nov 08:35:58.306 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo 10699:C 23 Nov 08:35:58.307 # Redis version=4.0.2, bits=64, commit=00000000, modified=0, pid=10699, just started 10699:C 23 Nov 08:35:58.307 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf 10699:M 23 Nov 08:35:58.309 * Increased maximum number of open files to 10032 (it was originally set to 256). _._ _.-``__ ''-._ _.-`` `. `_. ''-._ Redis 4.0.2 (00000000/0) 64 bit .-`` .-```. ```\/ _.,_ ''-._ ( ' , .-` | `, ) Running in standalone mode |`-._`-...-` __...-.``-._|'` _.-'| Port: 6379 | `-._ `._ / _.-' | PID: 10699 `-._ `-._ `-./ _.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | http://redis.io `-._ `-._`-.__.-'_.-' _.-' |`-._`-._ `-.__.-' _.-'_.-'| | `-._`-._ _.-'_.-' | `-._ `-._`-.__.-'_.-' _.-' `-._ `-.__.-' _.-' `-._ _.-' `-.__.-' 10699:M 23 Nov 08:35:58.312 # Server initialized 10699:M 23 Nov 08:35:58.312 * Ready to accept connections
Maven依赖
让我们在要使用的应用程序的
pom.xml
声明必要的依赖关系:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
Redis配置
我们需要将我们的应用程序与Redis服务器连接。 为了建立连接,我们使用Redis的客户端实现
Jedis 。
构型
让我们从配置bean的定义开始:
@Bean JedisConnectionFactory jedisConnectionFactory() { return new JedisConnectionFactory(); } @Bean public RedisTemplate<String, Object> redisTemplate() { final RedisTemplate<String, Object> template = new RedisTemplate<String, Object>(); template.setConnectionFactory(jedisConnectionFactory()); template.setValueSerializer(new GenericToStringSerializer<Object>(Object.class)); return template; }
JedisConnectionFactory
以bean的形式出现,因此我们可以创建
RedisTemplate
来请求数据。
帖子发布者
遵循
SOLID的
原理 ,我们创建
MessagePublisher
接口:
public interface MessagePublisher { void publish(final String message); }
我们使用高级RedisTemplate来实现
MessagePublisher
接口来发布消息,因为
RedisTemplate
允许
RedisTemplate
将任意对象作为消息发送:
@Service public class MessagePublisherImpl implements MessagePublisher { @Autowired private RedisTemplate<String, Object> redisTemplate; @Autowired private ChannelTopic topic; public MessagePublisherImpl() { } public MessagePublisherImpl(final RedisTemplate<String, Object> redisTemplate, final ChannelTopic topic) { this.redisTemplate = redisTemplate; this.topic = topic; } public void publish(final String message) { redisTemplate.convertAndSend(topic.getTopic(), message); } }
我们还将其定义为
RedisConfig
的bean:
@Bean MessagePublisher redisPublisher() { return new MessagePublisherImpl(redisTemplate(), topic()); }
邮件收件人
要订阅消息,您需要实现
MessageListener
接口:每次
MessageListener
新消息时,都会
onMessage
方法中的用户代码。 该接口提供对消息(接收消息的通道)的访问,并允许您使用用于订阅该通道的任何模板。
@Service public class MessageSubscriber implements MessageListener { public static List<String> messageList = new ArrayList<String>(); public void onMessage(final Message message, final byte[] pattern) { messageList.add(message.toString()); System.out.println("Message received: " + new String(message.getBody())); } }
另外,此类必须在
RedisConfig
注册为Bean:
@Bean MessageListenerAdapter messageListener() { return new MessageListenerAdapter(new MessageSubscriber()); }
重新存储库
现在,我们已经设置了与Redis服务器交互的应用程序,我们将准备该应用程序以接收测试数据。
型号
在此示例中,我们定义了具有两个字段的
Movie
模型:
private String id; private String name;
仓库接口
与其他Spring Data项目不同,Spring Data Redis提供了在其他Spring Data接口之上工作所需的一切。 对于有其他Spring Data项目经验的人来说,这看起来很奇怪。
通常,无需使用Spring Data项目编写存储库接口实现。 我们只是与界面进行交互。 Spring Data JPA提供了许多存储库接口,可以扩展它们以提供诸如CRUD操作,派生查询和分页之类的功能。
因此,不幸的是,我们需要
编写自己的接口,然后定义方法 :
public interface RedisRepository { Map<Object, Object> findAllMovies(); void add(Movie movie); void delete(String id); Movie findMovie(String id); }
仓库实施
该类使用
RedisConfig
配置
RedisConfig
定义的
RedisConfig
。
我们使用
HashOperations
,Spring Data Redis提供了以下功能:
@Repository public class RedisRepositoryImpl implements RedisRepository { private static final String KEY = "Movie"; private RedisTemplate<String, Object> redisTemplate; private HashOperations hashOperations; @Autowired public RedisRepositoryImpl(RedisTemplate<String, Object> redisTemplate){ this.redisTemplate = redisTemplate; } @PostConstruct private void init(){ hashOperations = redisTemplate.opsForHash(); } public void add(final Movie movie) { hashOperations.put(KEY, movie.getId(), movie.getName()); } public void delete(final String id) { hashOperations.delete(KEY, id); } public Movie findMovie(final String id){ return (Movie) hashOperations.get(KEY, id); } public Map<Object, Object> findAllMovies(){ return hashOperations.entries(KEY); } }
让我们注意
init()
方法。 在此方法中,我们使用名为
opsForHash()
的函数,该函数返回使用与此键
opsForHash()
哈希值执行的操作。 然后,我们将
init()
定义的
hashOps
用于所有CRUD操作。
网页界面
在本节中,我们将研究向Web界面添加Redis CRUD功能。
添加电影
我们希望能够通过网页添加电影。 关键是电影的标识符,而值是实际的对象。 但是,稍后我们将返回此内容,因此仅将电影的名称显示为该值。
让我们向HTML文档添加一个表单,并分配适当的名称和标识符:
<form id="addForm"> <div class="form-group"> <label for="keyInput">Movie ID (key)</label> <input name="keyInput" id="keyInput" class="form-control"/> </div> <div class="form-group"> <label for="valueInput">Movie Name (field of Movie object value)</label> <input name="valueInput" id="valueInput" class="form-control"/> </div> <button class="btn btn-default" id="addButton">Add</button> </form>
现在,我们使用JavaScript来保存提交表单时的值:
$(document).ready(function() { var keyInput = $('#keyInput'), valueInput = $('#valueInput'); refreshTable(); $('#addForm').on('submit', function(event) { var data = { key: keyInput.val(), value: valueInput.val() }; $.post('/add', data, function() { refreshTable(); keyInput.val(''); valueInput.val(''); keyInput.focus(); }); event.preventDefault(); }); keyInput.focus(); });
我们为POST请求设置
@RequestMapping
参数,请求键和值,创建一个
Movie
对象并将其保存在存储库中:
@RequestMapping(value = "/add", method = RequestMethod.POST) public ResponseEntity<String> add( @RequestParam String key, @RequestParam String value) { Movie movie = new Movie(key, value); redisRepository.add(movie); return new ResponseEntity<>(HttpStatus.OK); }
查看内容
添加Movie对象后,我们将更新表以显示新值。 在JavaScript代码块中,我们调用了
refreshTable()
函数。 它执行GET请求以检索存储库中的当前数据:
function refreshTable() { $.get('/values', function(data) { var attr, mainTable = $('#mainTable tbody'); mainTable.empty(); for (attr in data) { if (data.hasOwnProperty(attr)) { mainTable.append(row(attr, data[attr])); } } }); }
GET请求由
findAll()
方法处理,该方法检索存储在存储中的所有Movie对象,然后将数据类型从
Map <Object, Object>
为
Map <String, String>
:
@RequestMapping("/values") public @ResponseBody Map<String, String> findAll() { Map<Object, Object> aa = redisRepository.findAllMovies(); Map<String, String> map = new HashMap<String, String>(); for(Map.Entry<Object, Object> entry : aa.entrySet()){ String key = (String) entry.getKey(); map.put(key, aa.get(key).toString()); } return map; }
电影删除
我们将编写一个脚本来沿
/delete
路径执行POST请求,更新表并切换键盘焦点以方便输入:
function deleteKey(key) { $.post('/delete', {key: key}, function() { refreshTable(); $('#keyInput').focus(); }); }
我们请求一个密钥,并基于此密钥删除
redisRepository
的对象:
@RequestMapping(value = "/delete", method = RequestMethod.POST) public ResponseEntity<String> delete(@RequestParam String key) { redisRepository.delete(key); return new ResponseEntity<>(HttpStatus.OK); }
演示版
在这里,我们添加了两部电影:

一部电影被删除了:

结论
在本指南中,我们研究了Spring Data Redis,以及将其连接到Web应用程序以执行CRUD操作的一种方法。
该示例应用程序的源代码位于
GitHub上 。
仅此而已。 传统上等待您的评论。