java后台的访问时间大多是在操作数据库上,对于java本身的业务逻辑流程判断时间相对来说都比较少,所以我们有必要减少对mysql的访问。而redis数据库的访问就是特别的快,这时就可以使用redis实现简单缓存,首先在redis数据库中获取数据,如果没有,那就再到mysql数据库中获取,同时更新redis数据库,将这条记录放入redis。
在redis的使用中,有些业务使用比较频繁,所以直接放在service层实现不太好,应该另外建一个dao层代码类。如下:
RuntimeSchema是一个序列化的转换工具,可以实现指定的类对象和byte数组的相互转换。
byte[] bytes = ProtostuffIOUtil.toByteArray(record, schema , LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE));通过序列化工具把record转为byte数组,第三个参数呢LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE)就是一个缓冲器,加快序列化的效率。
jedis.setex(key.getBytes(), 3600, bytes);这个就是通过jedis访问redis数据库,插入一条记录,3600就是设定这条记录的超时时间。
package cn.wzy.dao.Impl;
import cn.wzy.entity.User;
import com.dyuproject.protostuff.LinkedBuffer;
import com.dyuproject.protostuff.ProtostuffIOUtil;
import com.dyuproject.protostuff.runtime.RuntimeSchema;
import lombok.extern.log4j.Log4j;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
/**
* Created by Wzy
* on 2018/6/4
*/
@Log4j
public class RedisDao {
private final JedisPool jedisPool;
public RedisDao(String ip, int port) {
jedisPool = new JedisPool(ip, port);
}
private final RuntimeSchema<User> schema = RuntimeSchema.createFrom(User.class);
public User getUser(int userId) {
try {
Jedis jedis = jedisPool.getResource();
try {
String key = "user:" + userId;
byte[] bytes = jedis.get(key.getBytes());
if (bytes != null) {
User user = schema.newMessage();
ProtostuffIOUtil.mergeFrom(bytes, user, schema);
return user;
}
} catch (Exception e) {
e.printStackTrace();
} finally {
jedis.close();
}
} catch (Exception e) {
log.error(e.getMessage(), e);
}
return null;
}
public String putUser(User record) {
try {
Jedis jedis = jedisPool.getResource();
try {
String key = "user:" + record.getId();
byte[] bytes = ProtostuffIOUtil.toByteArray(record, schema
, LinkedBuffer.allocate(LinkedBuffer.DEFAULT_BUFFER_SIZE));
String result = jedis.setex(key.getBytes(), 3600, bytes);
return result;
} finally {
jedis.close();
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
这里就需要加入jedis的访问依赖项,以及序列化工具的依赖项:
<!--jedis依赖-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.7.3</version>
</dependency>
<!-- 序列换依赖 -->
<dependency>
<groupId>com.dyuproject.protostuff</groupId>
<artifactId>protostuff-core</artifactId>
<version>1.0.8</version>
</dependency>
<dependency>
<groupId>com.dyuproject.protostuff</groupId>
<artifactId>protostuff-runtime</artifactId>
<version>1.0.8</version>
</dependency>
这里模拟一下获取用户业务逻辑的优化:
package cn.wzy.service;
import cn.wzy.dao.Impl.RedisDao;
import cn.wzy.dao.UserDao;
import cn.wzy.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* Created by Wzy
* on 2018/6/4
*/
@Service
public class UserService {
@Autowired
private UserDao userDao;
@Autowired
private RedisDao redisDao;
public User queryById(int id) {
User user = redisDao.getUser(id);
if (user == null) {
user = userDao.selectByPrimaryKey(id);
System.out.println("select from db.");
if (user == null)
return null;
else {
redisDao.putUser(user);
return user;
}
}
System.out.println("select from redis.");
return user;
}
}
测试阶段:
public class UserServiceTest extends BaseTest {
@Autowired
private UserService userService;
@Test
public void test() {
System.out.println(userService.queryById(1));
System.out.println(userService.queryById(1));
}
}
结果可以看出第二次获取的时候就直接是返回redis数据库的内容啦。
=============start=====test==========
select from redis.
User(id=1, username=2222, age=1222, phoneNum=565656)
select from redis.
User(id=1, username=2222, age=1222, phoneNum=565656)
=============start======end==========