Spring Boot Redis简介

1.概述

在本文中,我们将通过Spring Data Redis库回顾如何在Spring Boot中使用Redis

我们将构建一个应用程序,演示如何通过Web界面执行CRUD RedisGithub上提供了该项目的完整源代码。

2.什么是Redis?

Redis是一个开源的内存中键值数据存储,用作数据库,缓存和消息代理。 在实现方面,键值存储代表NoSQL空间中最大和最旧的成员之一。 Redis支持带范围查询的数据结构,例如字符串,哈希,列表,集合和排序集合。

通过为数据存储提供抽象, Spring Data Redis框架使编写使用Redis键值存储的Spring应用程序变得容易。

3.设置Redis服务器

该服务器可从http://redis.io/download免费获得。

如果您使用的是Mac,则可以通过自制软件安装它:

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

4. 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>

5. Redis配置

我们需要将我们的应用程序与Redis服务器连接。 为了建立这种连接,我们使用Redis客户端实现Jedis

5.1配置

让我们从配置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来查询数据。

5.2消息发布者

遵循SOLID原理,我们创建一个MessagePublisher接口:

public interface MessagePublisher {

    void publish(final String message);
}

我们实现了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接口:每次收到新消息时,都会调用回调,并通过名为onMessage的方法执行用户代码。 该接口可访问消息,已通过其接收消息的通道以及订阅使用的与该通道匹配的任何模式。

因此,我们创建一个服务类来实现MessageSubscriber

@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());
    }

6. Redis存储库

现在,我们已经配置了应用程序以与Redis服务器交互,我们将准备应用程序以获取示例数据。

6.1模型

在此示例中,我们定义了具有两个字段的Movie模型:

private String id;
private String name;
//standard getters and setters

6.2储存库界面

与其他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);
    
}

6.3资料库的实施

我们的实现类使用我们的配置类RedisConfig定义的redisTemplate。

我们使用Spring Data Redis提供的HashOperations模板:

@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()的函数该函数返回对绑定到给定键的哈希值执行的操作。 然后,我们将init()中定义的hashOps用于所有CRUD操作。

7. Web界面

在本节中,我们将回顾向Web界面添加Redis CRUD操作功能。

7.1添加电影

我们希望能够在我们的网页中添加电影。 关键是电影ID ,值是实际对象。 但是,我们稍后将解决此问题,因此仅将电影名称显示为值。

因此,让我们将表单添加到HTML文档中,并分配适当的名称和ID:

<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);
    }

7.2查看内容

添加Movie对象后,我们将刷新表以显示更新的表。 在7.1节JavaScript代码块中,我们调用了一个名为refreshTable()JavaScript函数。 此函数执行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;
    }

7.3删除电影

我们编写Javascript来执行POST请求 / delete ,刷新表,并将键盘焦点设置为按键输入:

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);
    }

8.演示

在这里,我们添加了两部电影:

在这里,我们删除了一部电影:

9.结论

在本教程中,我们介绍了Spring Data Redis,以及将其连接到Web应用程序以执行CRUD操作的一种方法。

示例应用程序的源代码在Github上

翻译自: https://www.javacodegeeks.com/2017/11/intro-redis-spring-boot.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值