SSM-Spring+SpringMVC+Mybatis框架相信你們都很熟悉了,可是有的時候須要頻繁訪問數據庫中不變或者不常常改變的數據,就會加劇數據庫的負擔,這時咱們就會想起Redishtml
Redis是由C語言編寫,高性能的key-value存儲系統,經常使用於緩存不常常變更或者根本不變的數據,Redis高級:http://www.javashuo.com/article/p-ylmgjcna-bq.htmljava
廢話很少說,先練練手再說git
安裝Redisgithub
這裏介紹的window下的安裝redis
一、下載spring
下載地址:https://github.com/MSOpenTech/redis/releases
數據庫
下載適合本身系統的zip包,而後解壓到想放的地方,我這裏直接放在E盤下apache
Win+R輸入cmd 進入E盤,Redis下,哎呀廢話很少說了,直接傳送http://www.runoob.com/redis/redis-install.htmlwindows
二、安裝+配置緩存
若是每次啓動都像上面那樣未免太麻煩了,因此咱們接下來把它作成服務,這樣啓動就方便多了。
cmd到redis.windows-service.conf所在目錄,執行
redis-server --service-install redis-windows-conf
就能夠了,接下來咱們就能夠在Windows任務管理器服務裏面找到Redis了,能夠右鍵啓動,也能夠
cmd 下輸入redis-server --service-start啓動
接下來配置redis.windows-service.conf,爲何不修改redis.windows.conf呢?
由於Redis服務默認加載的redis.windows-service.conf配置文件
配置文件裏面對於初級者須要修改的很少,
1、Redis默認不是以守護進程的方式運行,能夠經過該配置項修改,使用yes啓用守護進程 daemonize no 2、當Redis以守護進程方式運行時,Redis默認會把pid寫入/var/run/redis.pid文件,能夠經過pidfile指定 pidfile /var/run/redis.pid 3、設置Redis鏈接密碼,若是配置了鏈接密碼,客戶端在鏈接Redis時須要經過AUTH <password>命令提供密碼,默認關閉 requirepass foobared
更多配置詳見http://www.runoob.com/redis/redis-conf.html
SSM集成Redis
終於到這一步了,廢話很少說
首先固然是添加依賴
<spring.redis.version>1.6.0.RELEASE</spring.redis.version> <jedis.version>2.7.2</jedis.version> <!-- config redis data and client jar--> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> <version>${spring.redis.version}</version> </dependency> <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-pool2 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> <version>${commons.version}</version> </dependency> <!-- https://mvnrepository.com/artifact/redis.clients/jedis --> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>${jedis.version}</version> </dependency>
resources目錄下新建redis.properties
redis.host=127.0.0.1 redis.port=6379 redis.password=960521 redis.maxIdle=300 redis.maxWaitMillis=1000 redis.maxTotal=600 redis.testOnBorrow=true redis.testOnReturn=true redis.testWhileIdle=true redis.blockWhenExhausted=false redis.numTestsPerEvictionRun=1024 redis.timeBetweenEvictionRunsMillis=30000 redis.minEvictableIdleTimeMillis=1800000
而後Spring整合Redis,我配置在Spring-Mybatis.xml
<!--掃描redis配置文件--> <context:property-placeholder ignore-unresolvable="true" location="classpath:redis.properties"/> <!--Spring整合Redis--> <!--設置鏈接池--> <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig"> <!-- 最大空閒鏈接數 --> <property name="maxIdle" value="${redis.maxIdle}"/> <!-- 最大鏈接數 --> <property name="maxTotal" value="${redis.maxTotal}" /> <!-- 每次釋放鏈接的最大數目 --> <property name="numTestsPerEvictionRun" value="${redis.numTestsPerEvictionRun}" /> <!-- 釋放鏈接的掃描間隔(毫秒) --> <property name="timeBetweenEvictionRunsMillis" value="${redis.timeBetweenEvictionRunsMillis}" /> <!-- 鏈接最小空閒時間 --> <property name="minEvictableIdleTimeMillis" value="${redis.minEvictableIdleTimeMillis}" /> <!-- 獲取鏈接時的最大等待毫秒數,小於零:阻塞不肯定的時間,默認-1 --> <property name="maxWaitMillis" value="${redis.maxWaitMillis}" /> <!-- 在獲取鏈接的時候檢查有效性, 默認false --> <property name="testOnBorrow" value="${redis.testOnBorrow}" /> <property name="testOnReturn" value="${redis.testOnReturn}" /> <!-- 在空閒時檢查有效性, 默認false --> <property name="testWhileIdle" value="${redis.testWhileIdle}" /> <!-- 鏈接耗盡時是否阻塞, false報異常,ture阻塞直到超時, 默認true --> <property name="blockWhenExhausted" value="${redis.blockWhenExhausted}" /> </bean> <!-- jedis客戶端單機版 --> <bean id="redisClient" class="redis.clients.jedis.JedisPool"> <constructor-arg name="host" value="${redis.host}"></constructor-arg> <constructor-arg name="port" value="${redis.port}"></constructor-arg> <constructor-arg name="password" value="${redis.password}"></constructor-arg> <constructor-arg name="poolConfig" ref="poolConfig"></constructor-arg> <constructor-arg name="timeout" value="100000"></constructor-arg> </bean> <bean id="JedisClient" class="com.smart.redis.JedisClientSingle"/>
首先建立一個接口,下面不少方法都用不到,標紅的是我常常用的
import java.io.File; import java.util.List; public interface JedisClient { String get(String key); String set(String key,String value); public void setList(String key,List<?> value); public List<?> getList(String key); public void setObject(String key,Object o); public Object getObject(String key); public void clear(); public Object removeObject(String str); public int getSize(); public void setFile(String key,String path); public File getFile(String key); String hashGet(String key,String value);//獲取存儲結構爲hashMap的類型數據 long hset(String hkey,String key, String value); long incr(String key); long expire(String key,int second); long tt1(String key); long del(String key);//刪除數據 long hashDel(String hkey,String key); }
而後實現類
import org.springframework.beans.factory.annotation.Autowired; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import java.io.File; import java.util.List; public class JedisClientSingle implements JedisClient { @Autowired private JedisPool jedisPool; @Override public String get(String key) { Jedis jedis = jedisPool.getResource(); String str = jedis.get(key); jedis.close(); return str; } @Override public String set(String key, String value) { Jedis jedis = jedisPool.getResource(); String str = jedis.set(key,value); jedis.close(); return str; } @Override public long hset(String hkey, String key, String value) { Jedis jedis = jedisPool.getResource(); Long result = jedis.hset(hkey,key,value); jedis.close(); return result; } @Override public String hashGet(String key, String value) { Jedis jedis = jedisPool.getResource(); String str = jedis.hget(key,value); jedis.close(); return str; } @Override public long hashDel(String hkey, String key) { return 0; } @Override public long tt1(String key) { return 0; } @Override public long expire(String key, int second) { Jedis jedis = jedisPool.getResource(); Long result = jedis.expire(key,second); jedis.close(); return result; } @Override public long incr(String key) { return 0; } @Override public long del(String key) { Jedis jedis = jedisPool.getResource(); Long result = jedis.del(key); jedis.close(); return result; } @Override public void setList(String key, List<?> list) { Jedis jedis = jedisPool.getResource(); try{ if(list != null && !list.isEmpty()){ jedis.set(key.getBytes(),SerializeUtil.serializeList(list)); }else{ jedis.set(key.getBytes(), "".getBytes()); } }catch (Exception e){ e.printStackTrace(); } } @Override public List<?> getList(String key) { Jedis jedis = jedisPool.getResource(); if(jedis==null || !jedis.exists(key)){ return null; } byte[] data = jedis.get(key.getBytes()); return SerializeUtil.unSerializeList(data); } @Override public void setObject(String key, Object o) { Jedis jedis = jedisPool.getResource(); try{ o = o == null ? new Object():o; jedis.set(key.getBytes(),SerializeUtil.serializeObject(o)); }catch (Exception e){ e.printStackTrace(); } } @Override public Object getObject(String key) { Jedis jedis = jedisPool.getResource(); if(jedis == null || !jedis.exists(key)){ return null; } byte[] data = jedis.get(key.getBytes()); return (Object)SerializeUtil.unSerializeObject(data); } @Override public void clear() { Jedis jedis = jedisPool.getResource(); jedis.flushDB(); } @Override public Object removeObject(String key) { return jedisPool.getResource().expire(SerializeUtil.serializeObject(key), 0); } @Override public int getSize() { return Integer.valueOf(jedisPool.getResource().dbSize().toString()); } //保存文件方法 public void setFile(String key,String path){ Jedis jedis = jedisPool.getResource(); File fr = new File(path); try{ jedis.set(key.getBytes(), SerializeUtil.serializeObject(fr)); }catch (Exception e){ e.printStackTrace(); } } //讀取文件對象方法 public File getFile(String key){ Jedis jedis = jedisPool.getResource(); File file = (File)SerializeUtil.unSerializeObject(jedis.get(key.getBytes())); return file; } }
因爲Redis只能存儲5種類的數據,包括String、List、Set、zset和hash,其餘的類型則須要序列化以後方可存儲
下面這是序列化工具類
import java.io.*; import java.util.ArrayList; import java.util.List; public class SerializeUtil { /** * * 序列化對象 */ public static byte[] serializeObject(Object obj) { if(obj == null){ return null; } ObjectOutputStream oos = null; ByteArrayOutputStream baos = null; byte[] bytes = null; try { // 序列化 baos = new ByteArrayOutputStream(); oos = new ObjectOutputStream(baos); oos.writeObject(obj); bytes = baos.toByteArray(); } catch (IOException e) { e.printStackTrace(); }finally { close(oos); close(baos); } return bytes; } /** * * 反序列化 * * @param bytes * @return */ public static Object unSerializeObject(byte[] bytes) { if(bytes == null){ return null; } ByteArrayInputStream bais = null; ObjectInputStream ois = null; try { // 反序列化爲對象 bais = new ByteArrayInputStream(bytes); ois = new ObjectInputStream(bais); return ois.readObject(); } catch (Exception e) { e.printStackTrace(); }finally { close(bais); close(ois); } return null; } /** * * 序列化 */ public static byte[] serializeList(List<?> list) { if(list==null || list.isEmpty()){ return null; } ObjectOutputStream oos = null; ByteArrayOutputStream baos = null; byte[] bytes = null; try { // 序列化 baos = new ByteArrayOutputStream(); oos = new ObjectOutputStream(baos); for(Object o : list){ oos.writeObject(o); } bytes = baos.toByteArray(); } catch (IOException e) { e.printStackTrace(); }finally { close(oos); close(baos); } return bytes; } /** * * 反序列化 * * @param bytes * @return */ public static List<?> unSerializeList(byte[] bytes) { if(bytes == null){ return null; } List<Object> list = new ArrayList<Object>(); ByteArrayInputStream bais = null; ObjectInputStream ois = null; try { // 反序列化爲對象 bais = new ByteArrayInputStream(bytes); ois = new ObjectInputStream(bais); while (bais.available()>0){ Object o = (Object)ois.readObject(); if(o == null){ break; } list.add(o); } } catch (Exception e) { e.printStackTrace(); }finally { close(bais); close(ois); } return list; } //關閉IO流對象 public static void close(Closeable closeable){ if(closeable != null){ try{ closeable.close(); }catch (Exception e){ e.printStackTrace(); } } } }
至此咱們就整合好了,下面測試一下
@Service("userService") public class UserServiceImpl implements UserService { @Autowired private UserDao userDao; //注入 @Autowired com.smart.redis.JedisClient JedisClient; //判斷工號是否已存在 public boolean isNumberExist(String geNumber){ boolean isSuccess = false; User user = null; //先從Redis裏取 user = (User)JedisClient.getObject(geNumber); if(user==null){ //若是Redis沒有則從數據庫裏取 user = userDao.getUserById(geNumber); if(user!=null){ //從數據庫中取了以後,再存入Redis,以便下次取 JedisClient.setObject(geNumber,(Object) user); } } if(StringUtils.isEmpty(user)){ isSuccess = true; } return isSuccess; } }