使用mybatis 和数据缓存Spring Cache简单示例
- application.yaml
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost/springbootdata?serverTimezone
username: root
password: 123456
#配置控制台打印sql
logging:
level:
com.example.demo_cache.mapper: debug
- @EnableCaching 开启缓存
@SpringBootApplication
@EnableCaching //开启缓存
public class DemoCacheApplication {
public static void main(String[] args) {
SpringApplication.run(DemoCacheApplication.class, args);
}
}
Mapper层
@Mapper
public interface UserMapper {
@Select("SELECT * FROM `user`")
public List<User> getAll();
@Select("select * from `user` where id=#{id}")
public User getById(Integer id);
@Select("SELECT * FROM `user` where name=#{name}")
public User getByName(String name);
@Update("UPDATE user SET name=#{name},pwd=#{pwd} WHERE id=#{id}")
public int updateUser(User user);
@Delete("DELETE FROM user WHERE id=#{id}")
public int deleteUserById(Integer id);
@Insert("INSERT INTO `user` VALUES(#{id},#{name},#{pwd})")
public int insertUser(User user);
}
- @Cacheable 可以作用在方法和类上,以键值对的方式缓存类或方法的返回值
- @CachePut 方法被调用,然后结果被保存 每次都会触发真实方法调用
- @CacheEvit 清空缓存
- @Cacheing 组合多个注解缓存
Service层
package com.example.demo_cache.service;
import com.example.demo_cache.bean.User;
import com.example.demo_cache.mapper.UserMapper;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.*;
import org.springframework.stereotype.Service;
import java.util.List;
@CacheConfig(cacheNames = "user") //抽取缓存的公共配置 若添加cacheNames 则缓存注解中的value可以不写
@Service
public class UserService {
@Autowired
UserMapper userMapper;
public List<User> getAll() {
return userMapper.getAll();
}
/**
* 将方法的运行结果进行缓存 以后再要相同的数据,直接从缓存中获取,不调用方法
* CacheManager管理多个缓存组件 对缓存的真正CRUD操作在Cache组件中,每一个缓存组件有自己唯一一个名字
* 几个属性:
* cacheNames/value: 指定缓存组件名字
* key: 缓存数据使用的key 默认是使用方法参数值 使用SpEL表达式
* condition 指定符合条件才缓存 condition = "#id>0"
* unless: 否定缓存 党unless指定条件为true 方法的返回值就不会被缓存 可以获取到结果进行判断
* unless = "#result==null"
* sync: 是否使用异步模式
* @param id
* @return
*/
@Cacheable(value = {"user"}, condition = "#id>0", unless = "#result==null")
public User getUserById(Integer id) {
return userMapper.getById(id);
}
/**
* @return
* @CachePut: 既调用方法又更新缓存 同步更新缓存
* 修改了数据库中的某个数据,同时更新缓存 先调用目标方法再将目标方法结构缓存起来
* 修改后通过getUserById查询还是原来的信息 应该是更新后的数据
* 更新后的key和查询的key应该保持一致 这样才能更新数据库后更新缓存的数据
* key: = "#user.id" 使用传入参数的user.id
* key: = "#result.id" 使用返回后的id
* @Cacheable的key是不能使用#result
*/
@CachePut(value = "user", key = "#result.id")
public User updateUser(User user) {
userMapper.updateUser(user);
return user;
}
/**
* key: 指定要删除的数据
* allEntries = true 指定清除这个缓存中的所有事数据
* beforeInvocation = false 缓存的清除是否在方法执行之前清除 若为true 无论方法出现异常都会清除缓存
*
* @param id
* @return
*/
@CacheEvict(value = "user", key = "#id")
public boolean deleteUserById(Integer id) {
return userMapper.deleteUserById(id) > 0;
}
@CachePut(value = "user", key = "#result.id")
public User insertUser(User user) {
userMapper.insertUser(user);
return user;
}
/**
* 组合注解
* 第一次用name查 查询数据库 添加key为name的缓存
* 第二次用id查 没有查询数据库 查询缓存 key="#result.id"
* 第三次用name查 查询数据库 因为@Cacheput每次查询都要查询数据库
* 可以理解为一个值对应为多个key
* @param name
* @return
*/
@Caching(
cacheable = {@Cacheable(value = "user", key = "#name")},
put = {@CachePut(value = "user", key = "#result.id"), @CachePut(value = "user", key = "#result.pwd")}
)
public User getByName(String name) {
return userMapper.getByName(name);
}
}
Controller层
package com.example.demo_cache.controller;
import com.example.demo_cache.bean.User;
import com.example.demo_cache.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
@Autowired
UserService userService;
@GetMapping("/users")
public List<User> getUsers(){
return userService.getAll();
}
@GetMapping("/user/{id}")
public User getUserById(@PathVariable("id") Integer id){
return userService.getUserById(id);
}
@GetMapping("/user/name/{name}")
public User getUserByName(@PathVariable("name") String name){
return userService.getByName(name);
}
@GetMapping("/user")
public User updateUser(User user){
return userService.updateUser(user);
}
@GetMapping("/del")
public String deleteUser(Integer id){
return userService.deleteUserById(id)? "Success":"Failure";
}
@GetMapping("/insert")
public User insertUser(User user){
return userService.insertUser(user);
}
}