百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

还在用 RedisTemplate?试试 Redis 官方 ORM 框架吧,用起来够优雅

mhr18 2024-10-27 10:50 43 浏览 0 评论

之前在SpringBoot项目中,我一直使用RedisTemplate来操作Redis中的数据,这也是Spring官方支持的方式。对比Spring Data对MongoDB和ES的支持,这种使用Template的方式确实不够优雅!最近发现Redis官方新推出了Redis的专属ORM框架RedisOM,用起来够优雅,推荐给大家!

RedisOM简介

RedisOM是Redis官方推出的ORM框架,是对Spring Data Redis的扩展。由于Redis目前已经支持原生JSON对象的存储,之前使用RedisTemplate直接用字符串来存储JOSN对象的方式明显不够优雅。通过RedisOM我们不仅能够以对象的形式来操作Redis中的数据,而且可以实现搜索功能!

JDK 11安装

由于目前RedisOM仅支持JDK 11以上版本,我们在使用前得先安装好它。

  • 首先下载JDK 11,这里推荐去清华大学开源软件镜像站下载,下载地址:https://mirrors.tuna.tsinghua.edu.cn/AdoptOpenJDK/11/jdk/x64/
  • 下载压缩包版本即可,下载完成后解压到指定目录;
  • 然后在IDEA的项目配置中,将对应模块的JDK依赖版本设置为JDK 11即可。

使用

接下来我们以管理存储在Redis中的商品信息为例,实现商品搜索功能。注意安装Redis的完全体版本RedisMod,具体可以参考RediSearch 使用教程 。

  • 首先在pom.xml中添加RedisOM相关依赖;
<!--Redis OM 相关依赖-->
<dependency>
    <groupId>com.redis.om</groupId>
    <artifactId>redis-om-spring</artifactId>
    <version>0.3.0-SNAPSHOT</version>
</dependency>
  • 由于RedisOM目前只有快照版本,还需添加快照仓库;
<repositories>
    <repository>
        <id>snapshots-repo</id>
        <url>https://s01.oss.sonatype.org/content/repositories/snapshots/</url>
    </repository>
</repositories>
  • 然后在配置文件application.yml中添加Redis连接配置;
spring:
  redis:
    host: 192.168.3.105 # Redis服务器地址
    database: 0 # Redis数据库索引(默认为0)
    port: 6379 # Redis服务器连接端口
    password: # Redis服务器连接密码(默认为空)
    timeout: 3000ms # 连接超时时间
  • 之后在启动类上添加@EnableRedisDocumentRepositories注解启用RedisOM的文档仓库功能,并配置好文档仓库所在路径;
@SpringBootApplication
@EnableRedisDocumentRepositories(basePackages = "com.macro.mall.tiny.*")
public class MallTinyApplication {

    public static void main(String[] args) {
        SpringApplication.run(MallTinyApplication.class, args);
    }

}
  • 然后创建商品的文档对象,使用@Document注解标识其为文档对象,由于我们的搜索信息中包含中文,我们需要设置语言为chinese
/**
 * 商品实体类
 * Created by macro on 2021/10/12.
 */
@Data
@EqualsAndHashCode(callSuper = false)
@Document(language = "chinese")
public class Product {
    @Id
    private Long id;
    @Indexed
    private String productSn;
    @Searchable
    private String name;
    @Searchable
    private String subTitle;
    @Indexed
    private String brandName;
    @Indexed
    private Integer price;
    @Indexed
    private Integer count;
}
  • 分别介绍下代码中几个注解的作用;
    • @Id:声明主键,RedisOM将会通过全类名:ID这样的键来存储数据;
    • @Indexed:声明索引,通常用在非文本类型上;
    • @Searchable:声明可以搜索的索引,通常用在文本类型上。
  • 接下来创建一个文档仓库接口,继承RedisDocumentRepository接口;
/**
 * 商品管理Repository
 * Created by macro on 2022/3/1.
 */
public interface ProductRepository extends RedisDocumentRepository<Product, Long> {
}
  • 创建测试用的Controller,通过Repository实现对Redis中数据的创建、删除、查询及分页功能;
/**
 * 使用Redis OM管理商品
 * Created by macro on 2022/3/1.
 */
@RestController
@Api(tags = "ProductController", description = "使用Redis OM管理商品")
@RequestMapping("/product")
public class ProductController {

