发表于: 2017-04-17 23:39:30

3 1291


今天完成的事情:

学习redis:

1.关于昨天遇到的问题:

Caused by: java.lang.ClassNotFoundException: org.apache.commons.pool2.impl.GenericObjectPoolConfig

网上的解决办法,也是说找到这个jar包,今天仔细检查了一下,是我搞错了文件名,导致没有依赖成功,修改后即可。枉我昨天试了那么多方法。

2.

注意新版的(具体从哪个版本开始不清楚,有兴趣可以查一下)JedisPoolConfig的property name,不是maxActive而是maxTotal,而且没有maxWait属性,建议看一下Jedis源码。
出现的问题:好像也会出现1中的错误。

3.通过搜索又发现了spring和redis集成的用法:

首先在jedis的配置文件中把jedisPoolConfig和sharedJedisPool作为bean引入。

然后自定义一个类来实现jedis实例的生成和回收。如:JedisDataSourceImpl.class

在然后编写一个具体的Jedis操作类,可以在redis缓存中对对象进行CURD。然后可以在业务逻辑中使用redis了。


这种方法,就是配置了两个pool,然后自己生成jedis的实例,并且编写具体的jedis操作类,对数据进行操作(自定义的),然后再将操作类应用到具体的业务上。
我感觉这种做法和我现在用到的不太一样:我引用的是spring-data-redis,根据redisTemplate来对数据进行操作。而不是自定义。

4.

StringRedisTemplate和RedisTemplate区别
RedisTemplate支持pojo对象,StringRedisTemplate键值对操作的是字符串.

5.参照搜索的内容自己写了一些关于字符串和对象在redis里的操作

①使用回调函数进行字符串操作

@Override
public Boolean addUser2(final String sex) {

//使用回调函数(stringRedisTemplate只可以操作字符串)
   Boolean result = stringRedisTemplate.execute(new RedisCallback<Boolean>() {
@Override
       public Boolean doInRedis(RedisConnection redisConnection) throws DataAccessException {

RedisSerializer<String> redisSerializer = getRedisSerializer();
           byte[] s = redisSerializer.serialize(sex);
           byte[] boy = redisSerializer.serialize("男");
           System.out.println("添加sex 到redis 成功");
           System.out.println("序列化后的boy" + boy);
           return redisConnection.setNX(s,boy);
       }
});
   return result;
}
@Override
public String get(final String keyName) {
String result = stringRedisTemplate.execute(new RedisCallback<String>() {
@Override
       public String doInRedis(RedisConnection redisConnection) throws DataAccessException {
RedisSerializer<String> redisSerializer = getRedisSerializer();
           byte[] key = redisSerializer.serialize(keyName);
           byte[] value = redisConnection.get(key);
           if(value == null){
System.out.println("缓存中没有该对象");
               return  null;
           }
String sex = redisSerializer.deserialize(value);
           System.out.println("缓存中有该对象:" + sex);
           return sex;
       }
});

   return  result;
}

用redisTemplate的api来操作字符串:

@Override
public void addUser() {
/*ValueOperations<String,User>  valueOperations = redisTemplate.opsForValue();
   valueOperations.set(user.getU_name(),user);*/
   //redisTemplate 可以操作对象
   redisTemplate.opsForValue().set("name","王欢");
   String name = redisTemplate.opsForValue().get("name");
   System.out.println("名字是:" + name);
   System.out.println("添加字符串到redis成功");
}

api操作存储和获取对象:

@Override
public void addUser3(User user) {
try {
redisTemplate.opsForValue().set("userId:" + user.getU_id(),user);
       //User user1= (User) redisTemplate.opsForValue().get("userId:" + 10);
       Object o = redisTemplate.opsForValue().get("userId:" + user.getU_id());
       System.out.println(o);

   } catch (Exception e) {
System.out.println("UserDao  出错");
       e.printStackTrace();
   }

}

结果:可以输出缓存中的对象。(异常是controller层,在task4基础上修改,出现的错误我都catch了,保证程序正常进行。)

但是用其操作对象会出现点问题,我感觉很可惜,因为这是很简单的方法,相对于我用的其他方法来操作对象。

②回调函数操作对象:保存

@Override
public Boolean save(final User user) {
final byte[] value = SerializeUtil.serialize(user);
   Boolean result = (Boolean) redisTemplate.execute(new RedisCallback<Boolean>() {
@Override
       public Boolean doInRedis(RedisConnection redisConnection) throws DataAccessException {
RedisSerializer<String> redisSerializer = getRedisSerializer();
           byte[] key = redisSerializer.serialize("userId:" + user.getU_id());
           System.out.println("已经把key缓存到redis中   key:" + key);
           return redisConnection.setNX(key, value);
       }
});
   return  result;
}

获取对象:

@Override
public Object getObject(final String key) {
return  redisTemplate.execute(new RedisCallback() {
@Override
       public Object doInRedis(RedisConnection redisConnection) throws DataAccessException {
RedisSerializer<String> redisSerializer = getRedisSerializer();
           byte[] k = redisSerializer.serialize(key);
           if (k != null) {
byte[] value = redisConnection.get(k);
               Object o = null;
               if (value != null) {
o = SerializeUtil.unserialize(value);
               }
return o;
           }
return null;
       }
});
}

对象需要序列化,所以用到了工具类:(回调函数中好像只能将字符串转换字节,不能将对象转换)

public class SerializeUtil {
public static byte[] serialize(Object object) {
ObjectOutputStream oos = null;
       ByteArrayOutputStream baos = null;
       try {
// 序列化
           baos = new ByteArrayOutputStream();
           oos = new ObjectOutputStream(baos);
           oos.writeObject(object);
           byte[] bytes = baos.toByteArray();
           return bytes;
       } catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
       }
}

public static Object unserialize(byte[] bytes) {
ByteArrayInputStream bais = null;
       try {
// 反序列化
           bais = new ByteArrayInputStream(bytes);
           ObjectInputStream ois = new ObjectInputStream(bais);
           return ois.readObject();
       } catch (Exception e) {
throw new RuntimeException(e.getMessage(), e);
       }
}
}


6.关于删除缓存中的内容需要注意:

redisTemplate和stringRedisTemplate  序列化策略不同
就是因为序列化策略的不同,即使是同一个key用不同的Template去序列化,结果是不同的。所以根据key去删除数据的时候就出现了删除失败的问题。
解决办法:



明天计划的事情:

1.对项目中写的接口性能测试

2。开始任务八

遇到的问题:

1.

java.net.ConnectException: Connection refused: connect
这是一个令人纠结的问题:简直蠢得不要不要的,我想过redis是不是要像memcache一样先打开,但是我 看的教程一个都没有提到这一点。

2.

JedisConnectionException: java.net.UnknownHostException: 127.0.0.1
解决:
redi.properties文件中  去掉   关于password的部分

3.在本地用命令行查看redis中的内容:全是这种字节形式的。


收获:

发现idea真是有点强大,快捷键熟悉一下,感觉很方便。debug模式感觉也很方便。



返回列表 返回列表
评论

    分享到