Spring Boot整合 NoSQL 数据库 Redis详解

yizhihongxing

下面我会给您讲解一下“Spring Boot整合 NoSQL 数据库 Redis”的完整攻略。

简介

Redis是一个基于内存的高性能key-value数据库,支持多种数据类型,可应用于缓存、消息队列、实时统计等场景。在Spring Boot应用中,我们可以很方便地集成Redis来实现快速高效的数据存取。

环境配置

要使用Redis,首先需要在本地安装Redis服务,可以去Redis官网下载并安装。安装完成后,启动Redis服务即可。

在Spring Boot项目中,我们需要引入Redis的依赖。可以在pom.xml文件中添加以下内容:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

Redis配置

在Spring Boot项目中,我们需要在application.properties文件中配置Redis连接信息,如下所示:

spring.redis.host=localhost
spring.redis.port=6379
spring.redis.password= # 如果Redis服务设置了密码,则需要填写密码信息

使用Redis

在Spring Boot项目中,可以通过注入RedisTemplate对象来使用Redis。RedisTemplate是Spring封装的Redis客户端,提供了一组操作Redis数据的方法。

以保存一个String类型的值为例,示例代码如下:

@Autowired
private RedisTemplate<String, String> redisTemplate;

public void save(String key, String value) {
    redisTemplate.opsForValue().set(key, value);
}

上面的代码中,redisTemplate.opsForValue()方法返回一个ValueOperations对象,可以使用这个对象来操作String类型的数据。set方法用于保存一个键值对。

示例一

下面我们通过一个简单示例来展示如何使用Redis实现缓存信息的存取。

首先定义一个用于查询员工信息的接口:

public interface EmployeeService {
    Employee getEmployeeById(Long id);
}

然后实现这个接口,这里我们通过休眠2秒钟的方式,模拟查询员工信息的耗时:

@Service
public class EmployeeServiceImpl implements EmployeeService {