    @Autowired
    private ProductRepository productRepository;

    @ApiOperation("导入商品")
    @PostMapping("/import")
    public CommonResult importList() {
        productRepository.deleteAll();
        List<Product> productList = LocalJsonUtil.getListFromJson("json/products.json", Product.class);
        for (Product product : productList) {
            productRepository.save(product);
        }
        return CommonResult.success(null);
    }

    @ApiOperation("创建商品")
    @PostMapping("/create")
    public CommonResult create(@RequestBody Product entity) {
        productRepository.save(entity);
        return CommonResult.success(null);
    }

    @ApiOperation("删除")
    @PostMapping("/delete/{id}")
    public CommonResult delete(@PathVariable Long id) {
        productRepository.deleteById(id);
        return CommonResult.success(null);
    }

    @ApiOperation("查询单个")
    @GetMapping("/detail/{id}")
    public CommonResult<Product> detail(@PathVariable Long id) {
        Optional<Product> result = productRepository.findById(id);
        return CommonResult.success(result.orElse(null));
    }

    @ApiOperation("分页查询")
    @GetMapping("/page")
    public CommonResult<List<Product>> page(@RequestParam(defaultValue = "1") Integer pageNum,
                                            @RequestParam(defaultValue = "5") Integer pageSize) {
        Pageable pageable = PageRequest.of(pageNum - 1, pageSize);
        Page<Product> pageResult = productRepository.findAll(pageable);
        return CommonResult.success(pageResult.getContent());
    }

}
  • 当我们启动项目时,可以发现RedisOM会自动为文档建立索引;
  • 接下来我们访问Swagger进行测试,先使用导入商品接口导入数据,访问地址:http://localhost:8088/swagger-ui/
  • 导入成功后我们可以发现RedisOM已经向Redis中插入了原生JSON数据,以全类名:ID的形式命名了键,同时将全部的ID存储到了一个SET集合中去了;
  • 我们可以通过ID来查询商品信息;
  • 当然RedisOM也是支持衍生查询的,通过我们创建的方法名称就可以自动实现查询逻辑,比如根据品牌名称查询商品,根据名称和副标题关键字来搜索商品;
/**
 * 商品管理Repository
 * Created by macro on 2022/3/1.
 */
public interface ProductRepository extends RedisDocumentRepository<Product, Long> {
    /**
     * 根据品牌名称查询
     */
    List<Product> findByBrandName(String brandName);

    /**
     * 根据名称或副标题搜索
     */
    List<Product> findByNameOrSubTitle(String name, String subTitle);
}
  • 在Controller中可以添加如下接口进行测试;
/**
 * 使用Redis OM管理商品
 * Created by macro on 2022/3/1.
 */
@RestController
@Api(tags = "ProductController", description = "使用Redis OM管理商品")
@RequestMapping("/product")
public class ProductController {

    @Autowired
    private ProductRepository productRepository;

    @ApiOperation("根据品牌查询")
    @GetMapping("/getByBrandName")
    public CommonResult<List<Product>> getByBrandName(String brandName) {
        List<Product> resultList = productRepository.findByBrandName(brandName);
        return CommonResult.success(resultList);
    }

    @ApiOperation("根据名称或副标题搜索")
    @GetMapping("/search")
    public CommonResult<List<Product>> search(String keyword) {
        List<Product> resultList = productRepository.findByNameOrSubTitle(keyword, keyword);
        return CommonResult.success(resultList);
    }

}
  • 我们可以通过品牌名称来查询商品;
  • 也可以通过关键字来搜索商品;
  • 这类根据方法名称自动实现查询逻辑的衍生查询有什么规则呢,具体可以参考下表。

总结

今天体验了一把RedisOM,用起来确实够优雅,和使用Spring Data来操作MongoDB和ES的方式差不多。不过目前RedisOM只发布了快照版本,期待Release版本的发布,而且Release版本据说会支持JDK 8的!

来源:https://mp.weixin.qq.com/s/s2MoZuapTiAUesYXpYSbhw

作者:梦想de星空

相关推荐

订单超时自动取消业务的 N 种实现方案,从原理到落地全解析

在分布式系统架构中,订单超时自动取消机制是保障业务一致性的关键组件。某电商平台曾因超时处理机制缺陷导致日均3000+订单库存锁定异常,直接损失超50万元/天。本文将从技术原理、实现细节、...

