使用Spring Boot的Redis简介

本文的翻译是专门为“ 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; //standard getters and setters 

仓库接口


与其他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上

仅此而已。 传统上等待您的评论。

Source: https://habr.com/ru/post/zh-CN463365/


All Articles