项目引入缓存Cache

项目引入缓存Cache

随着项目代码的书写变多,回过来发现,代码只局限于完成功能,或者在完成功能的基础上进行优化,但是对于性能问题考虑的不是很深入,在平时中也接触不到高并发等一系列需要书写高质量、符合实际生产环境的代码,

现做尝试1:

把数据库表中的字典数据引入到缓存中,二次操作时不需要再操作数据库,直接从缓存中读取;

spingcache的简介

缓存就是将数据从数据库等数据来源获取数据,将数据缓存在内存或其它设备入redis中,为了二次查询能够快速高效的响应结果;

特点

提供cache通用入口,方便多种实现切换缓存源,入redis,guava cache等

支持事务,即事务回滚时,缓存同时自动回滚

准备一个springboot环境

添加依赖包

    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-cache</artifactId>
    </dependency>

新建实体类

public class LowCarbonEquTypeTbl {

    public String equType;
    public String equValue;
    public String equTrans;

    public LowCarbonEquTypeTbl(String s, String s1, String s2) {
        this.equType=s;
        this.equValue=s1;
        this.equTrans=s2;
    }

    @Override
    public String toString() {
        return "LowCarbonEquTypeTbl{" +
                "equType='" + equType + '\'' +
                ", equValue='" + equValue + '\'' +
                ", equTrans='" + equTrans + '\'' +
                '}';
    }

    public String getEquType() {
        return equType;
    }

    public void setEquType(String equType) {
        this.equType = equType;
    }

    public String getEquValue() {
        return equValue;
    }

    public void setEquValue(String equValue) {
        this.equValue = equValue;
    }

    public String getEquTrans() {
        return equTrans;
    }

    public void setEquTrans(String equTrans) {
        this.equTrans = equTrans;
    }
}

增加数据表

用于测试

 

 

 

新建Service接口

public interface TypeService {
    public List<TypeTbl> select();

    public TypeTbl update(TypeTbl tbl);

    public TypeTbl save(TypeTbl tbl);
}

新建实现impl

@Service
public class TypeImpl implements TypeService{
    private Logger logger = Logger.getLogger("TypeImpl");

    @Resource
    private TypeMapper equTypeMapper;

    // 先从缓存中读取,如果没有再调用方法获取数据,然后把数据添加到缓存中

    @Override
    @Cacheable(value = "tbl")
    public List<TypeTbl> select() {
        logger.info("=====select查询数据库啦=====");
        List<TypeTbl> tbls = equTypeMapper.selectList(null);
        return tbls;
    }

    // 移除对应的缓存

    @Override
    @CacheEvict(value = "tbl", key = "#tbl",allEntries = true)
    public TypeTbl update(TypeTbl tbl) {
        logger.info("=====update查询数据库啦=====");
        QueryWrapper wrapper = new QueryWrapper();
        wrapper.eq("equ_type",tbl.getEquType());
        wrapper.eq("equ_value",tbl.getEquValue());
        wrapper.eq("equ_trans",tbl.getEquTrans());
        int rows = equTypeMapper.delete(wrapper);
        return tbl;
    }

    // 查询数据库,将查询结果放到缓存

    @Override
    @CachePut(value = "tbl", key = "#tbl", unless = "#tbl == null ")
    public TypeTbl save(TypeTbl tbl) {
        logger.info("=====save查询数据库啦=====");
        equTypeMapper.insert(tbl);
        return tbl;
    }

}

新建测试类

@RunWith(SpringRunner.class)
 //指定启动类
@SpringBootTest(classes = LogFrameworkApplication.class)
@Slf4j
public class DemoApplicationTests {
//    private Logger logger = Logger.getLogger("DemoApplicationTests");

    @Resource
    private TypeService service;


    @Test
    public void testCache() {

        //增加数据的值并且缓存当前数据库的值
        TypeTbl user = service.save(new TypeTbl("1", "1","1"));
        log.info("[ save方法  - {} ]",user);
        //查询数据库中的值
        List<TypeTbl> user1 = service.select();
        log.info("[ select 方法  - {} ]",user1);
        //删除数据库的值,但是没有删除缓存的值--数据不同步问题,需要解决
        service.update(user);
        List<TypeTbl> user2 = service.select();
        //获取到的是缓存的值不是数据库的值
        log.info("[ select 方法  - {} ]",user2);
        List<TypeTbl> user3 = service.select();
        //获取到的事缓存的值不是数据库的值
        log.info("[ select 方法  - {} ]",user3);
    }
}

运行结果

 =====save查询数据库啦=====
 HikariPool-1 - Start completed.
 [ save方法  - TypeTbl{equType='1', equValue='1', equTrans='1'} ]
 =====select查询数据库啦=====
 [ select 方法  - [TypeTbl{equType='dt', equValue='01', equTrans='demo'}, TypeTbl{equType='1', equValue='1', equTrans='1'}] ]
 =====update查询数据库啦=====
 =====select查询数据库啦=====
 [ select 方法  - [TypeTbl{equType='dt', equValue='01', equTrans='demo'}] ]
 [ select 方法  - [TypeTbl{equType='dt', equValue='01', equTrans='demo'}] ]
 HikariPool-1 - Shutdown initiated...
 HikariPool-1 - Shutdown completed.

测试缓存遇到的问题

注解中key的取值、allEntries = true清除缓存的值

出发点是利用缓存 减轻数据库的压力

但是有一个数据一致性的问题,人为操作数据库,造成数据变动 ,此时缓存中的值会和本身数据库中的值不一致,怎么办?

当前情况下,缓存中数据用来存储定值不易改变的,密集的操作完成后即删去缓存中的值 等待下次操作重新填充数据库的值,

改变了存储的定值,需要重启项目系统,自动释放再次同步获取数据

这是不引用外部组件的情况下,减小了项目重量。在一个接口中完成新建缓存,消除缓存的操作。

 

posted @ 2022-11-18 15:29  subtlman  阅读(74)  评论(0)    收藏  举报