一、环境搭建

业务分析:编写一个简单的前端页面,选择用一个 <select>列表,页面加载完成后发送Ajax请求, 加载所有省份。

数据库环境

创建如下的数据库以及数据表:

create database province;
use province;
create table province(id int primary key not null auto_increment,name varchar(20) not null
);insert into province(name) value("北京");
insert into province(name) value("天津");
insert into province(name) value("上海");
insert into province(name) value("重庆");

配置环境

使用druid.properties文件:

driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql:///province
username=root
password=123456
initialSize=5
maxActive=10
maxWait=3000

使用redis.properties文件:

redis.host=127.0.0.1
redis.port=6379
redis.maxTotal=30
redis.maxIdle=10

依赖文件pom.xml为:

<dependencies><dependency><groupId>commons-logging</groupId><artifactId>commons-logging</artifactId><version>1.2</version></dependency><dependency><groupId>commons-beanutils</groupId><artifactId>commons-beanutils</artifactId><version>1.7.0</version></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.6</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-annotations</artifactId><version>2.12.2</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-core</artifactId><version>2.12.1</version></dependency><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId><version>2.12.1</version></dependency><dependency><groupId>jstl</groupId><artifactId>jstl</artifactId><version>1.2</version></dependency><dependency><groupId>org.glassfish.web</groupId><artifactId>jstl-impl</artifactId><version>1.2</version></dependency><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.23</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-tx</artifactId><version>5.2.4.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.2.4.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-beans</artifactId><version>5.2.4.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>5.2.4.RELEASE</version></dependency>
</dependencies>

其中,创建servlet需要的核心依赖为:

<dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version>
</dependency>

创建web包,并且引入jQuery框架包。在web包下编写主页代码,其中body主题如下所示:

<body>
<select id="province"><option>--请选择省份--</option>
</select>
</body>

二、编写业务

业务逻辑

整个业务逻辑:

HTML页面发送请求——Servlet接收请求处理——调用Service层——调用dao层——数据库查询

dao层

创建com.company.dao.ProvinceDao接口

public interface ProvinceDao {List<Province> findAll();
}

创建对应的实现类com.company.dao.impl.ProvinceDaoImpl类

public class ProvinceDaoImpl implements ProvinceDao {// 1. 声明JdbcTemplate对象private final JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource());@Overridepublic List<Province> findAll() {// 2. 定义sqlString sql = "select * from province";// 3. 执行sql语句List<Province> provinces = jdbcTemplate.query(sql, new BeanPropertyRowMapper<Province>(Province.class));return provinces;}
}

domain层

创建实体类com.company.domain.Province类

public class Province {private int id;private String name;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}@Overridepublic String toString() {return "Province{" +"id=" + id +", name='" + name + '\'' +'}';}
}

service层

创建service层com.company.service.ProvinceService接口

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

创建对应的实现类com.company.service.impl.ProvinceServiceImpl类

public class ProvinceServiceImpl implements ProvinceService {// 声明dao变量,service调用dao层private final ProvinceDao dao = new ProvinceDaoImpl();@Overridepublic List<Province> findAll() {return dao.findAll();}
}

util包

创建jdbc工具类com.company.util.JDBCUtils类

