1. 程式人生 > >redis的初步使用(一)

redis的初步使用(一)

以法院專案查詢公告為例

步驟一:在application.yml中新增redis資訊

spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql:///ggt
    username: root
    password: root
    type: com.alibaba.druid.pool.DruidDataSource
  redis:
    host: 10.9.251.200
    port: 8100
    password: redis001
    jedis:
      pool:
        max-active: 1024
        max-idle: 100
        min-idle: 10
pagehelper:
  helper-dialect: mysql
  params: count=countsql
  reasonable: true
  support-methods-arguments: true

步驟二::新增配置檔案類,在伺服器啟動的時候建立JedisPool物件

package com.qf.fayuan.config;


import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

@Configuration
public class RedisConfig {

    @Value(value = ("${spring.redis.host}"))
    private String host;
    @Value(value = ("${spring.redis.port}"))
    private int port;
    @Value(value =("${spring.redis.password}") )
    private String password;

    @Bean
    public JedisPool jedisPool(JedisPoolConfig jedisPoolConfig){
        JedisPool jedisPool = new JedisPool(jedisPoolConfig,host,port,5000,password);
        return jedisPool;
    }

    @Bean
    public JedisPoolConfig jedisPoolConfig(){
        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxTotal(1024);
        jedisPoolConfig.setMaxIdle(100);
        jedisPoolConfig.setMinIdle(10);
        return jedisPoolConfig;
    }

}

步驟三:配置工具類,如果快取中沒有,將資料新增入

package com.qf.fayuan.utils;


import redis.clients.jedis.Jedis;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class RedisUtils {

    public static void hSet(int key, Object object, Jedis jedis){
        //獲取類的位元組碼物件
        Class<?> aClass = object.getClass();
        //獲得類中的所有屬性
        Field[] declaredFields = aClass.getDeclaredFields();
        for (Field field : declaredFields) {
            String fieldName = field.getName();
            try {
                //獲取屬性的get/set 方法
                PropertyDescriptor propertyDescriptor = new PropertyDescriptor(fieldName, aClass);
                //獲取get方法
                Method readMethod = propertyDescriptor.getReadMethod();
                if (readMethod != null) {
                    //得到屬性的值
                    Object result = readMethod.invoke(object);
                    if (result != null) {
                        //向快取中新增資料
                        jedis.hset(key + "noticeinfo", fieldName, result.toString());
                    }
                }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }


第四部分:service部分

   /**
     * 通過查詢id獲得公告的資訊,這裡使用快取來提高效率
     * @param id  公告資訊的id
     * @return
     */
    @Override
    public ResultBean getNoticeInfo(int id) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            //從快取中讀取,判斷快取中是否含有資料
            Map<String, String> stringMap = jedis.hgetAll(id + "noticeinfo");
            if (stringMap == null || stringMap.isEmpty()) {
                //設定防止穿透,判斷資料庫中是否含有該項資料,沒有的話就不用去查詢資料庫了
                Boolean fangchuantou_notice = jedis.sismember("fangchuantou_notice", String.valueOf(id));
                if (fangchuantou_notice) {
                    Notice notice = noticeMapper.getNoticeInfo(id);
                    if (notice != null) {
                        //將資料新增到快取中
                        RedisUtils.hSet(id, notice, jedis);
                        //設定資料在快取中的儲存時間,單位是 秒
                        jedis.expire(id + "noticeinfo", 1800);
                        return ResultBean.setOk(notice);
                    }
                }
            }else {
                    return ResultBean.setOk(stringMap);
                }
            }catch(Exception e){
                e.printStackTrace();
                throw e;
            }finally{
                if (jedis != null) {
                    jedis.close();
                }
            }
        return ResultBean.setError(ErrorCodeInterface.XIUGAIMIMASHIBAI,"查詢失敗",null);
    }

第五部分:為了防止穿透,在伺服器啟動的時候就遍歷資料庫,將所有的key值便利出來

package com.qf.fayuan.config;

import com.qf.fayuan.mapper.NoticeMapper;
import com.qf.fayuan.notice.pojo.Notice;
import io.swagger.models.auth.In;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import javax.annotation.PostConstruct;
import java.util.List;

@Configuration
public class GetAllRedisConfig {

    @Autowired
    private JedisPool jedisPool;

    @Autowired
    private NoticeMapper noticeMapper;

    @PostConstruct
    public void init(){
         Jedis jedis = jedisPool.getResource();
         List<Integer> list =  noticeMapper.getAllNoticeKey();
//         String[]  arr = list.toArray(new String[list.size()]);
        String[] arr = new String[list.size()];
        for (int i = 0; i < list.size(); i++) {
            arr[i] = list.get(i).toString();
        }
         jedis.sadd("fangchuantou_notice",arr);
         jedis.close();
    }
}

第六部分:在使用者執行其他操作時(增刪改查),要實時更新防穿透列表



@Service
public class NoticeServiceImpl implements NoticeService {

    @Autowired
    private NoticeMapper noticeMapper;

    @Autowired
    private JedisPool jedisPool;
    @Override
    public void addNotice(Notice notice) {
        noticeMapper.addNotice(notice);
        //比如新增資料的時候,更新放穿透列表
        Jedis jedis = jedisPool.getResource();
        jedis.sadd("fangchuantou_notice",notice.getId()+"");
        jedis.close();
    }

上面注意的是,新增資料後如何獲取物件的id 要將selectkey 放在sql插入語句後面

    <insert id="addNotice">
        insert into rw_notice(number, user_id, notice_type_id, court_id, case_num,show_area, about_mobile, about_identify_num, about_name, name_id, create_time, update_time, img,status, trade_no, pub_time, pub_days) values (#{number},#{user_id},#{notice_type_id},#{court_id},#{case_num},#{show_area},#{about_mobile},#{about_identify_num},#{about_name},#{name_id},#{create_time},#{update_time},#{img},#{status},#{trade_no},#{pub_time},#{pub_days})
        <selectKey resultType="int" keyProperty="id" order="AFTER">
            select LAST_INSERT_ID() as value
        </selectKey>
    </insert>