案例需求:

  1.提供index.html页面,页面中有一个省份下拉列表

  2.当页面加载完成后发送ajax请求,加载所有省份

  3.列表中的省份保持不变,则之后每次刷新页面都是从redis中获取

* 注意:使用redis缓存一些不经常发生变化的数据。
    * 数据库的数据一旦发生改变,则需要更新缓存。
      * 数据库的表执行 增删改的相关操作,需要将redis缓存数据清除,再次存入
      * 在service对应的增删改方法中,将redis数据删除。

前端页面:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/jquery-3.3.1.min.js"></script> <script>
$(function () {
//发送ajax请求,加载所有省份数据
$.get("provinceServlet",{},function (data) {
//[{"id":1,"name":"北京"},{"id":2,"name":"上海"},{"id":3,"name":"广州"},{"id":4,"name":"陕西"}] //1.获取select
var province = $("#province");
//2.遍历json数组
$(data).each(function () {
//3.创建<option>
var option = "<option name='"+this.id+"'>"+this.name+"</option>"; //4.调用select的append追加option
province.append(option);
});
});
});
</script> </head>
<body>
<select id="province">
<option>--请选择省份--</option>
</select>
</body>
</html>
jar包:

provinceServlet:

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

provinceService接口 和 provinceServiceImpl代码:

public interface ProvinceService {

    public List<Province> findAll();

    public String findAllJson();
}
===================================================================
public class ProvinceServiceImpl implements ProvinceService {
//声明dao
private ProvinceDao dao = new ProvinceDaoImpl(); @Override
public List<Province> findAll() {
return dao.findAll();
} /**
使用redis缓存
*/
@Override
public String findAllJson() {
//1.先从redis中查询数据
//1.1获取redis客户端连接
Jedis jedis = JedisPoolUtils.getJedis();
String province_json = jedis.get("province"); //2判断 province_json 数据是否为null
if(province_json == null || province_json.length() == 0){
//redis中没有数据
System.out.println("redis中没数据,查询数据库...");
//2.1从数据中查询
List<Province> ps = dao.findAll();
//2.2将list序列化为json
ObjectMapper mapper = new ObjectMapper();
try {
province_json = mapper.writeValueAsString(ps);
} catch (JsonProcessingException e) {
e.printStackTrace();
} //2.3 将json数据存入redis
jedis.set("province",province_json);
//归还连接
jedis.close(); }else{
System.out.println("redis中有数据,查询缓存...");
}
return province_json;
}
}

provinceDao接口 和 provinceDaoImpl代码:

public interface ProvinceDao {

    public List<Province> findAll();
} =========================================================== public class ProvinceDaoImpl implements ProvinceDao { //1.声明成员变量 jdbctemplement
private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource()); @Override
public List<Province> findAll() {
//1.定义sql
String sql = "select * from province ";
//2.执行sql
List<Province> list = template.query(sql, new BeanPropertyRowMapper<Province>(Province.class));
return list;
}
}

JDBCUtils:

/**
* 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();
}
}

JedisPoolUtils:

public class JedisPoolUtils {

    private static JedisPool jedisPool;

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

druid.properties 和 jedis.properties以及sql文件:

 演示界面:

redis学习(二)——案例练习的更多相关文章

  1. Redis 学习(二) —— 数据类型及操作

    Redis支持string.list.set.zset.hash等数据类型,这一篇学习redis的数据类型.命令及某些使用场景. 一.String,字符串 字符串是 Redis 最基本的数据类型.一个 ...

  2. Redis学习二:Redis入门介绍

    一.入门概述 1.是什么 Redis:REmote DIctionary Server(远程字典服务器) 是完全开源免费的,用C语言编写的,遵守BSD协议,是一个高性能的(key/value)分布式内 ...

  3. C#中使用Redis学习二 在.NET4.5中使用redis hash操作

    上一篇>> 摘要 上一篇讲述了安装redis客户端和服务器端,也大体地介绍了一下redis.本篇着重讲解.NET4.0 和 .NET4.5中如何使用redis和C# redis操作哈希表. ...

  4. redis学习(二)

    深入了解redis字符串,列表,散列和有序集合命令,了解发布,订阅命令和其他命令.   一,字符串   1.字符串可以存储3种类型的值 字符串,整数,浮点数 2.运算命令列表 incr : incr ...

  5. Redis学习二:Redis高并发之主从模式

    申明 本文章首发自本人公众号:壹枝花算不算浪漫,如若转载请标明来源! 感兴趣的小伙伴可关注个人公众号:壹枝花算不算浪漫 22.jpg 前言 前面已经学习了Redis的持久化方式,接下来开始学习Redi ...

  6. Redis学习二 C#中如何进行这五种数据类型的操作

    我在网上找了好久,就是没有找到Redis和C#结合的书,都是和别的编程语言在一起鬼混. 简单的用C#实现向Redis中插入那我中类型的数据 首先需要到NuGet 里面下载 Redis IDatabas ...

  7. php+redis 学习 二 悲观锁

    <?php header('content-type:text/html;chaeset=utf-8'); /** * redis实战 * * 实现悲观锁机制 * */ $timeout = 5 ...

  8. redis学习二 排序

    文章转载自:http://www.cnblogs.com/redcreen/archive/2011/02/15/1955226.html redis支持对list,set和sorted set元素的 ...

  9. 【转】C#中使用Redis学习二 在.NET4.5中使用redis hash操作

    摘要 上一篇讲述了安装redis客户端和服务器端,也大体地介绍了一下redis.本篇着重讲解.NET4.0 和 .NET4.5中如何使用redis和C# redis操作哈希表.并且会将封装的一些代码贴 ...

随机推荐

  1. vue单项数据流

    当父组件给子组件传递数据的时候,子组件只能读取,不能改写.因为如果子组件改变父组件传递过来的数据时会造成数据流难以理解.

  2. CSPS_114

    考前自闭赛 综合我100场血的教训,我的考试策略应该是: 1.不要期望能AC某道题,想都不要想,否则很容易直接崩 2.哪怕想到正解,先打暴力,把暴力码出来!没用也码! 稳扎稳打地得到代码难度最小的下一 ...

  3. 【cf比赛记录】Codeforces Round #601 (Div. 2)

    Codeforces Round #601 (Div. 2) ---- 比赛传送门 周二晚因为身体不适鸽了,补题补题 A // http://codeforces.com/contest/1255/p ...

  4. Internet地址结构

    IP地址结构及分类寻址 IP地址 = <网络号> + <主机号>            ------------IPv4(32bit)点分四组表示法: 192.168.31.1 ...

  5. 小程序组件--> 组件传参

    小程序组件,在components文件夹右击-->创建文件夹-->右击-->新建component即可 创建一个组件 如果多个地方需要使用到,可以在app.json中加入一下代码,相 ...

  6. 微服务看门神-Zuul

    Zuul网关和基本应用场景 构建微服务时,常见的问题是为系统的客户端应用程序提供唯一的网关. 事实上,您的服务被拆分为小型微服务应用程序,这些应用程序应该对用户不可见,否则可能会导致大量的开发/维护工 ...

  7. 浅谈UDF并行

    首先我们来看说明UDF并行流程的这个图 网格和求解数据分布和储存在计算节点(compute-node)处理器上,而对于GUI界面和主机(host)节点上不存储任何数据,主机节点将命令从GUI传递到0节 ...

  8. 剑指offer:表示数值的字符串

    题目描述: 请实现一个函数用来判断字符串是否表示数值(包括整数和小数).例如,字符串"+100","5e2","-123","3. ...

  9. kotlin基础 字符串模板

    ${变量名} var tmp="字符串模板” print("今天学习${tmp}这个知识点")

  10. C# 动态创建EXE

    1.创建项目SaveExe或者修改代码中SaveExe名字为自己的项目 2.添加按钮调用CreateCodeEXE,即可实现编译生成一个新的exe即 复制了自身的exe生成一个新的exe(目的就是新生 ...