news 2026/8/10 7:34:24

【基于SpringBoot的图书购买系统】Redis中的数据以分页的形式展示:从配置到前后端交互的完整实现

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【基于SpringBoot的图书购买系统】Redis中的数据以分页的形式展示:从配置到前后端交互的完整实现

基于 Spring Boot 的图书购买系统:Redis 中的数据以分页形式展示完整实现

在图书购买系统中,我们常常需要将图书数据缓存到 Redis 中(如热门图书列表),并支持分页展示。这可以提高查询效率,避免频繁访问数据库。本教程基于 Spring Boot 3.x(最新 LTS 版本),使用 Redis 作为缓存层,实现从配置到前后端交互的完整流程。

前提假设

  • 项目使用 Spring Boot + Redis + Spring Data Redis。
  • 图书实体(Book):包含 id、title、author、price 等字段。
  • 数据存储在 Redis 的 List 或 Sorted Set 中(推荐 Sorted Set 以支持排序和高效分页)。
  • 分页策略:Redis 无原生分页,使用 ZRANGE(Sorted Set)或 LRANGE(List)模拟。基于工具搜索结果,Sorted Set 是高效选择(O(log N + M) 复杂度,M 为页面大小)。
  • 前端:简单使用 HTML + JavaScript(Fetch API)调用 REST 接口展示分页数据。生产环境可换 Vue/React。

项目结构概览

