关于springboot中redis注解我想说

关于redis注解这个问题,实在是折磨了我好久,网上一大堆的资料但是,却没有一个来讲讲到底注解该怎么去存,写完注解数据会存储什么类型,以什么样的方式写注解才可以存入redis缓存
redis的注解问题查询了很多资料,都没找到适合我的,直到后来,我开始从基础开始了解了redis的数据类型后,才对注解有了自己的理解。

下面讲一下,在实际项目中用注解怎么实现信息的增删查改。

(首先声明一下:
	我所谓的增删查改是对service进行的操作,
	是对mysql数的增删查改,
	并不是对redis数据库的增删查改)

首先说一下mysql数据的列表显示,
使用redis的目的:是将数据从mysql中取出,然后存入redis,当下次取数据时,先用过注解,去查寻redis数据库是否存在数据,如果存在你所需要的数据,那么,redis会直接取出数据,将不再去进行mysql数据库的查询。那也许有人会问了,为什么要用redis存数据呢,这样不是更麻烦吗?那是因为现在自己做的项目还小,感觉不出查询速度的差距,当数据量增大时,就能体现出mysql查询速度慢来了,redis就是用来解决这样的问题,一般说来,会被当作缓存使用。 因为它比数据库(mysql)快,所以常用的数据,可以考虑放在这里,这样就提高了性能。

好了回归正题:那么注解怎么使用呢?

Redis的缓存,我们都会在 Service 这一层上面做。 首先
我用BlogService来讲解

  1. 给分类加上如下注解,就表示分类在缓存里的keys,都是归 “blogs” 这个管理的。 通过工具Redis 图形界面客户端 可以看到有一个 blogs~keys, 就是它,用于维护分类信息在 redis里都有哪些 key.
 @CacheConfig(cacheNames="blogs")

  1. 通过id获得博客,获取一个上面的注解是"@Cacheable(key="‘blog’+ #p0")", 第一次访问的时候, redis 是不会有数据的,所以就会通过 jpa 到数据库里去取出来, 一旦取出来之后,就会放在 redis里。 key 呢就是blog84 这个 key。 第二次访问的时候,redis 就有数据了,就不会从数据库里获取了。
 @Cacheable(key="'blog'+ #p0")
    public Blog getBlog(Long id) {
        return blogRepository.findOne(id);
    }
  1. 分页查询,这个和获取一个,其实没什么区别,就是key不一样,数据不再是一个对象,而是一个集合。 (保存在 redis 里是一个 json 数组)
    ,p0代表的时传参的第一个参数,#p0.offset代表的是pageable参数的开始id,#p0.pageSize代表的是pageable分页大小,如图所示blogs-page-0-5 就是第一页数据
