从 01 开始 从 01 开始
首页
  • 📚 计算机基础

    • 计算机简史
    • 数字电路
    • 计算机组成原理
    • 操作系统
    • Linux
    • 计算机网络
    • 数据库
    • 编程工具
    • 装机
  • 🎨 前端

    • Node
  • JavaSE
  • Java 高级
  • JavaEE

    • 构建、依赖管理
    • Ant
    • Maven
    • 日志框架
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • 环境管理和配置管理-科普篇
    • Servlet
  • Spring

    • Spring基础
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC

    • SpringMVC 基础
  • SpringBoot

    • SpringBoot 基础
  • Windows 使用技巧
  • 手机相关技巧
  • 最全面的输入法教程
  • 最全面的浏览器教程
  • Office
  • 图片类工具
  • 效率类工具
  • 最全面的 RSS 教程
  • 码字工具
  • 各大平台
  • 校招
  • 五险一金
  • 职场规划
  • 关于离职
  • 杂谈
  • 自媒体
  • 📖 读书

    • 读书工具
    • 走进科学
  • 🌍 英语

    • 从零开始学英语
    • 英语兔的相关视频
    • Larry 想做技术大佬的相关视频
  • 🏛️ 政治

    • 反腐
    • GFW
    • 404 内容
    • 审查与自我审查
    • 互联网
    • 战争
    • 读书笔记
  • 💰 经济

    • 关于税
    • 理财
  • 💪 健身

    • 睡眠
    • 皮肤
    • 口腔健康
    • 学会呼吸
    • 健身日志
  • 🏠 其他

    • 驾驶技能
    • 租房与买房
    • 厨艺
  • 电影

    • 电影推荐
  • 电视剧
  • 漫画

    • 漫画软件
    • 漫画推荐
  • 游戏

    • Steam
    • 三国杀
    • 求生之路
  • 小说
  • 关于本站
  • 关于博主
  • 打赏
  • 网站动态
  • 友人帐
  • 从零开始搭建博客
  • 搭建邮件服务器
  • 本站分享
  • 🌈 生活

    • 2022
    • 2023
    • 2024
    • 2025
  • 📇 文章索引

    • 文章分类
    • 文章归档

晓林

程序猿,自由职业者,博主,英语爱好者,健身达人
首页
  • 📚 计算机基础

    • 计算机简史
    • 数字电路
    • 计算机组成原理
    • 操作系统
    • Linux
    • 计算机网络
    • 数据库
    • 编程工具
    • 装机
  • 🎨 前端

    • Node
  • JavaSE
  • Java 高级
  • JavaEE

    • 构建、依赖管理
    • Ant
    • Maven
    • 日志框架
    • Junit
    • JDBC
    • XML-JSON
  • JavaWeb

    • 服务器软件
    • 环境管理和配置管理-科普篇
    • Servlet
  • Spring

    • Spring基础
  • 主流框架

    • Redis
    • Mybatis
    • Lucene
    • Elasticsearch
    • RabbitMQ
    • MyCat
    • Lombok
  • SpringMVC

    • SpringMVC 基础
  • SpringBoot

    • SpringBoot 基础
  • Windows 使用技巧
  • 手机相关技巧
  • 最全面的输入法教程
  • 最全面的浏览器教程
  • Office
  • 图片类工具
  • 效率类工具
  • 最全面的 RSS 教程
  • 码字工具
  • 各大平台
  • 校招
  • 五险一金
  • 职场规划
  • 关于离职
  • 杂谈
  • 自媒体
  • 📖 读书

    • 读书工具
    • 走进科学
  • 🌍 英语

    • 从零开始学英语
    • 英语兔的相关视频
    • Larry 想做技术大佬的相关视频
  • 🏛️ 政治

    • 反腐
    • GFW
    • 404 内容
    • 审查与自我审查
    • 互联网
    • 战争
    • 读书笔记
  • 💰 经济

    • 关于税
    • 理财
  • 💪 健身

    • 睡眠
    • 皮肤
    • 口腔健康
    • 学会呼吸
    • 健身日志
  • 🏠 其他

    • 驾驶技能
    • 租房与买房
    • 厨艺
  • 电影

    • 电影推荐
  • 电视剧
  • 漫画

    • 漫画软件
    • 漫画推荐
  • 游戏

    • Steam
    • 三国杀
    • 求生之路
  • 小说
  • 关于本站
  • 关于博主
  • 打赏
  • 网站动态
  • 友人帐
  • 从零开始搭建博客
  • 搭建邮件服务器
  • 本站分享
  • 🌈 生活

    • 2022
    • 2023
    • 2024
    • 2025
  • 📇 文章索引

    • 文章分类
    • 文章归档
  • JavaSE

  • JavaSenior

  • JavaEE

  • JavaWeb

  • Spring

  • 主流框架

    • Redis

      • Redis 系列教程介绍
      • Redis 介绍
      • Redis 的安装和启停
      • Redis 操作数据
      • Redis 客户端
      • Redis 命令返回值
      • 多数据库
      • Redis 中的事务
      • Redis 中 key 的过期时间
      • Redis 持久化数据
      • Redis 的配置
      • Java 连接 Redis
      • Redis 连接池
      • Redis 搭建集群
      • Redis 中的哨兵
      • Redis 中的安全
      • 监控 Redis
      • Redis 小实验
        • 案例需求
        • 需求设计
        • 数据库准备
        • 添加依赖
        • 新建 Druid 配置文件
        • 准备 webapp 目录
        • 新建实体类
        • 新建 dao 接口
        • 新建 dao 接口实现类
        • 新建 service 接口
        • 新建 service 实现类
        • 新建 JDBC 工具类
        • 修改 dao 实现类
        • 修改 service 实现类
        • 新建 Servlet
        • 新建 index.html
        • 使用 Redis-设计思路
        • 修改 service 接口和实现类
        • 修改 Servlet
        • 重启并测试
    • Mybatis

    • Lucene

    • Elasticsearch

    • MQ

    • MyCat

    • Lombok

  • SpringMVC

  • SpringBoot

  • Java
  • 主流框架
  • Redis
