기사 디렉토리
-
- redis 사용 순서도 :
- 캐시 된 상품의 분류를 실현하는 마인드 맵 :
- 사례 실현
-
- 1. 테스트 클래스 작성
- 2. 콩 (Category) 상품 분류 작성
- 3. 키-값 쌍을 저장할 속성 파일 (jedis.properties)을 만듭니다.
- 4. Jedis 도구 클래스를 만들고 redis에 연결하고 속성 파일의 키-값 쌍 구성을 읽습니다.
- 5. 서비스 계층 (CategoryService) 작성
- 6. dao 레이어 쓰기
- 7. TestCategoryService를 테스트하여 논리가 올바른지 확인합니다.
- 8. 페이지 서블릿 디스플레이 작성 (테스트 유형 복사 및 수정 만 작성)
- 9. 복잡한 코드를 방지하기위한 필터링
- 10. jsp 페이지 작성
- 11. 필수 jar 패키지
- 12. 결과 실행
redis 사용 순서도 :
캐시 된 상품의 분류를 실현하는 마인드 맵 :
- 브라우저는 요청을 보내고 서버는 요청을 받아 CategroySerivce 클래스의 queryAll () 메서드에 전달하여 쿼리 데이터를 처리합니다.
- redis를 처음 쿼리 할 때 데이터 (json 형식)가 없으면 CategoryDao를 호출하여 데이터베이스 (MySQL)에서 검색하고 컬렉션 목록 제품 분류 컬렉션을 가져온 다음 CategorySrvice로 반환하고 List 데이터를 json으로 변환하고 redis에 캐시하도록하는 동시에 동시에 json 데이터는 서버로 반환됩니다.
- 두 번째 쿼리의 경우 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. 콩 (Category) 상품 분류 작성
public class Category {
private int cid; //编号
private String cname; //名称
//省略setter和getter
}
3. 키-값 쌍을 저장할 속성 파일 (jedis.properties)을 만듭니다.
maxTotal=50
maxIdle=15
url=localhost
port=6379
4. Jedis 도구 클래스를 만들고 redis에 연결하고 속성 파일의 키-값 쌍 구성을 읽습니다.
//使用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. 서비스 계층 (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는 로컬 로컬 호스트이며 reids 서버를 켜야합니다 redis-server.exe
. 그렇지 않으면 연결 오류가보고됩니다.)
첫 번째 쿼리 테스트
(첫 번째 쿼리) 데이터베이스에서 데이터를 찾기위한 redis에 데이터가 없습니다.
발견 된 categoryList의 json 데이터는 다음과 같습니다.
[{ "cid": 0, "cname": "menu name0"}, { "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”}]
카테고리 {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 = 'menu 이름 6 '}
카테고리 {cid = 7, cname ='메뉴 이름 7 '}
카테고리 {cid = 8, cname ='메뉴 이름 8 '}
카테고리 {cid = 9, cname ='메뉴 이름 9 '}
두 번째 / 세 번째 쿼리 데이터 (첫 번째 검색 이외의 횟수)
첫 번째 쿼리가 아닌 데이터는 redis에 캐시되고 redis에는 데이터가 있으며 메모리에서 직접 반환됩니다. 빠른
Category {cid = 0, cname = 'menu name 0'}
Category {cid = 1, cname = 'menu name 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'}
결과를 통해 비즈니스 로직에 오류가 없음을 알 수 있으며 페이지를 작성할 수 있습니다.
8. 페이지 서블릿 디스플레이 작성 (테스트 유형 복사 및 수정 만 작성)
@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>