@Cacheable(key="'blogs-page-'+#p0.offset+ '-' + #p0.pageSize")
    public Page4Navigator<Blog> listBlog(Pageable pageable) {
        Page<Blog> pageFromJPA=  blogRepository.findAll(pageable);
        Page4Navigator<Blog> page = new Page4Navigator<>(pageFromJPA,5);
        return page;
    }
  1. 增加,删除和修改这几个要好好讲一讲。 注意看,增加,删除和修改用的注解都是:@CacheEvict(allEntries=true),其意义是删除 blogs~keys 里的所有的keys. 可是呢,下面有各种有一行注释掉的注解。 比如增加,注释掉的注解是:// @CachePut(key="‘blog-one-’+ #p0")
    它的作用是以 blog-one-id 的方式增加到 Redis中去。 这样做本身其实是没有问题的,而且在 get 的时候,还可以使用,但是最后还是放弃这种做法了,为什么呢?
    因为,虽然这种方式可以在 redis 中增加一条数据,但是: 它并不能更新分页缓存 blogs-page-0-8 里的数据, 这样就会出现数据不一致的问题了。 即。在redis 中,有这一条单独数据的缓存,但是在分页数据里,却没有这一条,这样就矛盾了。
    为了解决这个矛盾,最精细的做法是,同时更新分页缓存里的数据。 因为 redis 不是结构化的数据,它是 “nosql", 为了做到 同时更新缓存分页缓存里的数据,会超级的复杂,而且超级容易出错,其开发量也会非常大。
    那么怎么办呢? 最后,我们采纳了折中的办法,即,一旦增加了某个分类数据,那么就把缓存里所有分类相关的数据,都清除掉。 下一次再访问的时候,一看,缓存里没数据,那么就会从数据库中读出来,读出来之后,再放在缓存里。如此这般,牺牲了一点小小的性能,数据的一致性就得到了保障了。
    修改和删除,都是同一个道理。
 @Transactional
    @Override
    @CacheEvict(allEntries=true)
    public Blog saveBlog(Blog blog) {
        if (blog.getId() == null) {
            blog.setId((long) 0);
            blog.setCreateTime(new Date());
            blog.setUpdateTime(new Date());
            blog.setViews(0);
        } else {
            blog.setUpdateTime(new Date());
        }
        return blogRepository.save(blog);
    }
 @Transactional
    @Override
    @CacheEvict(allEntries=true)
    public void deleteBlog(Long id) {
        blogRepository.delete(id);
    }
    @Transactional
    @Override
    @CacheEvict(allEntries=true)
    public Blog updateBlog(Long id, Blog blog) {
        Blog b = blogRepository.findOne(id);
        if (b == null) {
            throw new NotFoundException("该博客不存在");
        }
        BeanUtils.copyProperties(blog,b, MyBeanUtils.getNullPropertyNames(blog));
        b.setUpdateTime(new Date());
        return blogRepository.save(b);
    }

所有源码:

@Service
@CacheConfig(cacheNames="blogs")
public class BlogServiceImpl implements BlogService {
    @Autowired
    private BlogRepository blogRepository;

    /** * 通过id获得博客 * 获取一个上面的注解是 * "@Cacheable(key="'blog'+ #p0")" * 第一次访问的时候, redis 是不会有数据的,所以就会通过 jpa 到数据库里去取出来, * 一旦取出来之后,就会放在 redis里。 key 呢就是blogs84 这个 key。 * 第二次访问的时候,redis 就有数据了,就不会从数据库里获取了。 * @param id * @return */
    @Override
    @Cacheable(key="'blog'+ #p0")
    public Blog getBlog(Long id) {
        return blogRepository.findOne(id);
    }

    /** * * @param id * @return */
    @Transactional
    @Override
    public Blog getAndConvert(Long id) {
        Blog blog = blogRepository.findOne(id);
        if (blog == null) {
            throw new NotFoundException("该博客不存在");
        }
        Blog b = new Blog();
        BeanUtils.copyProperties(blog,b);
        String content = b.getContent();
        b.setContent(MarkdownUtils.markdownToHtmlExtensions(content));

        blogRepository.updateViews(id);
        return b;
    }

