redis(1)

NoSQL 技術

泛指非關係型的數據庫,NoSQL數據庫的產生就是爲了解決大規模數據集合多重數據種類帶來的挑戰,尤爲是大數據應用難題。它是基於內存的數據庫,而且提供必定的持久化功能。redis

Redis和MongoDB是當前使用最普遍的NoSQL,而就Redis技術而言,它的性能十分優越,能夠支持每秒十幾萬此的讀/寫操做,其性能遠超數據庫,而且還支持集羣、分佈式、主從同步等配置,原則上能夠無限擴展,讓更多的數據存儲在內存中,更讓人欣慰的是它還支持必定的事務能力,這保證了高併發的場景下數據的安全和一致性。spring

Redis數據庫

Redis 是一個開源(BSD許可)的,內存中的數據結構存儲系統,它能夠用做數據庫、緩存和消息中間件。 它支持多種類型的數據結構,如字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 與範圍查詢, bitmaps, hyperloglogs 和 地理空間(geospatial) 索引半徑查詢。 Redis 內置了 複製(replication),LUA腳本(Lua scripting), LRU驅動事件(LRU eviction),事務(transactions) 和不一樣級別的 磁盤持久化(persistence), 並經過 Redis哨兵(Sentinel)和自動 分區(Cluster)提供高可用性(high availability)。json

Linux安裝Redis

1)在redis根目錄下執行: make 指令vim

2)安裝:make install緩存

3)reids 啓動校驗:redis -server安全

4)解決控制檯啓動redis後不能在執行其它指令數據結構

 在redis根目錄下執行:vim redis.conf併發

4.1:取消ip綁定app

4.2:關閉保護模式

 

4.3:開啓後臺啓動

 spring管理redis

1.序列化工具類

/**
 *     須要將json串與對象實現互轉

 */
public class ObjectMapperUtil {
    
    private static final ObjectMapper MAPPER = new ObjectMapper();
    
    public static String toJSON(Object obj) {
        String json = null;
        try {
            json = MAPPER.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
        return json;
    }
    
    //將json串轉化爲對象
    public static <T> T toObject(String json,Class<T> targetClass) {
        T obj = null;
        try {
            obj = MAPPER.readValue(json, targetClass);
        } catch (IOException e) {
            
            e.printStackTrace();
            throw new RuntimeException(e);
        }
        return obj;
    }
    
    
    
    
    
    
    
    
    
    
    
}

2.編輯properties文件

redis.host=192.168.175.129
redis.port=6379

3.編輯配置類

@Configuration //標識配置類
@PropertySource("classpath:/properties/redis.properties")
public class RedisConfig {
    
    @Value("${redis.host}")
    private String host;
    @Value("${redis.port}")
    private Integer port;
    
    @Bean
    @Scope("prototype")    //設置爲多例 當用戶使用時建立
    public Jedis jedis() {
        
        return new Jedis(host, port);
    }
    
}

4.業務實現

/**
     * 步驟:
     *     1.先查詢緩存  肯定key的寫法
     *     2.若是緩存中沒有數據.說明用戶第一次查詢.
     *     先查詢數據庫,將數據轉化爲JSON.保存到redis中.
     *     3.若是緩存中有數據.說明不是第一次查詢.從redis中
     *     獲取數據.須要將json轉化爲對象.
     */
    @SuppressWarnings("unchecked")
    @Override
    public List<EasyUITree> findItemCatCache(Long parentId) {
        
        List<EasyUITree> treeList = new ArrayList<>();
        String key = "ITEMCAT::"+parentId;
        String json = jedis.get(key);
        //判斷數據是否爲null
        if(StringUtils.isEmpty(json)) {
            //用戶第一次查詢
            treeList =  findItemCatByParentId(parentId);
            String itemCatJSON = 
                    ObjectMapperUtil.toJSON(treeList);
            jedis.set(key, itemCatJSON);
            System.out.println("用戶第一次查詢數據");
        }else {
            //說明用戶不是第一次查詢
            treeList = 
            ObjectMapperUtil.toObject(json, treeList.getClass());
            System.out.println("用戶查詢緩存!!!!");
        }
        
        return treeList;
    }

