Spring Boot整合 NoSQL 数据库 Redis详解

下面我会给您讲解一下“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远程连接不上的解决方法

    MySQL远程连接不上可能是因为以下原因: 1.防火墙问题 2.MySQL配置问题 3.权限问题 针对第一种情况,需要检查服务器的防火墙是否阻止了MySQL的连接。可以先关闭防火墙,测试一下是否能够连接MySQL。如果可以连接,说明是防火墙导致的。 要开放MySQL需要使用的端口(默认为3306),在Linux操作系统中使用iptables命令开放端口。可以…

    database 2023年5月22日
    00
  • redis三种连接方式

    安装 tar zxvf redis-2.8.9.tar.gz cd redis-2.8.9 #直接make 编译 make #可使用root用户执行`make install`,将可执行文件拷贝到/usr/local/bin目录下。这样就可以直接敲名字运行程序了。 make install 启动 #加上`&`号使redis以后台程序方式运行 ./re…

    Redis 2023年4月12日
    00
  • Oracle AWR(自动工作量资料档案库)的管理与维护详解

    Oracle AWR的管理与维护详解 简介 Oracle AWR(自动工作量资料档案库)是Oracle数据库自带的一个工具,可以记录数据库的性能数据并生成性能分析报告。通过对AWR报告的分析,可以定位数据库出现性能问题的原因并进行优化。 AWR的管理与维护是使用Oracle数据库的必备技能之一。下面将详细介绍如何管理和维护AWR。 开启AWR 在Oracle…

    database 2023年5月22日
    00
  • MongoDB聚合分组取第一条记录的案例与实现方法

    下面是详细的讲解“MongoDB聚合分组取第一条记录的案例与实现方法”的完整攻略。 案例说明 假设我们有一个用户评论的集合(collection),每条评论包含以下字段: _id:评论ID。 userId:用户ID。 content:评论内容。 createTime:评论时间。 现在我们需要对所有评论按照用户进行分组,取每个用户的最新评论进行展示。具体实现方…

    database 2023年5月22日
    00
  • 详解CentOS7下PostgreSQL 11的安装和配置教程

    详解CentOS7下PostgreSQL 11的安装和配置教程 本文将介绍在 CentOS 7 系统下安装 PostgreSQL 11 数据库的详细步骤和配置。 步骤一:安装 PostgreSQL 11 更新系统软件源 $ yum update -y 添加 PostgreSQL 的官方仓库 $ rpm -ivh https://download.postgr…

    database 2023年5月22日
    00
  • Oracle 12.2监听无法启动解决方法

    为了解决Oracle 12.2监听无法启动的问题,需要按照以下步骤进行操作: 确认监听进程是否在运行 在解决问题之前,先要确认是否存在监听进程。可以通过执行以下命令来检查监听进程: ps -ef | grep tns 如果没有监听进程运行,需要执行以下步骤来启动监听进程。 启动监听进程 检查“listener.ora”文件的配置 在运行监听进程之前,需要确保…

    database 2023年5月22日
    00
  • Linux常用命令last的使用方法详解

    Linux常用命令last的使用方法详解 什么是last命令? last命令是一个Linux系统中常用的命令之一,用于列出已经登录过系统的用户列表,并显示其登录的时间、登录方式、登录IP地址等信息,可用于审计用户行为,也可以用于检查系统安全。 last命令的语法 last命令的语法如下: last [参数] [选项] [用户名] [终端] 参数:用于指定输出…

    database 2023年5月22日
    00
  • 数据库索引并不是万能药

    数据库索引并不是万能药 引言 很多人认为,加上索引可以加速查询,甚至认为索引是提高数据库性能的唯一途径。但实际上,不管是哪一种数据库,在指定条件下,都会因索引而产生一定的开销甚至会导致性能下降。因此,合理使用索引是提升数据库性能的一个重要方面,并非一个万能药。 索引的优势 提升查询效率:索引可以将检索记录的一个大集合快速转化为一个小集合。 保证数据的唯一性:…

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