使用Spring Boot 3开发时,如何选择合适的分布式技术?

作为互联网大厂的后端开发人员,当你满怀期待地用上SpringBoot3,准备在项目中大显身手时,却发现一个棘手的问题摆在面前:面对众多分布式技术,究竟该如何选择,才能让SpringBoot...

数据库内存爆满怎么办?99%的程序员都踩过这个坑!

你的数据库是不是又双叒叕内存爆满了?!服务器监控一片红色警告,老板在群里@所有人,运维同事的电话打爆了手机...这种场景是不是特别熟悉?别慌!作为一个在数据库优化这条路上摸爬滚打了10年的老司机,今天...

springboot利用Redisson 实现缓存与数据库双写不一致问题

使用了Redisson来操作Redis分布式锁,主要功能是从缓存和数据库中获取商品信息,以下是针对并发时更新缓存和数据库带来不一致问题的解决方案1.基于读写锁和删除缓存策略在并发更新场景下,...

外贸独立站数据库炸了?对象缓存让你起死回生

上周黑五,一个客户眼睁睁看着服务器CPU飙到100%——每次页面加载要查87次数据库。这让我想起2024年Pantheon的测试:Redis缓存能把WooCommerce查询速度提升20倍。跨境电商最...

手把手教你在 Spring Boot3 里纯编码实现自定义分布式锁

为什么要自己实现分布式锁?你是不是早就受够了引入各种第三方依赖时的繁琐?尤其是分布式锁这块,每次集成Redisson或者Zookeeper,都得额外维护一堆配置,有时候还会因为版本兼容问题头疼半...

如何设计一个支持百万级实时数据推送的WebSocket集群架构?

面试解答:要设计一个支持百万级实时数据推送的WebSocket集群架构,需从**连接管理、负载均衡、水平扩展、容灾恢复**四个维度切入:连接层设计-**长连接优化**:采用Netty或Und...

Redis数据结构总结——面试最常问到的知识点

Redis作为主流的nosql存储,面试时经常会问到。其主要场景是用作缓存,分布式锁,分布式session,消息队列,发布订阅等等。其存储结构主要有String,List,Set,Hash,Sort...

skynet服务的缺陷 lua死循环

服务端高级架构—云风的skynet这边有一个关于云风skynet的视频推荐给大家观看点击就可以观看了!skynet是一套多人在线游戏的轻量级服务端框架,使用C+Lua开发。skynet的显著优点是,...

七年Java开发的一路辛酸史:分享面试京东、阿里、美团后的心得

前言我觉得有一个能够找一份大厂的offer的想法,这是很正常的,这并不是我们的饭后谈资而是每个技术人的追求。像阿里、腾讯、美团、字节跳动、京东等等的技术氛围与技术规范度还是要明显优于一些创业型公司...

mysql mogodb es redis数据库之间的区别

1.MySQL应用场景概念:关系型数据库,基于关系模型,使用表和行存储数据。优点:支持ACID事务,数据具有很高的一致性和完整性。缺点:垂直扩展能力有限,需要分库分表等方式扩展。对于复杂的查询和大量的...

redis,memcached,nginx网络组件

1.理解阻塞io,非阻塞io,同步io,异步io的区别2.理解BIO和AIO的区别io多路复用只负责io检测,不负责io操作阻塞io中的write,能写多少是多少,只要写成功就返回,譬如准备写500字...

SpringBoot+Vue+Redis实现验证码功能

一个小时只允许发三次验证码。一次验证码有效期二分钟。SpringBoot整合Redis...

AWS MemoryDB 可观测最佳实践

AWSMemoryDB介绍AmazonMemoryDB是一种完全托管的、内存中数据存储服务,专为需要极低延迟和高吞吐量的应用程序而设计。它与Redis和Memcached相似,但具有更...

从0构建大型AI推荐系统:实时化引擎从工具到生态的演进

在AI浪潮席卷各行各业的今天,推荐系统正从幕后走向前台,成为用户体验的核心驱动力。本文将带你深入探索一个大型AI推荐系统从零起步的全过程,揭示实时化引擎如何从单一工具演进为复杂生态的关键路径。无论你是...

取消回复欢迎 发表评论: