Redis综合案例 - 使用redis来实现缓存商品分类 - 创建Jedis工具类连接redis

使用redis的流程图:

在这里插入图片描述

实现缓存商品分类的思维图:

在这里插入图片描述

  1. 浏览器发送请求,服务器接收请求交给CategroySerivce类的queryAll()方法处理去查询数据
  2. 首次查询redis,如果没有数据(json格式),就调用CategoryDao去数据库(MySQL)查找,获取集合List商品分类集合,然后先返回给CategorySrvice,让其将List数据转成json后缓存进redis,同时将json数据返回给服务器。
  3. 第二次起查询,直接从redis中获取json数据格式的商品分类,然后将json转成List,显示到浏览器上。

案例实现

1. 编写测试类

//第一步:测试开发CategoryService
public class TestCategoryService {
    
    
    @Test
    public void test01() throws Exception {
    
    
        //1. 创建业务类对象
        CategoryService categoryService = new CategoryService();
        //2. 查询所有分类集合
        List<Category> list = categoryService.queryAll();
        //3. 循环遍历输出
        for(Category category:list){
    
    
            System.out.println(category);
        }
    }
}

2. 编写商品分类的bean(Category)

public class Category {
    
    
    private int cid;		//编号
    private String cname;	//名称
   //省略setter和getter
}

3. 创建properties文件(jedis.properties)存放键值对

maxTotal=50
maxIdle=15
url=localhost
port=6379

4. 创建Jedis工具类,连接redis,读取propties文件键值对配置

//使用ResourceBundle读.propties文件
public class JedisUtils {
    
    
    //单例模式 静态代码块只执行一次,因为创建会很消耗性能
    private static JedisPool pool = null;
    //1. 创建一个连接池   静态代码在项目中,如果被使用只会加载一次
    static{
    
    
        //1.1 通过ResourceBundle读取properties文件 jedis.properties
        ResourceBundle bundle = ResourceBundle.getBundle("jedis");

        //获取参数
        String maxTotal = bundle.getString("maxTotal");
        String maxIdle = bundle.getString("maxIdle");
        String url = bundle.getString("url");
        String port = bundle.getString("port");

        //1.2创建连接池
        //创建连接池的配置对象
        JedisPoolConfig config = new JedisPoolConfig();
        //设置最大连接数
        config.setMaxTotal(Integer.parseInt(maxTotal));
        //设置空闲连接数
        config.setMaxIdle(Integer.parseInt(maxIdle));

        //2:创建连接池
        pool = new JedisPool(config, url, Integer.parseInt(port));
    }

    //2。 对外提供一个获取连接的方法
    public static Jedis getJedis(){
    
    
        return  pool.getResource();
    }

    //3。 提供释放资源的方法
    public static void close(Jedis jedis){
    
    
        if(jedis != null) {
    
    
            jedis.close();
        }
    }
}

5. 编写service层(CategoryService)

public class CategoryService {
    
    
    //调用dao层查询数据
    CategoryDao dao = new CategoryDao();
    //jackson 的 ObjectMapper类3  用来将数据与json格式相互转换
    ObjectMapper objectMapper = new ObjectMapper();
    public List<Category> queryAll() throws IOException {
    
    
        //1. 先访问redis,有数据就返回 JedisUtils  数据格式:Map<Srting,String>
        //  获取redis连接
         Jedis redis = JedisUtils.getJedis();
        //  查找redis缓存中的数据
        String json = redis.get("categoryList");
        if(json == null){
    
    //2. 如果没有数据就查询数据库(MySQL),缓存到redis
            System.out.println("(第一次查询) redis中没有数据,去查找数据库的数据");
            List<Category> categoryList = dao.findAll();
            //缓存  将查找到的list集合转换成json数据格式,缓存到redis上
            //通过ObjectMapper对象,转list数据格式转化成json数据格式
            String categoryListJson =  objectMapper.writeValueAsString(categoryList);
			System.out.println("查找到的categoryList的json数据是:");
            System.out.println(categoryListJson);

            redis.set("categoryList",categoryListJson);
            return categoryList;
        }else{
    
    //json ! =null 在redis中查询到了数据
            System.out.println("非第一次查询,数据缓存到redis中,redis有数据,直接从内存中返回,速度快");
            //将json转成对象   参1 json数据  参2 TypeReference
            List<Category> categoryList = objectMapper.readValue(json,new TypeReference<List<Category>>(){
    
    });
            return categoryList;
        }

    }
}

6. 编写dao层

public class CategoryDao {
    
    
    public List<Category> findAll() {
    
    
        //1:创建集合
        List<Category> categoryList = new ArrayList<>();
        //使用循环模拟数据,以后使用mybatis来查数据
        for (int i = 0; i < 10; i++) {
    
    
            categoryList.add(new Category(i,"菜单名" + i));
        }
        return categoryList;
    }
}

7. 测试TestCategoryService看逻辑是否正确

(这里连接的redis是本地的localhost,需要开启reids服务器redis-server.exe,否则会报连接错误)

第一次查询测试

(第一次查询) redis中没有数据,去查找数据库的数据
查找到的categoryList的json数据是:
[{“cid”:0,“cname”:“菜单名0”},{“cid”:1,“cname”:“菜单名1”},{“cid”:2,“cname”:“菜单名2”},{“cid”:3,“cname”:“菜单名3”},{“cid”:4,“cname”:“菜单名4”},{“cid”:5,“cname”:“菜单名5”},{“cid”:6,“cname”:“菜单名6”},{“cid”:7,“cname”:“菜单名7”},{“cid”:8,“cname”:“菜单名8”},{“cid”:9,“cname”:“菜单名9”}]
Category{cid=0, cname=‘菜单名0’}
Category{cid=1, cname=‘菜单名1’}
Category{cid=2, cname=‘菜单名2’}
Category{cid=3, cname=‘菜单名3’}
Category{cid=4, cname=‘菜单名4’}
Category{cid=5, cname=‘菜单名5’}
Category{cid=6, cname=‘菜单名6’}
Category{cid=7, cname=‘菜单名7’}
Category{cid=8, cname=‘菜单名8’}
Category{cid=9, cname=‘菜单名9’}

第二次/三次查询数据(非第一次的任意次数查找)

非第一次查询,数据缓存到redis中,redis有数据,直接从内存中返回,速度快
Category{cid=0, cname=‘菜单名0’}
Category{cid=1, cname=‘菜单名1’}
Category{cid=2, cname=‘菜单名2’}
Category{cid=3, cname=‘菜单名3’}
Category{cid=4, cname=‘菜单名4’}
Category{cid=5, cname=‘菜单名5’}
Category{cid=6, cname=‘菜单名6’}
Category{cid=7, cname=‘菜单名7’}
Category{cid=8, cname=‘菜单名8’}
Category{cid=9, cname=‘菜单名9’}

从结果可以知道业务逻辑没有错误,这时候就可以写页面了

8. 编写页面Servlet显示(就是测试类copy修改就写)

@WebServlet("/CategoryListServlet")
public class CategoryListServlet extends HttpServlet {
    
    
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    
        doGet(request,response);
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    
    
        //1. 创建业务类对象
        CategoryService categoryService = new CategoryService();

        //2. 查询分类集合
        List<Category> categoryList = categoryService.queryAll();

        //3. 请求转发
        request.setAttribute("categoryList",categoryList);
        request.getRequestDispatcher("categoryList.jsp").forward(request,response);

    }
}

9. 过滤器,防止乱码

//拦截所有,进行编码设置
@WebFilter("/*")
public class EncodingFilter implements Filter {
    
    
    public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws ServletException, IOException {
    
    
        req.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");
        chain.doFilter(req, resp);//放行
    }
}

10. 写jsp页面

<%-- isELIgnored="false 开启el表达式--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
 <html>
<head>
    <title>categoryList商品类型列表</title>
</head>
<body>


        <c:if test="${empty categoryList}">
            商品类型是空的哟
        </c:if>
        <c:if test="${!empty categoryList}">
            <table border="1" cellpadding="0" cellspacing="0">
                <thead>
                <tr>
                    <th>编号</th>
                    <th>商品类型名称</th>
                </tr>
                </thead>
                <tbody>
                <c:forEach items="${categoryList}" var="category" varStatus="vs">

                    <tr>
                        <td>${vs.count}</td>
                        <td>${category.cname}</td>
                    </tr>
                </c:forEach>
                </tbody>
            </table>
        </c:if>
</body>
</html>

11. 需要的jar包

在这里插入图片描述

12. 运行结果

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_40542534/article/details/108740426
今日推荐