三.SSM項目-redis緩存策略和配置實現
距離上兩篇文章已過去蠻久了,爲了響應各位網友的需求,最近把這個系列重新整理下。如有不足之處,請指正。
本章將實現redis緩存策略和Spring集成redis配置。
1. Redis簡單介紹
redis是一個key-value存儲系統。和Memcached類似,它支持存儲的value類型相對更多,包括string(字符串)、list(鏈表)、set(集合)、zset(sortedset --有序集合)和hash(哈希類型)。這些數據類型都支持push/pop、add/remove及取交集並集和差集及更豐富的操作,而且這些操作都是原子性的。在此基礎上,redis支持各種不同方式的排序。與memcached一樣,爲了保證效率,數據都是緩存在內存中。區別的是redis會週期性的把更新的數據寫入磁盤或者把修改操作寫入追加的記錄文件,並且在此基礎上實現了master-slave(主從)同步。
Redis是一個高性能的key-value數據庫。 redis的出現,很大程度補償了memcached這類key/value存儲的不足,在部 分場合可以對關係數據庫起到很好的補充作用。它提供了Java,C/C++,C#,PHP,JavaScript,Perl,Object-C,Python,Ruby,Erlang等客戶端,使用很方便。
Redis支持主從同步。數據可以從主服務器向任意數量的從服務器上同步,從服務器可以是關聯其他從服務器的主服務器。這使得Redis可執行單層樹複製。存盤可以有意無意的對數據進行寫操作。由於完全實現了發佈/訂閱機制,使得從數據庫在任何地方同步樹時,可訂閱一個頻道並接收主服務器完整的消息發佈記錄。同步對讀取操作的可擴展性和數據冗餘很有幫助。
----摘自百度百科
總結:
1.1 Redis是一個key-value存儲系統,支持多種存儲結構,如String,Hash,list,zset等;
1.2 Redis採用內存中數據集的形式,因此讀寫性能優異;
1.3 Redis支持數據持久化,支持AOF和RDB兩種持久化方式;
1.4 Redis類似mysql可以進行主從複製,可以實現讀寫分離;
1.5 Redis由於是內存中數據集存儲的,故對內存的要求較高,對海量數據處理有限制;
1.6 Redis主從複製時,由於宕機或其他情況一起,導致最後部分數據可能丟失。
2. Redis緩存策略
Redis和數據庫結合使用,使用策略如下:
2.1 讀取數據
2.2 更新數據—常用數據,變動性不強,併發不高
2.3 更新數據—併發較高
3. Spring集成redis
3.1 applicationContext-redis.xml
spring與redis集成配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd">
<!-- 連接池配置 -->
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<!-- 最大連接數 -->
<property name="maxTotal" value="30" />
<!-- 最大空閒連接數 -->
<property name="maxIdle" value="10" />
<!-- 每次釋放連接的最大數目 -->
<property name="numTestsPerEvictionRun" value="1024" />
<!-- 釋放連接的掃描間隔(毫秒) -->
<property name="timeBetweenEvictionRunsMillis" value="30000" />
<!-- 連接最小空閒時間 -->
<property name="minEvictableIdleTimeMillis" value="1800000" />
<!-- 連接空閒多久後釋放, 當空閒時間>該值 且 空閒連接>最大空閒連接數 時直接釋放 -->
<property name="softMinEvictableIdleTimeMillis" value="10000" />
<!-- 獲取連接時的最大等待毫秒數,小於零:阻塞不確定的時間,默認-1 -->
<property name="maxWaitMillis" value="1500" />
<!-- 在獲取連接的時候檢查有效性, 默認false -->
<property name="testOnBorrow" value="true" />
<!-- 在空閒時檢查有效性, 默認false -->
<property name="testWhileIdle" value="true" />
<!-- 連接耗盡時是否阻塞, false報異常,ture阻塞直到超時, 默認true -->
<property name="blockWhenExhausted" value="false" />
</bean>
<bean id="jedisPool" class="redis.clients.jedis.JedisPool">
<constructor-arg name="host" value="${redis.ip}"></constructor-arg>
<constructor-arg name="port" value="${redis.port}"></constructor-arg>
<constructor-arg name="poolConfig" ref="jedisPoolConfig"></constructor-arg>
</bean>
</beans>
3.2 redisDao接口和實現
簡單通過redis實現增刪改查
package com.ssm.manager.dao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import redis.clients.jedis.JedisPool;
@Repository("redisDao")
public class RedisDaoImpl implements RedisDao {
@Autowired
private JedisPool jedisPool;
@Override
public String get(String key) {
return jedisPool.getResource().get(key);
}
@Override
public String set(String key, String value) {
return jedisPool.getResource().set(key,value);
}
@Override
public String hget(String hkey, String key) {
return jedisPool.getResource().hget(hkey, key);
}
@Override
public long hset(String hkey, String key, String value) {
return jedisPool.getResource().hset(hkey, key,value);
}
}
3.3 UserServiceImpl實現
實現User業務,先查redis,如果不存在從數據庫獲取,然後把相關信息寫入到redis
package com.ssm.manager.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import com.ssm.commons.JacksonUtils;
import com.ssm.manager.dao.RedisDao;
import com.ssm.manager.mapper.UserMapper;
import com.ssm.manager.pojo.User;
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
@Autowired
private RedisDao redisDao;
@Override
public List<User> getUsers() {
return userMapper.getUsers();
}
@Override
public void insertUser(User user) {
userMapper.insertUser(user);
String userJson = redisDao.get("user_" + user.getId());
if(StringUtils.isEmpty(userJson)){
redisDao.set("user_" + user.getId(), JacksonUtils.objectToJson(user));
}
}
@Override
public User getUserById(String id) {
String userJson = redisDao.get("user_" + id);
User user = null;
if(StringUtils.isEmpty(userJson)){
user = userMapper.getUserById(id);
//不存在,設置
if(user != null)
redisDao.set("user_" + id, JacksonUtils.objectToJson(user));
}else{
user = JacksonUtils.jsonToPojo(userJson, User.class);
}
return user;
}
}
4. 單元測試
package com.ssm.test;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.ssm.manager.pojo.User;
import com.ssm.manager.service.UserService;
public class ssmTest {
private ApplicationContext ctx = null;
private UserService userService = null;
@Before
public void init()
{
ctx = new ClassPathXmlApplicationContext("spring/applicationContext-service.xml");
userService = ctx.getBean(UserService.class);
}
@Test
public void testGetUsers(){
List<User> users = userService.getUsers();
System.out.println(users);
}
@Test
public void testInsertUser(){
User user = new User();
user.setPassword("123");
user.setUserName("ssm1111");
userService.insertUser(user);
}
@Test
public void testGetUserById(){
String id="4";
System.out.println(userService.getUserById(id));
}
}
5. 總結
本章簡單的介紹Spring與redis框架jedis集成。如果需要也可以考慮通過spring data redis去集成.
後續本來也會通過springboot+spring data redis的實例來實現redis。
6. 代碼路徑
代碼下載:http://download.csdn.net/download/a123demi/10029883
轉載:https://blog.csdn.net/a123demi/article/details/78284555