基於三層架構的開發模式實現的Redis緩存小項目

項目需求:

1. 提供index.html頁面,頁面中有一個省份 下拉列表
	2. 當 頁面加載完成後 發送ajax請求,加載全部省份
複製代碼

圖解思路html

搭建環境

一、導入相關jar包(因爲不是maven項目,因此jar包還得手動導入)

二、建立數據庫(建庫建表操做)java

三、導入配置文件(數據庫鏈接池和緩存客戶端配置文件)mysql

四、編寫utils類(數據庫鏈接工具類和緩存客戶端工具類)jquery

四、基於三層架構的開發模式git

3.1 entity包(存放javaBean實體類)
3.2 dao包(持久層)
3.3 service包 (業務層)
3.4 servlet包 (控制層)
複製代碼

entity實體類

package com.baoji.web.entity;
/*
    編寫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;
    }
}
複製代碼

dao(持久層)

接口:
複製代碼
package com.baoji.web.dao;

import com.baoji.web.entity.Province;

import java.util.List;

public interface ProvinceDao {
    //定義查詢全部方法
    public List<Province> findAll();
}
複製代碼
實現類:
複製代碼
package com.baoji.web.dao.impl;

import com.baoji.web.dao.ProvinceDao;
import com.baoji.web.entity.Province;
import com.baoji.web.util.JDBCUtils;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;

import java.util.List;

public class ProvinceDaoImpl implements ProvinceDao {
    //定義成員變量 jdbcTemplate  (而且經過jdbc工具類獲取數據庫鏈接池對象)
    private JdbcTemplate jdbcTemplate = new JdbcTemplate(JDBCUtils.getDataSource());
    @Override
    public List<Province> findAll() {
       //一、定義sql
        String sql = "select * from province";
        //二、執行sql
        List<Province> list = jdbcTemplate.query(sql,new BeanPropertyRowMapper<Province>(Province.class));
        return list;
    }
}
複製代碼

service(業務層)

接口:
複製代碼
package com.baoji.web.service;

import com.baoji.web.entity.Province;

import java.util.List;

public interface ProvinceService {
    //定義查詢全部方法
    public List<Province> findAll();
    public String findAllJson();
}
複製代碼
實現類:
複製代碼
package com.baoji.web.service.impl;

import com.baoji.web.dao.ProvinceDao;
import com.baoji.web.dao.impl.ProvinceDaoImpl;
import com.baoji.web.entity.Province;
import com.baoji.web.service.ProvinceService;
import com.baoji.web.util.JedisPoolUtils;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import redis.clients.jedis.Jedis;

import java.util.List;

public class ProvinceServiceImpl implements ProvinceService {
    //定義ProvinceServiceDao成員變量
    private ProvinceDao dao = new ProvinceDaoImpl();
    @Override
    public List<Province> findAll() {
        return dao.findAll();
    }

    @Override
    public String findAllJson() {
        //一、先從radis查詢數據
        //1.1獲取radis客戶端鏈接
        Jedis jedis = JedisPoolUtils.getJedis();
        String province_json = jedis.get("province");
        //二、判斷province_json數據是否爲空
        if(province_json == null || province_json.length() == 0){
            //radis中沒有數據
            System.out.println("redis中沒有數據,查詢數據庫");
            //2.1查詢數據庫中的數據
            List<Province> list = dao.findAll();
            //2.2將list數據轉換爲json格式
            ObjectMapper mapper = new ObjectMapper();
            try {
                province_json = mapper.writeValueAsString(list);
            } catch (JsonProcessingException e) {
                e.printStackTrace();
            }
            //2.3將json傳入redis
            jedis.set("province",province_json);
            //2.4歸還鏈接
            jedis.close();
        }else{
            System.out.println("redis中有數據,查詢redis緩存中數據");
        }
        return province_json;
    }
}
複製代碼
* 注意:使用redis緩存一些不常常發生變化的數據。
		* 數據庫的數據一旦發生改變,則須要更新緩存。
			* 數據庫的表執行 增刪改的相關操做,須要將redis緩存數據清空,再次存入
			* 在service對應的增刪改方法中,將redis數據刪除。
複製代碼

servlet(控制層)

package com.baoji.web.servlet;

import com.baoji.web.entity.Province;
import com.baoji.web.service.ProvinceService;
import com.baoji.web.service.impl.ProvinceServiceImpl;
import com.fasterxml.jackson.databind.ObjectMapper;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

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

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//        //一、調用service的查詢方法
//        ProvinceService service = new ProvinceServiceImpl();
//        List<Province> list = service.findAll();
//        //二、將數據序列換爲json格式
//        ObjectMapper mapper = new ObjectMapper();
//        String json = mapper.writeValueAsString(list);

        //一、調用service的查詢方法
       ProvinceService service = new ProvinceServiceImpl();
        String json = service.findAllJson();
        System.out.println(json);
        //三、響應結果
        response.setContentType("application/json;charset=utf-8");//設置接收的數據返回json格式
        response.getWriter().write(json);
    }
}
複製代碼

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>下拉列表</title>
    <!--導入jquery的配置文件-->
    <script src="js/jquery-3.3.1.js"></script>
    <script>
        //入口函數
        $(function () {
            //發送ajax請求,加載全部省份數據
            $.get("provinceServlet",{},function (data) {
                //一、獲取select
                var province = $("#province");
                //二、遍歷json數組
                $(data).each(function () {
                    //三、建立<option>  this表明當前對象
                    var option = "<option name='"+this.id+"'>"+this.name+"</option>";
                    //四、調用select的append方法追加option
                    province.append(option);
                });

            });
        });
    </script>
</head>
<body>
    <select id="province">
        <option>--請選擇省份--</option>
    </select>
</body>
</html>
複製代碼

utils工具類

JDBCUtils類 (基本操做,必定要會)github

package com.baoji.web.util;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

/**
 * JDBC工具類 使用Druid鏈接池
 */
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工具類web

package com.baoji.web.util;
/*
    JedisPool工具類
        加載配置文件,配置鏈接池的參數
        提供獲取鏈接的方法
 */

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

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")));  //將讀取到的字符串改成int型  Integer.parseInt();
        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();
    }
    /*
        得到關閉方法
     */
    public static void closeJedis(){
        jedisPool.close();
    }
}
複製代碼

配置文件(.properties)

jedis.properties (redis緩存客戶端)ajax

host=127.0.0.1
port=6379
maxTotal=50
maxIdle=10
複製代碼

druid.properties(數據庫鏈接池)redis

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql:///provinces
username=root
password=root
initialSize=5
maxActive=10
maxWait=3000
複製代碼

敲黑板


對於不常常修改的數據,在service層先判斷redis緩存中是否有此數據,若是有,從緩存中取數據,若是沒有,從數據庫提取數據,將數據解析成json字符串形式,存放在redis緩存中,這樣有利於性能的提升,不會對數據庫形成很大的壓力。spring

三層架構思想很重要,但願讀者理清思路,且行且珍惜。。。


寫在最後

推薦做者的Github地址:github.com/Lmobject

相關文章
相關標籤/搜索