SpringBoot,Mysql,Redis综合案例(2)
·
SpringBoot,Mysql,Redis综合案例(2)
StudentService的实现
基本框架
@Service
@Slf4j
public class StudentApplicationImpl extends ServiceImpl<StudentMapper, Student> implements StudentService {
// 声明StudentMapper对象,用于数据库操作
private StudentMapper studentMapper;
// 声明StringRedisTemplate对象,用于Redis字符串类型操作
private StringRedisTemplate stringRedisTemplate;
// 声明ValueOperations对象,用于Redis的String类型数据操作
private ValueOperations<String, String> forValue;
// 声明ListOperations对象,用于Redis的List类型数据操作
private ListOperations<String, String> forList;
// 定义学生信息在Redis中的键前缀常量
public static final String PREFIX_STUDENT = "PREFIX_STUDENT";
// 定义存储所有学生信息的Redis键常量
public static final String ALL_STUDENT = "ALL_STUDENT";
// 构造方法,通过@Autowired实现依赖注入
@Autowired
public StudentApplicationImpl(StudentMapper studentMapper, StringRedisTemplate stringRedisTemplate) {
// 赋值studentMapper,用于后续数据库操作
this.studentMapper = studentMapper;
// 赋值stringRedisTemplate,用于后续Redis操作
this.stringRedisTemplate = stringRedisTemplate;
// 初始化forValue,获取Redis的String类型操作对象
this.forValue = stringRedisTemplate.opsForValue();
// 初始化forList,获取Redis的List类型操作对象
this.forList = stringRedisTemplate.opsForList();
}
}
各功能的实现
根据ID查询学生信息(先查Redis缓存,再查数据库)
@Override
public Student getStudentById(String id) {
// 打印日志,记录开始查询指定ID的学生数据
log.info("开始查询id:{}的数据", id);
// 从Redis中查询指定ID的学生信息(键为前缀+ID)
String studentJSON = forValue.get(PREFIX_STUDENT + id);
// 打印日志,记录从Redis查询到的JSON数据
log.info("返回id:{}的数据:{}", id, studentJSON);
// 判断Redis中是否存在该学生的缓存数据
if (studentJSON != null) {
// 将JSON字符串转换为Student对象并返回
return JSONArray.parseObject(studentJSON, Student.class);
}
// Redis中无缓存,从数据库查询该学生信息
Student student = studentMapper.selectById(id);
// 打印日志,记录从数据库查询到的学生数据
log.info("不存在该数据,从数据库中获取该数据:{}", student);
// 将数据库查询到的学生对象转换为JSON字符串
String jsonString = JSONArray.toJSONString(student);
// 将JSON字符串存入Redis,设置键为前缀+ID,过期时间1天
forValue.set(PREFIX_STUDENT + id, jsonString,1, TimeUnit.DAYS);
// 打印日志,记录已将数据存入Redis
log.info("存放数据到redis中");
// 返回从数据库查询到的学生对象
return student;
}
查询所有学生信息(建议方法三)
方法一:
@Override
public List<Student> findAllStudent1() {
// 从Redis中查询所有学生信息(键为ALL_STUDENT)
String string = forValue.get(ALL_STUDENT);
// 判断Redis中是否存在所有学生的缓存数据
if(string != null){
// 将JSON数组字符串转换为List<Student>并返回
return JSONArray.parseArray(string, Student.class);
}
// Redis中无缓存,从数据库查询所有学生信息
List<Student> list = this.list();
// 将数据库查询到的学生列表转换为JSON字符串并存入Redis,设置过期时间1天
forValue.set(ALL_STUDENT, JSONArray.toJSONString(list),1, TimeUnit.DAYS);
// 返回从数据库查询到的学生列表
return list;
}
方法二:
@Override
public List<Student> findAllStudent2() {
// 从Redis的List结构中查询所有学生信息(0到-1表示查询全部元素)
List<String> all = forList.range(ALL_STUDENT, 0, -1);
// 判断Redis中是否存在缓存数据
if(all != null&&!all.isEmpty()){
// 初始化学生列表用于存储转换后的数据
List<Student> list =new ArrayList<>();
// 遍历Redis中获取的JSON字符串
all.forEach(s->{
// 将JSON字符串转换为Student对象
Student jsonObject = JSONArray.parseObject(s , Student.class);
// 添加到学生列表中
list.add(jsonObject);
});
// 返回从Redis缓存中获取的学生列表
return list;
}
// Redis中无缓存,从数据库查询所有学生
List<Student> students = this.list();
// 将数据库查询结果存入Redis缓存
students.forEach(student -> {
// 将Student对象转换为JSON字符串
String s = JSONArray.toJSONString(student);
// 向Redis的List尾部添加学生JSON数据
forList.rightPush(ALL_STUDENT,s);
});
// 返回数据库查询的学生列表
return students;
}
方法三:
@Override
public List<Student> findAllStudent3() {
// 从Redis的List中查询所有学生ID(0到-1表示查询全部)
List<String> all = forList.range(ALL_STUDENT, 0, -1);
// 判断Redis中是否存在缓存的ID列表
if(all != null&&!all.isEmpty()){
// 初始化学生列表用于存储查询结果
List<Student> list =new ArrayList<>();
// 遍历每个学生ID
all.forEach(s->{
// 根据ID从Redis的String结构中获取学生详情JSON
String string = forValue.get(s);
// 将JSON字符串转换为Student对象
Student student = JSONArray.parseObject(string, Student.class);
// 添加到学生列表中
list.add(student);
});
// 返回从Redis缓存中组装的学生列表
return list;
}
// Redis中无缓存,从数据库查询所有学生
List<Student> students = this.list();
// 将数据库查询结果存入Redis缓存(List存ID,String存详情)
students.forEach(student -> {
// 向Redis的List尾部添加学生ID
forList.rightPush(ALL_STUDENT,student.getId()+"");
// 以学生ID为键,JSON字符串为值存入Redis的String结构
forValue.set(student.getId()+"",JSONArray.toJSONString(student));
});
// 返回数据库查询的学生列表
return students;
}
新增学生时同步更新Redis缓存(建议方法二)
方法一:
@Override
public int saveStudent(Student student) {
// 向数据库保存或更新学生信息
boolean b = this.saveOrUpdate(student);
// 创建查询条件构造器
QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
// 添加查询条件:按姓名和学号查询(确保唯一性)
queryWrapper.eq("name", student.getName());
queryWrapper.eq("stu_no",student.getStuNo() );
// 从数据库查询刚保存的学生信息(获取完整字段,如自动生成的ID)
Student one = getOne(queryWrapper);
// 将学生信息同步到Redis缓存
String jsonString = JSONArray.toJSONString(one);
// 向Redis的List尾部添加新学生的JSON数据
forList.rightPush(ALL_STUDENT,jsonString);
// 根据数据库操作结果返回1(成功)或0(失败)
return b?1:0;
}
方法二:
// 重写saveStudent的另一种实现(注释掉的版本),使用ID作为List元素
@Override
public int saveStudent(Student student) {
// 向数据库保存或更新学生信息
boolean b = this.saveOrUpdate(student);
// 创建查询条件构造器
QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
// 添加查询条件:按姓名和学号查询
queryWrapper.eq("name", student.getName());
queryWrapper.eq("stu_no",student.getStuNo() );
// 从数据库查询刚保存的学生信息
Student one = getOne(queryWrapper);
// 向Redis的List尾部添加学生ID
forList.rightPush(ALL_STUDENT,one.getId()+"");
// 以学生ID为键,JSON为值存入Redis的String结构
forValue.set(one.getId() + "",JSONArray.toJSONString(one));
// 返回操作结果标识
return b ? 1 : 0;
}
更新学生时同步更新Redis缓存(建议方法二)
方法一:
public int updateStudent(Student student) {
// 根据ID更新数据库中的学生信息
Boolean b = updateById(student);
// 创建查询条件构造器
QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
// 添加查询条件:按ID查询(获取更新后的完整信息)
queryWrapper.eq("id", student.getId());
Student one = getOne(queryWrapper);
// 从Redis中查询所有学生的JSON列表
List<String> list = forList.range(ALL_STUDENT, 0, -1);
// 判断Redis中是否存在缓存数据
if(list!=null&&!list.isEmpty()){
// 定义索引变量用于记录List中元素的位置
final int[] index = {0};
// 遍历Redis中的学生JSON列表
list.forEach(e->{
// 将JSON字符串转换为Student对象
Student student1 = JSONArray.parseObject(e, Student.class);
// 判断当前元素是否为需要更新的学生(通过ID匹配)
if(student1.getId().equals(student.getId())){
// 在Redis的List中替换对应位置的元素为更新后的JSON
forList.set(ALL_STUDENT, index[0],JSONArray.toJSONString(one));
}
// 索引自增,记录下一个元素位置
index[0]++;
});
}
// 根据数据库操作结果返回1(成功)或0(失败)
return b ? 1 : 0;
}
方法二:
@Override
public int updateStudent(Student student) {
// 根据ID更新数据库中的学生信息
Boolean b = updateById(student);
// 创建查询条件构造器
QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
// 添加查询条件:按ID查询
queryWrapper.eq("id", student.getId());
// 获取更新后的学生信息
Student one = getOne(queryWrapper);
// 如果Redis中存在该学生的缓存,则更新对应的String值
forValue.setIfPresent(one.getId()+"",JSONArray.toJSONString(one));
// 返回操作结果标识
return b?1:0;
}
删除学生时同步删除Redis缓存
@Override
public int removeStudentById(String id) {
// 从数据库中删除指定ID的学生
boolean b = removeById(id);
// 从Redis的List中删除包含该ID的元素(1表示删除一个匹配项)
forList.remove(ALL_STUDENT,1,id+"");
// 从Redis中删除该ID对应的String缓存
stringRedisTemplate.delete(id+"");
// 根据数据库操作结果返回1(成功)或0(失败)
return b?1:0;
}
test的实现
在test包下创建StudentApp类实现功能的测试
// 标注该类为Spring Boot测试类,用于测试Spring Boot应用中的组件
@SpringBootTest
// 引入Slf4j日志注解,方便打印日志
@Slf4j
public class StudentApp {
// 注入StudentService接口的实现类,用于调用学生相关的业务方法
@Resource
StudentService studentService;
// 测试方法:根据ID查询学生信息
@Test
public void a(){
// 调用Service层方法,根据指定ID查询学生
Student studentById = studentService.getStudentById("1967043343284449283");
// 打印查询到的学生信息日志
log.info("studentById:{}", studentById);
}
// 测试方法:查询所有学生(使用缓存策略1)
@Test
public void b1(){
// 调用Service层方法,查询所有学生(对应findAllStudent1实现)
List<Student> allStudent = studentService.findAllStudent1();
// 打印所有学生信息日志
log.info("allStudent:{}", allStudent);
}
// 测试方法:查询所有学生(使用缓存策略2)
@Test
public void b2(){
// 调用Service层方法,查询所有学生(对应findAllStudent2实现)
List<Student> allStudent = studentService.findAllStudent2();
// 注释掉直接打印列表的方式,改为遍历打印每个学生信息(避免日志过长)
// log.info("allStudent:{}", allStudent);
allStudent.forEach(e->{
log.info("e:{}", e);
});
}
// 测试方法:查询所有学生(使用缓存策略3)
@Test
public void b3(){
// 调用Service层方法,查询所有学生(对应findAllStudent3实现)
List<Student> allStudent = studentService.findAllStudent3();
// 遍历打印每个学生信息
allStudent.forEach(e->{
log.info("e:{}", e);
});
}
// 测试方法:新增学生信息
@Test
public void c(){
// 创建学生对象并设置属性
Student student=new Student();
student.setName("aaa");
student.setPlaceOfOrigin("陕西西安");
student.setCourseId(1965250158253547036L);
student.setSchoolId(1965321181514842113L);
student.setBirthday("2003-9-19");
student.setStuNo("RG2025092837822");
student.setGender('男');
// 调用Service层方法保存学生信息,接收操作结果(1成功,0失败)
int i = studentService.saveStudent(student);
// 打印操作结果日志
log.info("i:{}", i);
}
// 测试方法:更新学生信息
@Test
public void d(){
// 创建学生对象,设置需要更新的ID和字段(此处更新生日)
Student student = new Student();
student.setId(1967043343284449283L);
student.setBirthday("2003-9-21");
// 调用Service层方法更新学生信息,接收操作结果
int row = studentService.updateStudent(student);
// 打印操作结果日志
log.info("row:{}", row);
}
// 测试方法:根据ID删除学生信息
@Test
public void e(){
// 调用Service层方法,根据指定ID删除学生
studentService.removeStudentById("1967043343284449283");
}
}
更多推荐
所有评论(0)