此文已由作者赵计刚授权网易云社区发布。
欢迎访问网易云社区,了解更多网易技术产品运营经验。
RedisBaseUtil:
1 package com.xxx.cache.redis; 2 3 import redis.clients.jedis.ShardedJedis; 4 import redis.clients.jedis.ShardedJedisPool; 5 6 /** 7 * 获取ShardJedis与归还实例 8 */ 9 public class RedisBaseUtil { 10 /** 11 * 从ShardJedisPool中获取ShardJedis 12 */ 13 public static ShardedJedis getJedis(){ 14 ShardedJedisPool jedisPool = RedisFactory.getJedisPool();//获取连接池 15 if(jedisPool == null){ 16 return null; 17 } 18 return jedisPool.getResource(); 19 } 20 21 /** 22 * 归还jedis实例到连接池中 23 */ 24 public static void returnJedis(ShardedJedis jedis, boolean broken){ 25 if(jedis==null){//如果传入的jedis是null的话,不需要归还 26 return; 27 } 28 ShardedJedisPool jedisPool = RedisFactory.getJedisPool();//获取连接池 29 if(jedisPool == null){//如果连接池为null的话,不需要归还 30 return; 31 } 32 if(broken){//如果为true的话,表示是因为发生了异常才归还 33 jedisPool.returnBrokenResource(jedis); 34 return; 35 } 36 jedisPool.returnResource(jedis);//缓存正常操作结束之后,归还jedis 37 } 38 }
注意:
RedisStringUtil:
package com.xxx.cache.redis; import com.xxx.cache.util.CachePrefix; import redis.clients.jedis.ShardedJedis; /** * 字符串缓存操作类或者JavaBean缓存操作类 * key String, value String-->看下边的注意点2 * key byte[], value byte[]-->key.getBytes[], value 序列化为byte[],通常需要自己写一个序列化工具 * 注意:这一点与memcached不一样,memcached可以key String, value Object * 1、memcached直接加序列化器就可以,或者在业务层中将Object-->String * 2、redis执行此接口,一般只会采用后者Object-->String */ public class RedisStringUtil extends RedisBaseUtil{ private static final String KEY_SPLIT = "-";//用于隔开缓存前缀与缓存键值 /** * 设置缓存 * 类似于memcached的set,不管是否已经有相同的key,都成功 * 实际上只是set(String, String) */ public static void set(CachePrefix keyPrefix, String key, String value){ boolean broken = false;//标记:该操作是否被异常打断而没有正常结束 ShardedJedis jedis = null; try { jedis = getJedis();//获取jedis实例 if(jedis==null){ broken = true; return; } jedis.set(keyPrefix+KEY_SPLIT+key, value);//set(String,String),value除了string以外,还可以是byte[] } catch (Exception e) { broken = true; }finally{ returnJedis(jedis, broken); } } /** * 设置缓存,并指定缓存过期时间,单位是秒 */ public static void setex(CachePrefix keyPrefix, String key, String value, int expire){ boolean broken = false;//该操作是否被异常打断而没有正常结束 ShardedJedis jedis = null; try { jedis = getJedis();//获取jedis实例 if(jedis==null){ broken = true; return; } jedis.setex(keyPrefix+KEY_SPLIT+key, expire, value); } catch (Exception e) { broken = true; }finally{ returnJedis(jedis, broken); } } /** * 设置缓存,如果设置的key不存在,直接设置,如果key已经存在了,则什么操作都不做,直接返回 * 类似于memcached的add */ public static boolean setnx(CachePrefix keyPrefix, String key, String value){ boolean broken = false;//该操作是否被异常打断而没有正常结束 ShardedJedis jedis = null; try { jedis = getJedis();//获取jedis实例 if(jedis==null){ broken = true; return false; } long setCount = jedis.setnx(keyPrefix+KEY_SPLIT+key, value); if(setCount == 1){ return true; } return false; } catch (Exception e) { broken = true; }finally{ returnJedis(jedis, broken); } return false; } /** * 根据key获取缓存 * @param key * @return String */ public static String get(CachePrefix keyPrefix, String key){ boolean broken = false;//该操作是否被异常打断而没有正常结束 ShardedJedis jedis = null; try { jedis = getJedis();//获取jedis实例 if(jedis==null){ broken = true; return null; } return jedis.get(keyPrefix+KEY_SPLIT+key); } catch (Exception e) { broken = true; }finally{ returnJedis(jedis, broken); } return null; } /** * 删除缓存 */ public static void delete(CachePrefix keyPrefix, String key){ boolean broken = false;//该操作是否被异常打断而没有正常结束 ShardedJedis jedis = null; try { jedis = getJedis();//获取jedis实例 if(jedis==null){ broken = true; return; } jedis.del(keyPrefix+KEY_SPLIT+key); } catch (Exception e) { broken = true; }finally{ returnJedis(jedis, broken); } } /** * 更新缓存过期时间,单位:秒 * 从运行该方法开始,为相应的key-value设置缓存过期时间expire * 类似于memcached中的touch命令 */ public static void setExpire(CachePrefix keyPrefix, String key, int expire){ boolean broken = false; ShardedJedis jedis = null; try { jedis = getJedis(); if(jedis==null){ broken = true; return; } jedis.expire(keyPrefix+KEY_SPLIT+key, expire); } catch (Exception e) { broken = true; }finally{ returnJedis(jedis, broken); } } /** * 测试 */ public static void main(String[] args) { //System.out.println(RedisStringUtil.get("hello")); //RedisStringUtil.delete("hello"); //RedisStringUtil.setex("hello1", "word1", 1); //RedisStringUtil.setExpire("hello1", 20); //System.out.println(RedisStringUtil.get("hello1")); } }
注意:
附:
这里需要安装一个redis服务器,redis在实际使用中是安装在Linux上的,我们为了方便,使用windows版本的(我这里使用了redis2.6-win32),如果是64bit的,可以使用redis2.8。
redis2.6(32bit)的文件下载链接:http://pan.baidu.com/s/1hri1erq
安装方式如下:
下载后解压,此时如果直接双击"redis-server.exe",可能会报内存警告,所以先修改redis.conf文件,添加如下配置,如果你下载的上边的链接,可能已经配置了。
之后,以管理员身份运行cmd.exe,并在命令窗口中进入redis-server.exe所在目录下,执行"redis-server.exe redis.conf"即可。
2.3、ssmm0-data
AdminService:
/*********************redis********************/ public Admin findAdminByIdFromRedis(int id) { //从缓存中获取数据 String adminStr = RedisStringUtil.get(CachePrefix.USER_MANAGEMENT, String.valueOf(id)); //若缓存中有,直接返回 if(StringUtils.isNoneBlank(adminStr)){ return Admin.parseJsonToAdmin(adminStr); } //若缓存中没有,从数据库查询 Admin admin = adminDao.getUserById(id); //若查询出的数据不为null if(admin!=null){ //将数据存入缓存 RedisStringUtil.set(CachePrefix.USER_MANAGEMENT, String.valueOf(id), admin.toJson()); } //返回从数据库查询的admin(当然也可能数据库中也没有,就是null) return admin; }
说明:只添加了如上方法,相当于将上一节的memcached缓存换成了redis
2.4、ssmm0-userManagement
AdminController:
说明:只添加了如上方法。
3、测试
首先对ssmm0整个项目"clean compile",然后通过浏览器访问,进行整体测试,测试方法与上一章《第八章 企业项目开发--分布式缓存memcached》完全相同
在以上的代码中,我只写了redis的String类型数据结构的缓存操作,其余的四种下一篇再说。
免费领取验证码、内容安全、短信发送、直播点播体验包及云服务器等套餐
更多网易技术、产品、运营经验分享请点击。