src/main/java ├── com.example.bookstore │ ├── BookstoreApplication.java │ ├── config/RedisConfig.java │ ├── entity/Book.java │ ├── service/BookService.java │ ├── controller/BookController.java resources/application.properties frontend/index.html // 前端页面(可选,放在 static 目录或单独前端项目)
步骤 1: 项目初始化与依赖配置
  1. 创建 Spring Boot 项目

    • 使用 Spring Initializr(https://start.spring.io/)创建项目。
    • 选择:Spring Boot 3.2.x、Java 17+、依赖:Spring Web、Spring Data Redis、Lombok(可选)。
  2. 添加依赖(pom.xml):

<dependencies><!-- Spring Boot Starter --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Redis --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!-- Lombok 简化代码 --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency></dependencies>
  1. 安装 Redis
    • Windows/macOS:下载 Redis 官方版或用 Docker:docker run -d -p 6379:6379 redis
    • 默认端口 6379,无密码。
步骤 2: Redis 配置
  1. application.properties配置 Redis 连接:
# Redis 配置 spring.data.redis.host=localhost spring.data.redis.port=6379 # 可选:密码、数据库 # spring.data.redis.password=yourpassword # spring.data.redis.database=0 # 缓存配置(可选,启用缓存) spring.cache.type=redis spring.cache.redis.time-to-live=600000 # 缓存 TTL 10 分钟
  1. Redis 配置类(RedisConfig.java):自定义 RedisTemplate,支持序列化。
packagecom.example.bookstore.config;importorg.springframework.context.annotation.Bean;importorg.springframework.context.annotation.Configuration;importorg.springframework.data.redis.connection.RedisConnectionFactory;importorg.springframework.data.redis.core.RedisTemplate;importorg.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;importorg.springframework.data.redis.serializer.RedisSerializer;@ConfigurationpublicclassRedisConfig{@BeanpublicRedisTemplate<String,Object>redisTemplate(RedisConnectionFactoryconnectionFactory){RedisTemplate<String,Object>template=newRedisTemplate<>();template.setConnectionFactory(connectionFactory);// 使用 JSON 序列化(支持复杂对象)RedisSerializer<?>jsonSerializer=newGenericJackson2JsonRedisSerializer();template.setDefaultSerializer(jsonSerializer);template.setKeySerializer(RedisSerializer.string());template.setHashKeySerializer(RedisSerializer.string());template.setValueSerializer(jsonSerializer);template.setHashValueSerializer(jsonSerializer);returntemplate;}}
  • 解释:默认 StringRedisTemplate 只支持字符串;这里用 RedisTemplate 支持对象存储。JSON 序列化便于存储 Book 对象。
步骤 3: 图书实体与数据存储到 Redis
  1. Book 实体(Book.java):
packagecom.example.bookstore.entity;importlombok.Data;@DatapublicclassBook{privateLongid;privateStringtitle;privateStringauthor;privateDoubleprice;}
  1. BookService:存储图书到 Redis 的 Sorted Set(键:“books”,score 为 id 或 price 以支持排序)。
packagecom.example.bookstore.service;importcom.example.bookstore.entity.Book;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.data.redis.core.RedisTemplate;importorg.springframework.data.redis.core.ZSetOperations;importorg.springframework.stereotype.Service;importjava.util.List;importjava.util.Set;importjava.util.stream.Collectors;@ServicepublicclassBookService{@AutowiredprivateRedisTemplate<String,Object>redisTemplate;privatestaticfinalStringBOOKS_KEY="books";// Redis Sorted Set 键// 添加图书(score 为 id,假设 id 自增)publicvoidaddBook(Bookbook){ZSetOperations<String,Object>zSetOps=redisTemplate.opsForZSet();zSetOps.add(BOOKS_KEY,book,book.getId());// score = id}// 分页查询(使用 ZRANGE 模拟分页)publicList<Book>getBooksByPage(intpage,intsize){ZSetOperations<String,Object>zSetOps=redisTemplate.opsForZSet();// ZRANGE start = (page-1)*size, end = page*size -1Set<Object>booksSet=zSetOps.range(BOOKS_KEY,(page-1)*size,page*size-1);returnbooksSet.stream().map(obj->(Book)obj).collect(Collectors.toList());}// 获取总记录数publiclonggetTotalBooks(){returnredisTemplate.opsForZSet().size(BOOKS_KEY);}}
  • 分页实现:使用 Sorted Set 的 ZRANGE,按 score 分页。page 从 1 开始。
  • 为什么 Sorted Set:支持排序和范围查询,效率高于 List 的 LRANGE(List 为 O(N) 最坏情况)。
  • 数据初始化:可在应用启动时(或测试方法)添加样例数据:
// 在服务中添加测试方法或 CommandLineRunnerpublicvoidinitData(){addBook(newBook(1L,"Java编程思想","Bruce Eckel",99.0));addBook(newBook(2L,"Spring Boot实战","Craig Walls",89.0));// ... 添加更多}
步骤 4: 后端控制器(REST API)

BookController.java:提供分页 API,支持 ?page=1&size=10 参数。

packagecom.example.bookstore.controller;importcom.example.bookstore.entity.Book;importcom.example.bookstore.service.BookService;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.http.ResponseEntity;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.RequestParam;importorg.springframework.web.bind.annotation.RestController;importjava.util.HashMap;importjava.util.List;importjava.util.Map;@RestControllerpublicclassBookController{@AutowiredprivateBookServicebookService;@GetMapping("/books")publicResponseEntity<Map<String,Object>>getBooks(@RequestParam(defaultValue="1")intpage,@RequestParam(defaultValue="10")intsize){List<Book>books=bookService.getBooksByPage(page,size);longtotal=bookService.getTotalBooks();Map<String,Object>response=newHashMap<>();response.put("books",books);response.put("total",total);response.put("currentPage",page);response.put("totalPages",(total+size-1)/size);returnResponseEntity.ok(response);}}
  • 解释:返回 JSON,包括图书列表、总记录、页码。使用 Spring 的 @RequestParam 处理分页参数。
步骤 5: 前端交互(简单 HTML + JS)

假设前端页面为 index.html(放在 src/main/resources/static/ 下,或单独前端项目)。

<!DOCTYPEhtml><htmllang="zh-CN"><head><metacharset="UTF-8"><title>图书购买系统 - 分页展示</title><style>table{border-collapse:collapse;width:100%;}th, td{border:1px solid #ddd;padding:8px;}.pagination{margin-top:10px;}button{margin:0 5px;}</style></head><body><h1>Redis 中的图书列表(分页)</h1><tableid="bookTable"><thead><tr><th>ID</th><th>标题</th><th>作者</th><th>价格</th></tr></thead><tbody></tbody></table><divclass="pagination"><buttonid="prevBtn"disabled>上一页</button><spanid="pageInfo"></span><buttonid="nextBtn">下一页</button></div><script>letcurrentPage=1;constpageSize=10;asyncfunctionfetchBooks(page){constresponse=awaitfetch(`/books?page=${page}&size=${pageSize}`);constdata=awaitresponse.json();consttbody=document.querySelector('#bookTable tbody');tbody.innerHTML='';// 清空表格data.books.forEach(book=>{consttr=document.createElement('tr');tr.innerHTML=`<td>${book.id}</td><td>${book.title}</td><td>${book.author}</td><td>${book.price}</td>`;tbody.appendChild(tr);});document.getElementById('pageInfo').textContent=`${data.currentPage}页 / 共${data.totalPages}页 (总${data.total}本书)`;document.getElementById('prevBtn').disabled=data.currentPage===1;document.getElementById('nextBtn').disabled=data.currentPage>=data.totalPages;}// 按钮事件document.getElementById('prevBtn').addEventListener('click',()=>{if(currentPage>1){currentPage--;fetchBooks(currentPage);}});document.getElementById('nextBtn').addEventListener('click',()=>{currentPage++;fetchBooks(currentPage);});// 初始加载fetchBooks(currentPage);</script></body></html>
  • 解释:使用 Fetch API 调用后端 /books 接口,动态渲染表格和分页按钮。点击“上一页/下一页”触发请求。
步骤 6: 测试与运行
  1. 启动应用:运行 BookstoreApplication.java,确保 Redis 运行。
  2. 初始化数据:在服务中调用 initData() 或手动通过 Redis CLI 添加。
  3. 访问前端:浏览器打开 http://localhost:8080/index.html,查看分页效果。
  4. 验证 Redis:用 Redis CLI:ZRANGE books 0 -1 WITHSCORES查看数据。
注意事项与优化
  • 性能:分页大小(size)不宜太大(<100),避免 O(N) 开销。
  • 错误处理:添加 try-catch 处理 Redis 连接异常。
  • 生产优化:用 Lettuce 连接池(默认配置)、添加缓存注解 @Cacheable(如果结合数据库)。
  • 扩展:结合数据库(JPA),Redis 只缓存热门图书;前端用 Element UI 或 Ant Design 提升 UI。
  • 最佳实践(基于搜索结果):Sorted Set 适合带排序的分页;若无排序需求,可用 List + LRANGE。

这个实现覆盖了从配置到交互的全链路。如果需要完整源码或特定调整(如用 Vue),随时告诉我!🚀

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/15 0:47:53

手把手教你从零搭建SpringBoot项目

手把手教你从零搭建 Spring Boot 项目&#xff08;2026 最新版超详细教程&#xff09; Spring Boot 是目前 Java 后端开发最主流的框架&#xff0c;能帮你几分钟内创建一个可运行的生产级应用。下面我们从完全零基础开始&#xff0c;一步一步教你搭建一个标准的 Spring Boot 3…

作者头像 李华
网站建设 2026/7/30 4:28:46

Image-to-Video生成失败?这5个CUDA错误解决方案必看

Image-to-Video生成失败&#xff1f;这5个CUDA错误解决方案必看 背景与问题定位&#xff1a;Image-to-Video二次开发中的典型GPU挑战 在基于 I2VGen-XL 模型的 Image-to-Video 图像转视频生成器 二次构建过程中&#xff0c;开发者“科哥”成功实现了本地化部署和WebUI交互功能。…

作者头像 李华
网站建设 2026/8/9 7:46:53

Sambert-HifiGan高级教程:自定义情感语音合成实战

Sambert-HifiGan高级教程&#xff1a;自定义情感语音合成实战 引言&#xff1a;中文多情感语音合成的现实需求 在智能客服、虚拟主播、有声读物等应用场景中&#xff0c;单一语调的语音合成已无法满足用户体验需求。用户期望听到更具表现力、富有情绪变化的声音——如喜悦、悲…

作者头像 李华
网站建设 2026/8/7 10:38:58

宠物自助新体验:JAVA无人共享洗澡系统源码

以下是一套基于JAVA的宠物无人共享洗澡系统源码方案&#xff0c;该方案整合了微服务架构、物联网通信、AI情绪识别、多端交互等核心能力&#xff0c;适用于宠物店、社区共享场景的无人化改造&#xff1a;一、系统架构设计系统采用四层分布式架构&#xff0c;包括用户端、API网关…

作者头像 李华
网站建设 2026/7/31 3:20:48

如何用Sambert-HifiGan为电子导览生成解说语音?

如何用Sambert-HifiGan为电子导览生成解说语音&#xff1f; 引言&#xff1a;语音合成在电子导览中的价值与挑战 随着智慧文旅、智能展馆和无人化服务的快速发展&#xff0c;高质量的中文语音解说系统已成为提升用户体验的核心组件。传统的预录音频维护成本高、扩展性差&#x…

作者头像 李华
网站建设 2026/7/31 4:32:44

安装包分发方式:Docker镜像还是Conda环境?

安装包分发方式&#xff1a;Docker镜像还是Conda环境&#xff1f; 背景与问题提出 在深度学习和AI应用开发中&#xff0c;如何高效、稳定地部署复杂依赖的项目一直是工程实践中的核心挑战。以 Image-to-Video 图像转视频生成器 为例&#xff0c;该项目基于 I2VGen-XL 模型构建&…

作者头像 李华