 5.控制層實現

@RequestMapping("/list")
    public List<EasyUITree> findItemCatByParentId
    (@RequestParam(value = "id",defaultValue = "0") Long parentId){
        
        //return itemCatService.findItemCatByParentId(parentId);
        
        //先查詢緩存,若是緩存中沒有數據,則查詢數據庫
        return itemCatService.findItemCatCache(parentId);
    }

 

AOP實現緩存查詢

1.自定義註解
@Target(ElementType.METHOD)    //對方法生效
@Retention(RetentionPolicy.RUNTIME) //運行時有效
public @interface CacheFind { 
    
    //1.key能夠動態獲取. 類名.方法名::第一個參數值
    //2.key也能夠本身指定.
    String key()  default "";
    int seconds() default 0;    //用戶數據不超時
    
}

 2.定義切面

@Component    //將類交給容器管理
@Aspect        //標識切面
public class CacheAspect {
    
    @Autowired
    private Jedis jedis;

    //若是是環繞通知,則參數必須寫ProceedingJoinPoint,必須位於第一位
    @Around("@annotation(cacheFind)")
    public Object around(ProceedingJoinPoint joinPoint,CacheFind cacheFind) {
        
        Object obj = null;
        String key = getKey(joinPoint,cacheFind);
        
        //1.先查詢緩存數據
        String result = jedis.get(key);
        try {
            
            if(StringUtils.isEmpty(result)) {
                //第一次查詢數據
                obj = joinPoint.proceed();    //執行目標方法
                //將數據保存到redis中
                String json = ObjectMapperUtil.toJSON(obj);
                //判斷用戶是否傳遞超時時間
                if(cacheFind.seconds()==0) 
                    jedis.set(key, json);
                else 
                    jedis.setex(key, cacheFind.seconds(), json);
                
                System.out.println("執行數據庫查詢");
            }else {
                //數據不爲null,將緩存數據轉化爲對象
                Class returnType = getType(joinPoint);
                obj = ObjectMapperUtil.toObject(result,returnType);
                System.out.println("執行AOP緩存!!!!");
            }
            
        } catch (Throwable e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }

        return obj;
    }
    
    /**
     * 目的:獲取方法的返回值類型
     * 提示:利用方法對象獲取返回值類型
     * @param joinPoint
     * @return
     */
    private Class getType(ProceedingJoinPoint joinPoint) {
        
        MethodSignature signature = 
                (MethodSignature) joinPoint.getSignature();
        
        return signature.getReturnType();
        
        /*
         * Object[] objs = joinPoint.getArgs(); Class[] argsClass = new
         * Class[objs.length]; for (int i=0; i<objs.length;i++) { argsClass[i] =
         * objs[i].getClass(); }
         * 
         * joinPoint.getTarget().getClass().getMethod(name, parameterTypes);
         */
    }

    //判斷用戶是否傳遞參數, 若是用戶傳參使用用戶本身的key.
    //若是用戶沒有指定參數,使用動態生成的.
    private String getKey(ProceedingJoinPoint joinPoint, CacheFind cacheFind) {
        //獲取當前方法的名稱 類名.方法名
        String className = joinPoint.getSignature().getDeclaringTypeName();
        String methodName = joinPoint.getSignature().getName();
        String key = cacheFind.key(); 

        if(!StringUtils.isEmpty(key)) { //以用戶的數據爲準

            return className+"."+methodName+"::"+key;
        }else {//動態拼接參數
            //類名.方法名::第一個參數值
            Object args0 = joinPoint.getArgs()[0];
            return className+"."+methodName+"::"+args0;
        }
    }

}

 

Redis命令

1.啓動命令:redis-server redis.conf

2.進入客戶端 : redis-cli -p 6379

3.查看客戶端詳細信息:info replication

4.關閉reids:redis-cli -p 6379 shutdown

 若是是默認端口  redis-cli shutdown

退出:ctrl+c、exit、quit

相關文章
相關標籤/搜索