2023-08-18
目录

Redis 小实验

# 160.Redis 小实验

本文我们来做一个综合性的应用:实现在前端页面加载省份下拉列表。 ‍

# 案例需求

  1. 提供 index.html 页面,页面中有一个省份下拉列表
  2. 当页面加载完成后发送 ajax 请求,加载所有省份

我们使用 redis 缓存一些不经常发生变化的数据,例如省份。

但数据库的数据一旦发生改变,则需要更新缓存。如果数据库的表执行了增删改的相关操作,则将 redis 缓存数据情况,再次存入。我们可以在 service 对应的增删改方法中,将 redis 数据删除。 ‍ 接下来我们开始设计和开发(所有代码已上传到了 GitHub (opens new window) 和 Gitee (opens new window) 上)

# 需求设计

首先,有个 HTML 页面,有一个下拉框显示省份;当页面加载后,发送 Ajax 请求给服务器,服务器返回数据给前端,前端获取数据后逐个加到下拉框里

假设 Servlet 名字为 ProvinceServlet,相应的,有 ProvinceService 和 ProvinceDao 接口和实现类,用于查询数据库

示意图:

# 数据库准备

这里我们创建一个新的数据库:

CREATE DATABASE day23; -- 创建数据库
USE day23; 	       -- 使用数据库
CREATE TABLE province(   -- 创建表
	id INT PRIMARY KEY AUTO_INCREMENT,
	NAME VARCHAR(20) NOT NULL

);
-- 插入数据
INSERT INTO province VALUES(NULL,'北京');
INSERT INTO province VALUES(NULL,'上海');
INSERT INTO province VALUES(NULL,'广州');
INSERT INTO province VALUES(NULL,'陕西');
1
2
3
4
5
6
7
8
9
10
11
12

# 添加依赖

‍

# 新建 Druid 配置文件

我们在 resources 文件下,新建

driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql:///day23
username=root
password=****
initialSize=5
maxActive=10
maxWait=3000
1
2
3
4
5
6
7

数据库信息请自行更换

# 准备 webapp 目录

我们在 src/main 目录下,新建 webapp 目录,并新建 WEB-INF 目录,WEB-INF/web.xml 文件;

然后在 webapp 目录下新建 js 目录,并导入 JQuery 的依赖

然后在 webapp 目录下新建 index.html 文件

# 新建实体类

