欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Redis综合案例 - 使用redis来实现缓存商品分类

程序员文章站 2022-04-29 23:42:39
...

使用redis的流程图:

Redis综合案例 - 使用redis来实现缓存商品分类

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

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. 编写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;
        }

    }
}

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

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

5. 编写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;
    }
}

6. 测试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’}

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

7. 编写页面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);

    }
}

8. 过滤器,防止乱码

//拦截所有,进行编码设置
@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);//放行
    }
}

9. 写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>

10. 需要的jar包

Redis综合案例 - 使用redis来实现缓存商品分类

11. 运行结果

Redis综合案例 - 使用redis来实现缓存商品分类