redis应用的场景
通过缓存来减少对关系型数据库的查询次数,减轻数据库压力。在执行DAO类的select***(), query***()方法时,先从Redis中查询有没有缓存数据,如果有则直接从Redis拿到结果,如果没有再向数据库发起查询请求取数据。
springboot已经集成了redis缓存,只需要在pom.xml中加载redis,然后通过注解即可完成配置。
首先在配置类中加上 @EnableCaching 注解
然后在DAO类加上@CacheConfig 注解
类中的对数据库操作的函数按功能加上 @CachePut @CacheEvict @Cacheable
@CachePut 是将数据加入到redis缓存中
@Cacheable 在获取数据的时候会先查询缓存,如果缓存中存在,则不执行查询数据库的方法,如果不存在则查询数据库,并加入到缓存中。
@CacheEvict 一般注解到删除数据的操作上,会将一条或多条数据从缓存中删除。
这三个方法都有value 和 key属性。
value指的是缓存的名称,不能为空。也可以在类@CacheConfig注解上指定value,则后面的方法的注解value可省略且value值与类注解的value相同。
key是缓存的键,默认为空,既表示使用方法的参数类型及参数值作为key。可通过key = "#p0",p0为方法的第一个参数,p1为第二个,也可直接 #参数的名字。
还有一个注解为@Caching 用于组合将多个注解注解到一个方法上。
具体代码:
package com.example.demo.dao;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.LinkedList;
import java.util.List;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import com.example.demo.entity.Diary;
import com.example.demo.entity.User;
import com.example.demo.map.DiaryMapper;
import com.example.demo.map.UserMapper;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
@Service
@CacheConfig(cacheNames="userCache") // 本类内方法指定使用缓存时,默认的名称就是userCache
public class UserDAOImpl implements UserDAO{
String resource = null;
InputStream is = null;
SqlSessionFactory sqlSessionFactory = null;
SqlSession sqlSession = null;
public UserDAOImpl() throws IOException {
resource = "sqlMapConfig.xml";
is = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
sqlSession = sqlSessionFactory.openSession();
}
//检查注册时用户名是否可用
public boolean checkUsername(String username) {
boolean flag = true;
UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
String name = userMapper.selectPwdByUsername(username);
sqlSession.commit();
if (name==username) {
flag = true;
}
return flag;
}
//登录时密码验证
@Cacheable()
public boolean checkPass(String username,String pwd){
boolean flag = false;
UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
String pass = userMapper.selectPwdByUsername(username);
System.out.println("查询数据库");
sqlSession.commit();
if(pass != null){
if (pass.equals(pwd)) {
flag = true;
}
}else{
}
return flag;
}
//注册
@CachePut()
public void register(String username,String userpwd,String email,String question,String answer,String photo){
User user = new User();
user.setUsername(username);
user.setPwd(userpwd);
user.setEmail(email);
user.setQuestion(question);
user.setAnswer(answer);
user.setImage(photo);
UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
try {
int flag = userMapper.insertUser(user);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
sqlSession.commit();
}
//分享
@CachePut(key = "#P1")
public void share(String username,String title,String content){
String time=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Calendar.getInstance().getTime());
System.out.println(time);
Diary diary = new Diary();
diary.setTitle(title);
diary.setContent(content);
diary.setWriteTime(time);
//User user = new User();
diary.setUsername(username);
DiaryMapper diaryMapper=sqlSession.getMapper(DiaryMapper.class);
try {
int flag = diaryMapper.insertDiary(diary);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
sqlSession.commit();
}
//@Cacheable() // @Cacheable 会先查询缓存,如果缓存中存在,则不执行方法
public User selectUser(String username){
User user = null;
System.out.println(username);
UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
user = userMapper.selectUser(username);
sqlSession.commit();
return user;
}
@Cacheable(key = "getMethodName()") // @Cacheable 会先查询缓存,如果缓存中存在,则不执行方法
public List seeShare() {
List list = new LinkedList();
DiaryMapper diaryMapper = sqlSession.getMapper(DiaryMapper.class);
list = diaryMapper.selectShare();
sqlSession.commit();
return list;
}
}
当执行时会将数据加入到缓存,在redis可视化工具中查看数据如下
显示的数据就是redis存入到内存中的二进制格式的数据,然后用十六进制显示了出来。
get一下也会显示这些数据
注意:在缓存对象是要让对象类实现Serializable接口,将对象序列化后再存储到内存中,取出来的时候redis会自动反序列化再显示出来。