package com.peterjxl.domain;

public class Province {
    private int id;
    private String name;
}

1
2
3
4
5
6
7

记得添加 getter 和 setter

# 新建 dao 接口

package com.peterjxl.dao;
import com.peterjxl.domain.Province;
import java.util.List;
public interface ProvinceDao {
    public List<Province> findAll();
}
1
2
3
4
5
6

# 新建 dao 接口实现类

package com.peterjxl.dao.impl;

import com.peterjxl.dao.ProvinceDao;
import com.peterjxl.domain.Province;

import java.util.List;

public class ProvinceDaoImpl implements ProvinceDao {
    @Override
    public List<Province> findAll() {
        return null;
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14

‍ 这里我们先不实现方法 ‍

# 新建 service 接口

package com.peterjxl.service;

import com.peterjxl.domain.Province;

import java.util.List;

public interface ProvinceService {
    List<Province> findAll();

}

1
2
3
4
5
6
7
8
9
10
11

‍

# 新建 service 实现类

package com.peterjxl.service.impl;
import com.peterjxl.domain.Province;
import com.peterjxl.service.ProvinceService;
import java.util.List;

public class ProvinceServiceImpl implements ProvinceService {
    @Override
    public List<Province> findAll() {
        return null;
    }
}
1
2
3
4
5
6
7
8
9
10
11

# 新建 JDBC 工具类

package com.peterjxl.util;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

/**
 * JDBC工具类 使用Durid连接池
 */
public class JDBCUtils {

    private static DataSource ds ;

    static {

        try {
            //1.加载配置文件
            Properties pro = new Properties();
            //使用ClassLoader加载配置文件,获取字节输入流
            InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties");
            pro.load(is);

            //2.初始化连接池对象
            ds = DruidDataSourceFactory.createDataSource(pro);

        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取连接池对象
     */
    public static DataSource getDataSource(){
        return ds;
    }


    /**
     * 获取连接Connection对象
     */
    public static Connection getConnection() throws SQLException {
        return  ds.getConnection();
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52

‍

# 修改 dao 实现类

package com.peterjxl.dao.impl;

import com.peterjxl.dao.ProvinceDao;
import com.peterjxl.domain.Province;
import com.peterjxl.util.JDBCUtils;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;

import java.util.List;

public class ProvinceDaoImpl implements ProvinceDao {


    JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());

    @Override
    public List<Province> findAll() {
        String sql = "select * from province";
        List<Province> list = template.query(sql, new BeanPropertyRowMapper<Province>(Province.class));
        return list
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 修改 service 实现类

package com.peterjxl.service.impl;

import com.peterjxl.dao.ProvinceDao;
import com.peterjxl.dao.impl.ProvinceDaoImpl;
import com.peterjxl.domain.Province;
import com.peterjxl.service.ProvinceService;

import java.util.List;

public class ProvinceServiceImpl implements ProvinceService {

    private ProvinceDao dao = new ProvinceDaoImpl();
    @Override
    public List<Province> findAll() {
        return dao.findAll();
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 新建 Servlet

package com.peterjxl.servlet;


import com.fasterxml.jackson.databind.ObjectMapper;
import com.peterjxl.domain.Province;
import com.peterjxl.service.ProvinceService;
import com.peterjxl.service.impl.ProvinceServiceImpl;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

@WebServlet("/provinceServlet")
public class ProvinceServlet extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ProvinceService service = new ProvinceServiceImpl();
        List<Province> list = service.findAll();
        ObjectMapper mapper = new ObjectMapper();
        String json = mapper.writeValueAsString(list);
        System.out.println(json);
        resp.setContentType("application/json;charset=utf-8");
        resp.getWriter().write(json);
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doPost(req, resp);
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

# 新建 index.html

‍

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Hello Redis</title>
        <script src="js/jquery-3.3.1.min.js"></script>
        <script>
            $(function (){
                //发送Ajax请求
                $.get("/provinceServlet", {}, function (data){

                    // 1. 获取select标签
                    var $province = $("#province");
                    $(data).each(function (index, obj){
                        // 2. 创建option标签
                        var $option = $("<option></option>");
                        // 3. 设置option标签的value属性值
                        $option.attr("value", obj.id);
                        // 4. 设置option标签的文本内容
                        $option.text(obj.name);
                        // 5. 将option标签添加到select标签中
                        $province.append($option);
                    })
                })
            });
        </script>
    </head>
    <body>
        <select id="province">
            <option>--请选择省份</option>
        </select>
    </body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

# 使用 Redis-设计思路

接下来开始重头戏。由于省份是很少变化的,我们可以用缓存来存储省份数据。

我们在 service 中,

  1. 首先从 Redis 中查询是否有数据
  2. 没有则查询数据库并填充到 Redis 中;有则跳到下一步
  3. 返回省份数据给前端

我们可以将 JSON 字符串存到 Redis 中。

# 修改 service 接口和实现类

我们添加一个 findAllJson 方法

package com.peterjxl.service;
import com.peterjxl.domain.Province;
import java.util.List;
public interface ProvinceService {
    List<Province> findAll();
    String findAllJson();
}
1
2
3
4
5
6
7
package com.peterjxl.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.peterjxl.dao.ProvinceDao;
import com.peterjxl.dao.impl.ProvinceDaoImpl;
import com.peterjxl.domain.Province;
import com.peterjxl.service.ProvinceService;
import com.peterjxl.util.JedisPoolUtils;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import java.util.List;

public class ProvinceServiceImpl implements ProvinceService {

    private ProvinceDao dao = new ProvinceDaoImpl();
    @Override
    public List<Province> findAll() {
        return dao.findAll();
    }

    @Override
    public String findAllJson() {
        Jedis jedis = JedisPoolUtils.getJedis();
        String province_json = jedis.get("province");
        if(null == province_json || 0 == province_json.length()){
            System.out.println("redis中没有数据,查询数据库");
            List<Province> list = dao.findAll();
            ObjectMapper mapper = new ObjectMapper();
            try {
                province_json = mapper.writeValueAsString(list);
            } catch (JsonProcessingException e) {
                throw new RuntimeException(e);
            }

            jedis.set("province",province_json);
            jedis.close();
        }else {
            System.out.println("redis中有数据,查询缓存");
        }

        return province_json;
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46

# 修改 Servlet

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    ProvinceService service = new ProvinceServiceImpl();
    String json = service.findAllJson();
    System.out.println(json);
    resp.setContentType("application/json;charset=utf-8");
    resp.getWriter().write(json);
}
1
2
3
4
5
6
7
8

‍

# 重启并测试

启动 Redis 服务端和客户端,然后查看当前的键,可以看到并没有 province

127.0.0.1:6379> keys *
1) "user"
2) "username"
3) "myList"
4) "hello"
5) "password"
6) "mySortedSet"
7) "myList2"
8) "mySet"
1
2
3
4
5
6
7
8
9

‍ 我们重启 Tomcat,访问页面,然后观察 Redis:

127.0.0.1:6379> keys *
1) "username"
2) "password"
3) "mySortedSet"
4) "user"
5) "myList"
6) "province"
7) "hello"
8) "myList2"
9) "mySet"
127.0.0.1:6379> get province
"[{\"id\":1,\"name\":\"\xe5\x8c\x97\xe4\xba\xac\"},{\"id\":2,\"name\":\"\xe4\xb8\x8a\xe6\xb5\xb7\"},{\"id\":3,\"name\":\"\xe5\xb9\xbf\xe5\xb7\x9e\"},{\"id\":4,\"name\":\"\xe9\x99\x95\xe8\xa5\xbf\"}]"
1
2
3
4
5
6
7
8
9
10
11
12

可以看到有这个 key,并且正常获取了。注意,这里只是将省份的数据做一个缓存,如果有更新,还得更新 Redis 的操作,例如 service 方法里的更新和删除方法中,更新 Redis 的数据,这里就不再演示了。

上次更新: 2025/6/3 09:31:54
监控 Redis
Mybatis 介绍

← 监控 Redis Mybatis 介绍→

最近更新
01
语雀文档一键下载至本地教程
07-04
02
要成功,就不要低估环境对你的影响
07-03
03
血泪教训:电子设备要定期开机
07-02
更多文章>
Theme by Vdoing | Copyright © 2022-2025 | 粤 ICP 备 2022067627 号 -1 | 粤公网安备 44011302003646 号 | 点击查看十年之约
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式