美文网首页
spring cache

spring cache

作者: 云之彼端l | 来源:发表于2019-01-05 19:41 被阅读0次
什么是缓存?

缓存可定义为一种存储机制,它将数据保存在某个地方,并以一种更快的方式提供服务。较为常见的一种情况是在应用中使用缓存机制,以避免方法的多次执行,从而克服性能缺陷,也可减少应用服务器或者数据库的压力。

什么情况下使用缓存?

通常会把一些静态数据或者变化频率不高的数据放到缓存中,如配置参数、字典表等。

在Web应用开发中,不同层级对应的缓存要求和缓存策略全然不同。

系统层级    缓存层级                                使用技术     



Web层       |   浏览器缓存、代理服务器缓存、网关缓存   |   HTTP头信息控制、代理服务器
 

应用层      |    单机缓存、分布式缓存                 | JVM或者服务器内存、Ehcache或Redis等
 


数据层      | ORM缓存                                | Hibernate、JPA的一级、二级缓存
spring boot使用redis缓存数据

1、启动类加入@EnableCaching 注解

@SpringBootApplication
@MapperScan(basePackages = "com.lsw.sell.dataobject.mapper")
@EnableCaching //缓存支持  配置Redis缓存需要的
public class SellApplication {

    public static void main(String[] args) {
        SpringApplication.run(SellApplication.class, args);
    }
}

2、在Service业务层或者Controller层方法加入注解

  • 2.1 @Cacheable用法
//    @Cacheable(cacheNames = "product",key = "123")
    //Redis缓存注解  Cacheable第一次访问会访问到方内的内容,方法会返回一个对象,返回对象的时候,会把这个对象存储。下一次访问的时候,不会进去这个方法,直接从redis缓存中拿
    //上面的key的值是可以动态写的@Cacheable(cacheNames = "product",key = "#sellerId")  sellerId为方法中的参数名
    //condition判断是否成立的条件  例如key = "#sellerId",condition = "#sellerId.length() > 3"  只有条件成立才会对结果缓存,结果不成立是不缓存的
    //依据结果来判断是否缓存 unless = "#result.getCode() != 0",#result其实就是ResultVO,也就是返回的对象
    //unless(除什么之外,如果不 的意思) 如果=0就缓存,需要写成!=0。理解起来就是,除了不等于0的情况之外,才缓存,也就是等于0才缓存。
    //其实就是,你想要什么条件下缓存,你反过来写就行了
    //测试缓存的话,你可以在方法内打一个断点进行测试
    //注意,返回的缓存对象一定要实现序列化!!!

    @GetMapping("/list")
//    @Cacheable(cacheNames = "product", key = "#sellerId", condition = "#sellerId.length() > 3", unless = "#result.getCode()!=0")
//    public ResultVO list(@RequestParam("sellerId") String sellerId)
    public ResultVO list() {
        //1. 查询所有的上架商品
        List<ProductInfo> productInfoList = productService.findUpAll();

        //2. 查询类目(一次性查询)
//        List<Integer> categoryTypeList = new ArrayList<>();
        //传统方法
//        for (ProductInfo productInfo : productInfoList) {
//            categoryTypeList.add(productInfo.getCategoryType());
//        }
        //精简方法(java8, lambda)
        List<Integer> categoryTypeList = productInfoList.stream()
                .map(e -> e.getCategoryType())
                .collect(Collectors.toList());
        List<ProductCategory> productCategoryList = categoryService.findByCategoryTypeIn(categoryTypeList);

        //3. 数据拼装
        List<ProductVO> productVOList = new ArrayList<>();
        for (ProductCategory productCategory : productCategoryList) {
            ProductVO productVO = new ProductVO();
            productVO.setCategoryType(productCategory.getCategoryType());
            productVO.setCategoryName(productCategory.getCategoryName());

            List<ProductInfoVO> productInfoVOList = new ArrayList<>();
            for (ProductInfo productInfo : productInfoList) {
                if (productInfo.getCategoryType().equals(productCategory.getCategoryType())) {
                    ProductInfoVO productInfoVO = new ProductInfoVO();
                    BeanUtils.copyProperties(productInfo, productInfoVO);
                    productInfoVOList.add(productInfoVO);
                }
            }
            productVO.setProductInfoVOList(productInfoVOList);
            productVOList.add(productVO);
        }

        return ResultVOUtil.success(productVOList);
    }
  • 2.2 @CacheEvict和@CachePut注解用法
 @PostMapping("/save")
        // @CacheEvict(cacheNames = "product",key = "123")
        // 访问这个方法之后删除对应的缓存,
    // 对应之前的Redis缓存注解的配置 。key如果不填,默认是空,对应的值应该就是方法的参数的值了.
    // 对应BuyerProductController-list的缓存

//    @CachePut(cacheNames = "product",key = "123") //对应之前的Redis缓存注解的配置
    //@CachePut 每次还是会执行方法中的内容,每次执行完成后会把返回的内容放到Redis中去.
    // 这种注解和原来对应的返回对象需要是相同的才行,这里返回的是ModelAndView。可以到service层注解或者dao层注解CachePut
    public ModelAndView save(@Valid ProductForm form,
                             BindingResult bindingResult,
                             Map<String, Object> map) {
        if (bindingResult.hasErrors()) {
            map.put("msg", bindingResult.getFieldError().getDefaultMessage());
            map.put("url", "/sell/seller/product/index");
            return new ModelAndView("common/error", map);
        }

        ProductInfo productInfo = new ProductInfo();
        try {
            //如果productId为空, 说明是新增
            if (!StringUtils.isEmpty(form.getProductId())) {
                productInfo = productService.findOne(form.getProductId());
            } else {
                form.setProductId(KeyUtil.genUniqueKey());
            }
            BeanUtils.copyProperties(form, productInfo);
            productService.save(productInfo);
        } catch (SellException e) {
            map.put("msg", e.getMessage());
            map.put("url", "/sell/seller/product/index");
            return new ModelAndView("common/error", map);
        }

        map.put("url", "/sell/seller/product/list");
        return new ModelAndView("common/success", map);
    }

  • 2.3 @CacheConfig用法
/**
 * @作者 lishw
 * @创建时间 2018/12/3
 * @描述 商品业务逻辑层
 */
@Service
//@CacheConfig(cacheNames = "product")
public class ProductServiceImpl implements ProductService {
    @Autowired
    private ProductInfoRepository repository;

    @Override
//    @Cacheable(key = "123")
    public ProductInfo findOne(String productId) {
        return repository.findOne(productId);
    }

    @Override
    public List<ProductInfo> findUpAll() {
        return repository.findByProductStatus(ProductStatusEnum.UP.getCode());
    }

    @Override
    public Page<ProductInfo> findAll(Pageable pageable) {
        return repository.findAll(pageable);
    }

    @Override
//    @CachePut(key = "123")
    public ProductInfo save(ProductInfo productInfo) {
        return repository.save(productInfo);
    }

相关文章

网友评论

      本文标题:spring cache

      本文链接:https://www.haomeiwen.com/subject/nwydrqtx.html