springboot + mybatis 使用 ehcache 缓存
我原本是学C/C++ 的,由于公司的需要,不得不转向java,发现 java 所要学的东西太多了,可是一嘴吃不成一个胖子,什么事情都是需要一步一步来,因此折腾了一下缓存,对缓存的配置文件似懂非懂,但是成功使用了缓存
在我折腾的过程中,真的好想有一个帖子能够指导我成功使用,但由于一些问题,让我对缓存某一些细节理解偏差,因此写这个
博客暴露一下当初理解有偏差的细节,也希望得到更多大神的指点,在此先多谢各位大神指出的错误。
IDE:IDEA
框架:springboot + mybatis
一:引入缓存的依赖包,在配置 pom.xml 文件中添加
<!--添加缓存--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency> <dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache</artifactId> </dependency>Maven项目时可以自动拉去依赖包的
二 : 添加缓存的配置文件 ehcache.xml
<?xml version="1.0" encoding="UTF-8"?> <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"> <diskStore path="java.io.tmpdir" /> <defaultCache eternal="false" maxElementsInMemory="1000" overflowToDisk="false" diskPersistent="false" timeToIdleSeconds="0" timeToLiveSeconds="600" memoryStoreEvictionPolicy="LRU" /> <cache name="userCache" maxElementsInMemory="1000" eternal="false" timeToIdleSeconds="300" timeToLiveSeconds="300" overflowToDisk="false" memoryStoreEvictionPolicy="LRU"> <!-- 配置缓存事件监听器 replicateAsynchronously 操作是否异步,默认值为true. replicatePuts 添加操作是否同步到集群内的其他缓存,默认为true. replicateUpdates 更新操作是否同步到集群内的其他缓存,默认为true. replicateUpdatesViaCopy 更新之后的对象是否复制到集群中的其他缓存(true); replicateRemovals 删除操作是否同步到集群内的其他缓存,默认为true. --> <cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" properties=" replicateAsynchronously=true, replicatePuts=true, replicateUpdates=true, replicateUpdatesViaCopy=true, replicateRemovals=true " /> <!-- 初始化缓存,以及自动设置 --> <bootstrapCacheLoaderFactory class="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory" properties="bootstrapAsynchronously=true" /> </cache> </ehcache>各个配置的意思百度一搜一大堆,在此就不多解释了。
三 : 设置项目启动时使用缓存
@SpringBootApplication // 配置扫描mapper 的位置 //@MapperScan("com.example.demo.mapper") // 启动缓存 @EnableCaching public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } }四:业务代码
4.1 我的代码结构
4.2 controller
@RestController @RequestMapping("user") public class UserController { private static final Logger logger = LoggerFactory.getLogger(UserController.class); @Autowired private IUserService userService; @GetMapping("getUser") public UserEntity getUser(){ logger.info("获取用户数据"); UserEntity user = new UserEntity(); return userService.getUser(1); } }4.3 service
@CacheConfig(cacheNames = "users") public interface IUserService { public UserEntity getUser(int id); }
4.4 serviceImpl
@Service @Transactional public class IUserServiceImpl implements IUserService { private static final Logger logger = LoggerFactory.getLogger(IUserServiceImpl.class); @Autowired private UserMapper userMapper; @Override @Cacheable(key="#id",value="userCache") public UserEntity getUser(int id){ // List<UserEntity> userList = new ArrayList<>(); logger.info("获取数据 : service"); UserEntity entity = userMapper.getUser(); logger.info("数据获取成功 : service"); return entity; } }注意:刚开始接触的时候就会拿缓存和 map 做对比,认为 value 就是查询到的值(也就是往缓存中放的值),如果你这么认为
那就打错特错了,value 是制定使用缓存的名称,并不是查询到的值。
4.5 mapper
@Mapper public interface UserMapper { //获取用户信息 @Select("select * from user where ID = 1") UserEntity getUser(); }4.6 运行结果
当第一次运行的时候,对数据库进行查询,第二次的时候,就直接在缓存中取值了。
个人在写东西的时候不在意排版的细节性问题,各位读友多多包涵。