    /** * 通过博客队列分页查询博客列表 * @param pageable * @param blog * @return */
    @Override
    @Cacheable(key="'blogs-BlogQuery-'+#p0+ '-page-' + #p1.offset+ '-' + #p1.pageSize")
    public Page4Navigator<Blog> listBlog(BlogQuery blog,Pageable pageable) {
        Page<Blog> pageFromJPA=  blogRepository.findAll(new Specification<Blog>(){
            @Override
            public Predicate toPredicate(Root<Blog> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {
                List<Predicate> predicates = new ArrayList<>();
                if (!"".equals(blog.getTitle()) && blog.getTitle() != null) {
                    predicates.add(cb.like(root.<String>get("title"), "%"+blog.getTitle()+"%"));
                }
                if (blog.getTypeId() != null) {
                    predicates.add(cb.equal(root.<Type>get("type").get("id"), blog.getTypeId()));
                }
                if (blog.isRecommend()) {
                    predicates.add(cb.equal(root.<Boolean>get("recommend"), blog.isRecommend()));
                }
                cq.where(predicates.toArray(new Predicate[predicates.size()]));
                return null;
            }
        },pageable);;
        Page4Navigator<Blog> page = new Page4Navigator<>(pageFromJPA,5);
        return page;
    }

    /** * 分页查询博客 * @param pageable * @return */
    @Override
    @Cacheable(key="'blogs-page-'+#p0.offset+ '-' + #p0.pageSize")
    public Page4Navigator<Blog> listBlog(Pageable pageable) {
        Page<Blog> pageFromJPA=  blogRepository.findAll(pageable);
        Page4Navigator<Blog> page = new Page4Navigator<>(pageFromJPA,5);
        return page;
    }

    /** * 通过标签分页查询博客 * @param tagId * @param pageable * @return */
    @Override
    @Cacheable(key="'blogs-tagId-'+#p0+'-page-'+#p1.offset + '-' + #p1.pageSize ")
    public Page4Navigator<Blog> listBlog(Long tagId,Pageable pageable) {
        Page<Blog> pageFromJPA=  blogRepository.findAll(new Specification<Blog>() {
            @Override
            public Predicate toPredicate(Root<Blog> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {
                Join join = root.join("tags");
                return cb.equal(join.get("id"),tagId);
            }
        },pageable);
        Page4Navigator<Blog> page = new Page4Navigator<>(pageFromJPA,5);
        return page;
    }

    @Override
    @Cacheable(key="'blogs-query-'+#p0+ '-page-' + #p1.offset+ '-' + #p1.pageSize")
    public Page4Navigator<Blog> listBlog(String query,Pageable pageable) {
        Page<Blog> pageFromJPA=  blogRepository.findByQuery(query,pageable);
        Page4Navigator<Blog> page = new Page4Navigator<>(pageFromJPA,5);
        return page;
    }

    @Override
    @Cacheable(key="'blogs-top-'+#p0")
    public List<Blog> listRecommendBlogTop(Integer size) {
        Sort sort = new Sort(Sort.Direction.DESC,"updateTime");
        Pageable pageable = new PageRequest(0, size, sort);
        return blogRepository.findTop(pageable);
    }

    @Override
    public Map<String, List<Blog>> archiveBlog() {
        List<String> years = blogRepository.findGroupYear();
        Map<String, List<Blog>> map = new HashMap<>();
        for (String year : years) {
            map.put(year, blogRepository.findByYear(year));
        }
        return map;
    }

    @Override
    @Cacheable(key="'blogs-count'")
    public Long countBlog() {
        return blogRepository.count();
    }


    @Transactional
    @Override
    @CacheEvict(allEntries=true)
    public Blog saveBlog(Blog blog) {
        if (blog.getId() == null) {
            blog.setId((long) 0);
            blog.setCreateTime(new Date());
            blog.setUpdateTime(new Date());
            blog.setViews(0);
        } else {
            blog.setUpdateTime(new Date());
        }
        return blogRepository.save(blog);
    }

    @Transactional
    @Override
    @CacheEvict(allEntries=true)
    public Blog updateBlog(Long id, Blog blog) {
        Blog b = blogRepository.findOne(id);
        if (b == null) {
            throw new NotFoundException("该博客不存在");
        }
        BeanUtils.copyProperties(blog,b, MyBeanUtils.getNullPropertyNames(blog));
        b.setUpdateTime(new Date());
        return blogRepository.save(b);
    }

    @Transactional
    @Override
    @CacheEvict(allEntries=true)
    public void deleteBlog(Long id) {
        blogRepository.delete(id);
    }
}

全部评论

相关推荐

11-11 14:21
西京学院 C++
Java抽象练习生:教育背景放最前面,不要耍小聪明
点赞 评论 收藏
分享
牛客868257804号:九个中铁八个中建
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务