    @Override
    public Employee getEmployeeById(Long id) {
        // 这里休眠2秒钟,模拟查询员工信息的耗时
        try {
            Thread.sleep(2000L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return new Employee(id, "张三", 30);
    }
}

接下来,我们定义一个用于缓存员工信息的接口:

public interface EmployeeCache {
    Employee getEmployeeById(Long id);
    void putEmployee(Employee employee);
}

然后通过Redis实现这个接口:

@Service
public class EmployeeCacheRedisImpl implements EmployeeCache {

    @Autowired
    private RedisTemplate<String, Employee> redisTemplate;

    @Override
    public Employee getEmployeeById(Long id) {
        String key = "employee:" + id;
        if (redisTemplate.hasKey(key)) {
            return redisTemplate.opsForValue().get(key);
        }

        Employee employee = getEmployeeFromDB(id);
        redisTemplate.opsForValue().set(key, employee);
        return employee;
    }

    @Override
    public void putEmployee(Employee employee) {
        String key = "employee:" + employee.getId();
        redisTemplate.opsForValue().set(key, employee);
    }

    private Employee getEmployeeFromDB(Long id) {
        // 这里只是简单模拟,实际开发中不应该这样做
        return new Employee(id, "张三", 30);
    }
}

上面的代码中,我们在getEmployeeById方法中,先从Redis缓存中获取员工信息,如果不存在,则通过getEmployeeFromDB方法从数据库中查询员工信息,并将查询结果保存到Redis缓存中。在保存到Redis缓存中时,我们使用了一个前缀employee:来区分不同的缓存信息。

最后,我们可以在Controller中使用这些接口:

@RestController
@RequestMapping("/employee")
public class EmployeeController {

    @Autowired
    private EmployeeService employeeService;

    @Autowired
    private EmployeeCache employeeCache;

    @GetMapping("/{id}")
    public Employee getEmployeeById(@PathVariable("id") Long id) {
        // 先从缓存中获取员工信息
        Employee employee = employeeCache.getEmployeeById(id);
        if (employee != null) {
            return employee;
        }

        // 如果缓存中不存在,则从数据库中获取员工信息,并保存到缓存中
        employee = employeeService.getEmployeeById(id);
        if (employee != null) {
            employeeCache.putEmployee(employee);
        }

        return employee;
    }
}

上面的代码中,我们先从缓存中获取员工信息,如果缓存中不存在,则通过getEmployeeById方法从数据库中获取,并将查询结果保存到缓存中。

示例二

接下来我们通过另一个简单示例来展示如何在Redis中使用Lua脚本。

首先定义一个用于扣减库存的接口:

public interface InventoryService {
    boolean reduceInventory(String sku, int quantity);
}

然后实现这个接口,这里我们使用了Redis中的decrBy命令来扣减库存,但是这个命令是原子操作,可能存在并发问题:

@Service
public class InventoryServiceImpl implements InventoryService {

    @Autowired
    private RedisTemplate<String, Integer> redisTemplate;

    @Override
    public boolean reduceInventory(String sku, int quantity) {
        String key = "inventory:" + sku;
        Integer stock = redisTemplate.opsForValue().get(key);
        if (stock == null || stock < quantity) {
            return false;
        }

        redisTemplate.opsForValue().decrement(key, quantity);
        return true;
    }
}

为了解决并发问题,我们可以使用Redis中的Lua脚本。Lua脚本可以保证操作的原子性,而且执行速度也很快。

我们可以将扣减库存的代码改写为Lua脚本,如下所示:

@Service
public class InventoryServiceImpl implements InventoryService {

    @Autowired
    private RedisTemplate<String, Integer> redisTemplate;

    @Override
    public boolean reduceInventory(String sku, int quantity) {
        String key = "inventory:" + sku;
        Integer stock = redisTemplate.opsForValue().get(key);
        if (stock == null || stock < quantity) {
            return false;
        }

        String script = "if redis.call('get', KEYS[1]) >= tonumber(ARGV[1]) then return redis.call('decrby', KEYS[1], ARGV[1]) else return 0 end";
        List<String> keys = new ArrayList<>();
        keys.add(key);
        List<String> args = new ArrayList<>();
        args.add(String.valueOf(quantity));
        Long result = redisTemplate.execute(new DefaultRedisScript<>(script, Long.class), keys, args);
        return result != null && result > 0;
    }
}

上面的代码中,我们使用了DefaultRedisScript对象来执行Lua脚本。在脚本中,我们首先判断库存是否足够,如果足够,则使用decrBy命令扣减库存。注意,在decrBy命令中,我们使用了ARGV[1]来表示传入的扣减数量。如果库存不足,则返回0。

最后,我们可以在Controller中使用这个接口:

@RestController
@RequestMapping("/inventory")
public class InventoryController {

    @Autowired
    private InventoryService inventoryService;

    @PostMapping("/reduce")
    public boolean reduceInventory(@RequestParam("sku") String sku, @RequestParam("quantity") int quantity) {
        return inventoryService.reduceInventory(sku, quantity);
    }
}

上面的代码中,我们通过POST请求来扣减库存。传入的参数包括产品SKU和扣减数量。

以上是关于Spring Boot整合Redis的完整攻略,提供了两个示例。希望可以对您有所帮助。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring Boot整合 NoSQL 数据库 Redis详解 - Python技术站

(0)
上一篇 2023年5月22日
下一篇 2023年5月22日

相关文章

  • mysql 获取今天、昨天0点时间戳的实例

    为了完整讲解“mysql 获取今天、昨天0点时间戳的实例”的攻略,我们可以分成以下几个步骤来完整讲解。 步骤一:获取昨天、今天的日期 要获取昨天和今天的日期,我们可以使用MySQL中的CURDATE()函数来获取当前时间。然后减去相应的时间间隔就可以得到昨天的日期。例如,要获取昨天的日期,可以使用以下代码: SELECT DATE_SUB(CURDATE()…

    database 2023年5月22日
    00
  • centos7安装mysql并jdbc测试实例详解

    CentOS7安装MySQL并JDBC测试实例详解 在CentOS7上安装MySQL,并使用Java Database Connectivity测试实例的步骤如下: 步骤一:安装MySQL 在CentOS7上使用以下命令安装MySQL: sudo yum install mysql-server 步骤二:启动MySQL服务 安装完成之后,启动MySQL服务:…

    database 2023年5月22日
    00
  • Redis高可用配置(Keepalived)

    主:172.16.0.104 备:172.16.0.105 VIP:172.16.0.107 客户端直接连VIP,当master 104的redis挂掉后,105作为master。当104重启后,104作为105的slave。当105又挂掉之后,104作为master…… 1、安装redis并配置主从同步      安装过程省略     1.1 配置…

    Redis 2023年4月13日
    00
  • mysql——索引的添加删除及排序

    今天一顿操作,猛如虎,把一个部署到2核4g的小服务器挂掉了。 幡然醒悟,关联操作还是要加上索引比较好,运行速度从几分钟迅速提到几秒。   1.mysql添加索引的方法主要有以下几种(可以对关联的字段提前建索引,然后再关联)。 a.添加PRIMARY KEY(主键索引) mysql>ALTER TABLE `table_name` ADD PRIMARY…

    MySQL 2023年4月13日
    00
  • sql 函数大全 比较常用的一些函数整理第1/2页

    首先,我们需要了解什么是SQL函数。在SQL中,函数是一些特殊的操作符,它们接受一些参数,执行特定的计算,并返回一个结果。SQL函数可以用于执行日期和时间处理、字符串操作、数学计算等一系列操作。本文将整理比较常用的SQL函数,让您更快更方便地查询、计算数据。 SQL 函数大全:比较常用的一些函数整理(第1/2页) 1. 字符串函数 常用的字符串函数包括: 1…

    database 2023年5月21日
    00
  • Linux 自动唤醒和关闭的实现方法

    下面是详细的讲解。 Linux 自动唤醒和关闭的实现方法 我们可以通过设置 BIOS 或者 ACPI(高级配置与电源管理接口)来实现 Linux 自动唤醒和关闭。其中,ACPI 是一种智能电源管理机制,它在操作系统内核和硬件之间起到桥梁的作用,可以实现更加高级的功能。 下面我们分别来讲解如何通过 BIOS 和 ACPI 来实现 Linux 自动唤醒和关闭。 …

    database 2023年5月22日
    00
  • MySQL联合索引用法示例

    MySQL的联合索引是由多个列组成的,可用于提高查询操作的性能。下面针对MySQL联合索引的用法进行详细讲解。 创建MySQL联合索引 在MySQL中,可以通过 ALTER TABLE 语句来创建联合索引。例如,我们创建一个由多个列组成的联合索引,语句如下: ALTER TABLE table_name ADD INDEX index_name (colum…

    database 2023年5月22日
    00
  • asp.net Accee数据库连接不稳定解决方案

    我来为您分享关于“asp.net Access数据库连接不稳定解决方案”的完整攻略。 问题描述 在asp.net开发中,有时会遇到Access数据库连接不稳定的情况,表现为应用程序启动时出现一些异常,或数据库连接断开等。这会导致用户无法正常操作应用程序,影响用户体验,甚至会导致数据丢失。 解决方案 为了解决这个问题,我们可以尝试以下的几种方法: 1. 使用连…

    database 2023年5月21日
    00
合作推广
合作推广
分享本页
返回顶部