public class JDBCUtils {public static DataSource ds;static {try {// 1. 加载配置文件Properties pro = new Properties();// 2. 获取字节输入流InputStream stream = JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties");pro.load(stream);// 3. 初始化连接池对象ds = DruidDataSourceFactory.createDataSource(pro);} catch (Exception e) {e.printStackTrace();}}// 获取数据源对象public static DataSource getDataSource() {return ds;}// 获取连接对象public static Connection getConnection() throws SQLException {return ds.getConnection();}}

web.servlet包

创建com.company.web.servlet.ProvinceServlet类

@WebServlet(name = "ProvinceServlet", value = "/provinceServlet")
public class ProvinceServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 1. 调用service查询ProvinceService service = new ProvinceServiceImpl();List<Province> list = service.findAll();// 2. 序列化list为jsonObjectMapper mapper = new ObjectMapper();String json = mapper.writeValueAsString(list);System.out.println(json);// 3. 响应结果response.setContentType("application/json;charset=utf-8");response.getWriter().write(json);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {}
}

三、Ajax请求

在主页中编写响应的请求代码,发起Ajax连接。

<script src="js/jquery-3.5.1.min.js"></script>
<script>$(function () {// 发送Ajax请求,加载所有省份数据$.get("provinceServlet", {}, function (data) {// [{"id":1,"name":"北京"},{"id":2,"name":"天津"}// {"id":3,"name":"上海"},{"id":4,"name":"重庆"}]// 1. 获取selectlet province = $("#province");// 2. 遍历json数组$(data).each(function () {// 3. 创建option标签let option = "<option name='" + this.id + "'>" + this.name + "</option>";// 4. 调用select的append方法,追加optionprovince.append(option);});});});
</script>

四、Redis优化

使用Redis对整个业务进行优化,主要的使用方式是使用Redis的缓存优化。

在整个业务的Service层进行操作,逻辑如下:

  • 从Redis中查询数据

    • 没有

      • 再从数据库中查询
      • 将数据存入Redis
      • 返回数据
      • 直接返回数据

这样的操作,可以减少数据库的查询次数,加快整个业务的运行速度。

准备阶段

导入新的jedis的依赖包:

<dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>3.6.0</version>
</dependency>

编写jedis连接池工具类com.company.util.JedisPoolUtils类:

public class JedisPoolUtils {private static JedisPool jedisPool;static {// 读取配置文件InputStream resource = JedisPoolUtils.class.getClassLoader().getResourceAsStream("redis.properties");Properties properties = new Properties();try {properties.load(resource);} catch (IOException e) {e.printStackTrace();}// 获取数据,设置到JedisPoolConfig中JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();jedisPoolConfig.setMaxTotal(Integer.parseInt(properties.getProperty("redis.maxTotal")));jedisPoolConfig.setMaxIdle(Integer.parseInt(properties.getProperty("redis.maxIdle")));// 初始化JedisPool对象jedisPool = new JedisPool(jedisPoolConfig, properties.getProperty("redis.host"), Integer.parseInt(properties.getProperty("redis.port")));}/*** 获取连接方法* @return 返回Jedis连接对象*/public static Jedis getJedis() {return jedisPool.getResource();}
}

添加方法

在service接口层添加新的方法:

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

实现类中添加新的方法:

/*** 使用redis缓存优化业务*/
@Override
public String findAllJson() {// 先从redis中查询数据// 创建jedis对象Jedis jedis = JedisPoolUtils.getJedis();System.out.println("连接成功");String provinceJson = jedis.get("province");// 判断provinceJson是否有值if (provinceJson == null || provinceJson.length() == 0) {System.out.println("redis中无数据,查询数据库...");// redis中没有数据,需要从数据库中获取List<Province> provinces = dao.findAll();// 将list序列化成jsonObjectMapper mapper = new ObjectMapper();try {provinceJson = mapper.writeValueAsString(provinces);System.out.println(provinceJson);} catch (JsonProcessingException e) {e.printStackTrace();}try {// 将json数据存入redis中String set = jedis.set("province", provinceJson);if ("OK".equals(set)) {System.out.println("数据存入成功");}} catch (Exception e) {e.printStackTrace();} finally {// 释放资源jedis.close();}} else {System.out.println("redis中有数据,查询缓存...");}return provinceJson;
}

最后在servlet中替换新的方法调用:

// 1. 查询json
ProvinceService service = new ProvinceServiceImpl();
// 2. 序列化结果
String json = service.findAllJson();
System.out.println(json);
// 3. 响应结果
response.setContentType("application/json;charset=utf-8");
response.getWriter().write(json);

五、注意

使用redis缓存一些内容不经常发生变化的数据更加合适

  • 数据库的数据一 旦发生改变,则需要更新缓存。
  • 数据库的表执行增删改的相关操作,需要将redis缓存数据情况,再次存入
  • 在service对应的增删改方法中,将redis数据删除

遇见问题:

java.lang.ClassNotFoundException: org.apache.commons.pool2.impl.GenericObjectPoolConfig

原因是缺少必要的jar包:

<dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId><version>2.6.0</version>
</dependency>

【Redis】利用Redis优化数据案例相关推荐

  1. 利用redis缓存对 list集合中的数据 进行分页操作(一)

    先说 存储的结构: 这里做了两块缓存  绿色是存储索引的缓存  黑色是存数据的缓存 翻页时需要两个参数  向上查询/或向下查询    还一个是   从第二页开始查询时需要一个索引的参数 有了这两个参数 ...

  2. 某大型政务网站的优化咨询案例(视频点播VOD+GZIP压缩+静态文件CDN+Redis缓存+全文索引)

    2022年圣诞节到来啦,很高兴这次我们又能一起度过~ 这次分享关于一个对某大型政务网站的优化咨询的案例,发生在今年的下半年,已过去一段时间,并取得了良好的成果!* 项目背景 某大型政务网站准备上线,需 ...

  3. Java 性能优化实战案例分析:Redis如何助力秒杀业务

    在上一课时,我们以 Guava 的 LoadingCache 为例,介绍了堆内缓存的特点以及一些注意事项.同时,还了解了缓存使用的场景,这对分布式缓存来说,同样适用. 那什么叫分布式缓存呢?它其实是一 ...

  4. python—简单数据抓取七(采取蘑菇API代理设置scrapy的代理IP池并利用redis形成队列依次使用,利用ip池访问网页并将scrapy爬取转移到items的数据存入到数据库)

    学习目标: Python学习二十七-简单数据抓取七 学习内容: 1.采取蘑菇API代理设置scrapy的代理IP池并利用redis形成队列依次使用 2.利用ip池访问网页并将scrapy爬取转移到it ...

  5. 利用Redis解决重复数据时候的并发异常和分布式锁解决方案

    最近公司里有一个并发业务.多个线程消费一个kafka数据流,这个kafka数据流里数据的某个字段有重复.需要根据这个字段来做下去重. 一开始的方案是利用Redis来实现,先查Redis如果没有的话则s ...

  6. 【Java项目中 利用Redis实现数据缓存】

    文章目录 Java SpringBoot项目中 用Redis实现数据缓存 1 环境搭建 1.1 maven坐标 1.2 配置文件 1.3 配置类 2 实现缓存短信验证码 3 缓存菜品数据 4 Spri ...

  7. NoSQL之 Redis配置与优化

    NoSQL之 Redis配置与优化 前言 一.缓存概念 (1)系统缓存 ①buffer与cache (2)缓存保存位置及分层结构 ①DNS缓存 ②应用层缓存 ③数据层缓存 ④硬件缓存 二.关系数据库和 ...

  8. c#获取对象的唯一标识_在 Java 中利用 redis 实现分布式全局唯一标识服务

    作者: 杨高超 juejin.im/post/5a4984265188252b145b643e 获取全局唯一标识的方法介绍 在一个IT系统中,获取一个对象的唯一标识符是一个普遍的需求.在以前的单体应用 ...

  9. NoSQL(2)之 Redis配置与优化

    文章目录 一.关系数据库和非关系数据库 1.1 关系型数据库 1.2 非关系型数据库 1.3 非关系型数据库的产生背景 1.4 关系型数据库和非关系型数据库区别 1.数据存储方式不同 2.扩展方式不同 ...

最新文章

  1. 【Android 组件化】路由组件 ( 注解处理器获取被注解的节点 )
  2. java银行管理系统_java实现银行管理系统
  3. Why SAP SQL view is not recommended to use in SQL ?
  4. C++学习之路 | PTA(天梯赛)—— L2-010 排座位 (25分)(带注释)(并查集)(精简)
  5. 给控件做数字签名之三:进行数字签名
  6. 21 世纪最需要的 7 种人才素质 - 李开复
  7. Hive时间戳TIMESTAMP使用的限制
  8. vue中:class实现样式的绑定
  9. 前端多个圆圈均匀横向排列_web前端工程师必须掌握的24条宝贵经验!让你在前端路上更轻松!...
  10. php yii2模块,Yii2 中关于模块(Modules)的使用及配置
  11. 哈密顿图、哈密顿回路
  12. 在python中的占位符中、请你选出不属于占位符的选项_2020年超星尔雅微表情识别·读脸读心 作业答案...
  13. DTOJ3704 威士忌(whiskey)
  14. linux文件夹可视化工具,4款简单实用的的服务器文件管理工具推荐
  15. PubWin不知道密码情况下卸载
  16. 2022年全网最新 Windows10 安装 JDK1.8
  17. linux系统搭建论坛,Linux下搭建discuz论坛
  18. python如何期货交易_能用python的期货交易软件
  19. html 绘制体温单,使用zrender.js绘制体温单效果
  20. 扇贝单词里有计算机英语吗,一个人背单词,一群人学英语:扇贝单词

热门文章

  1. WEB 视频开发-主流协议 HLS DASH
  2. 一些常用的语音特征提取算法
  3. Brave 浏览器续航测试:功耗比各大主流浏览器都要低
  4. 总结避免死锁的几种方法
  5. 【又换MCU】越来越好用系列,新塘031 SPI PDMA通信
  6. C#【中级篇】volatile关键字测试-在C#无区别,在Java有区别
  7. 为什么要在函数组件中使用React.memo?
  8. 不知道今天吃什么?今天吃什么 API 告诉你
  9. 计算机二级不参加会记入诚信档案吗,考生必看!弃考会被记入诚信档案吗?
  10. CorelDRAW Graphics Suite2022最新版新增功能及增强内容介绍