十次方day02(查询和缓存)

一.条件查询

需求:完成标签的条件查询和条件查询+分页

返回的数据类型

controller层我们进行组装查询条件

//条件查询
    @PostMapping("/search")
    public Result findSearch(@RequestBody Map map){
        List<Label> page =  labelService.findSearch(map);
        return  new Result(true,StaticCode.OK,"查询成功",page);
    }
    //条件查询+分页查询
    @PostMapping("search/{page}/{size}")
    public Result findSearchByPageAndSize(@PathVariable int page,@PathVariable int size,@RequestBody(required = false) Map map){
        //首先进行条件的封装
        Pageable pageable = PageRequest.of(page-1,size);
        Page<Label> pageData = labelService.findSearchByPageAndSize(pageable,map);

        PageResult<Label> pageResult = new PageResult<>(pageData.getTotalElements(), pageData.getContent());
        return  new Result(true,StaticCode.OK,"查询成功",pageResult);
    }

注意:在条件查询+分页查询中我们自己定义的pageRequest

service层开发

注意:dao接口中一定要进行继承

JpaSpecificationExecutor

用来动态的拼接我们的参数

 /**
     * 条件查询
     * @param map
     * @return
     */
    @Override
    public List<Label> findSearch(Map map) {
        //构建条件
        return labelDao.findAll(getSpecification(map));
    }

    /**
     * 条件查询+分页查询
     * @param pageable
     * @param map
     * @return
     */
    @Override
    public Page<Label> findSearchByPageAndSize(Pageable pageable, Map map) {
        return labelDao.findAll(getSpecification(map),pageable);
    }
    //构建查询条件
    public Specification<Label> getSpecification(Map map){
        return new Specification<Label>() {
            //动态的拼接参数进行组装参数
            /**
             *
             * @param root
             * @param criteriaQuery
             * @param criteriaBuilder
             * @return
             */
            @Override
            public Predicate toPredicate(Root<Label> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                //首先进行创建一个集合
                List<Predicate> list = new ArrayList<>();
                //判断map是否为空
                if (map==null){
                    return null;
                }
                    //构建第一个条件
                    //判断map中的labelname是否为空
                    if (!StringUtils.isEmpty(map.get("labelname"))){
                    Predicate p1 = criteriaBuilder.like(root.get("labelname").as(String.class), "%" + (String) map.get("labelname") + "%");
                    //添加到集合中
                        list.add(p1);
                    }
                    //构建第二个条件
                    //判断map中的state是否为空
                    if (!StringUtils.isEmpty(map.get("state"))){
                        Predicate p2 = criteriaBuilder.equal(root.get("state").as(String.class),  (String) map.get("state") );
                        //添加到集合中
                        list.add(p2);
                    }
                    //构建第二个条件
                    //判断map中的recommend是否为空
                    if (!StringUtils.isEmpty(map.get("recommend"))){
                        Predicate p3 = criteriaBuilder.equal(root.get("recommend").as(String.class),  (String) map.get("recommend") );
                        //添加到集合中
                        list.add(p3);
                    }
                    //判断list集合
                    if (list.size()<=0){
                        return null;
                    }
                    //通过and或者or拼接条件
                    Predicate[] restrictions = new Predicate[list.size()];
                //将集合转化数组
               // Predicate[] predicates = list.toArray(restrictions);
                return criteriaBuilder.and(list.toArray(new Predicate[list.size()]));
            }
        };
    }

测试:

分页查询

二.招聘微服务开发

需求:查询热门企业列表  推荐职位列表   最新职位列表

基础的CRUD代码我们通过代码生成器进行生成

我们通过方法命名法进行编写

1.热门企业

controller层

//热门企业查询
	@GetMapping("/search/hotlist")
	public Result findHotList(){
		return new Result(true,StatusCode.OK,"查询成功",enterpriseService.findHotList());
	}
	

service层

public List<Enterprise> findHotList() {
	 return enterpriseDao.findByIshot("1");
    }

dao层

public interface EnterpriseDao extends JpaRepository<Enterprise,String>,JpaSpecificationExecutor<Enterprise>{

    //方法命名法,通过ishost是一的查询出来
    public List<Enterprise> findByIshot(String ishot);
}

2.推荐职位和最新职位

controller层

//推荐职位
	@GetMapping("/search/recommend")
	public Result recommend(){
		return new Result(true,StatusCode.OK,"查询成功",recruitService.findCommend());
	}
	//最新职位
	@GetMapping("/search/newlist")
	public Result newList(){
		return new Result(true,StatusCode.OK,"查询成功",recruitService.findNewList());
	}
	

service层:

public List<Recruit> findCommend() {
		return recruitDao.findTop4ByStateOrderByCreatetimeDesc("2");
	}

	public List<Recruit> findNewList() {
		return recruitDao.findTop12ByStateNotOrderByCreatetimeDesc("0");
	}

dao层

public interface RecruitDao extends JpaRepository<Recruit,String>,JpaSpecificationExecutor<Recruit>{

    //推荐职位
    public List<Recruit> findTop4ByStateOrderByCreatetimeDesc(String state);
    //最新的职位
    public List<Recruit> findTop12ByStateNotOrderByCreatetimeDesc(String state);
}

测试:

三.问答微服务开发

需求分析:

通过点击每个标题,下面的列表展示三个页签,最新回答,热门回答,等待回答

注意:我们通过原生的sql可以查询,也可以通过JPQL进行查询    还要添加一个中间表, Pl表   一个标签可以有多个问题一个问题也可以有多个标签,

原生的采用这样方式:

 @Query(nativeQuery = true, value = "select * from tb_problem p where p.id in(select problemid from tb_pl p1 WHERE p1.labelid = ?1)")

JPQl方式查询

controller层

	/**
	 * 热门问答列表
	 */
	@GetMapping("/hotlist/{labelid}/{page}/{size}")
	public Result findHotList(@PathVariable String labelid,@PathVariable int page,@PathVariable int size){
		Pageable pageable = PageRequest.of(page-1,size);
		Page<Problem> pageData =  problemService.findHostList(labelid,pageable);
	return new Result(true,StatusCode.OK,"查询成功",new PageResult<Problem>(pageData.getTotalElements(), pageData.getContent()));
	}
	/**
	 * 最新问答
	 */
	@GetMapping("/newlist/{labelid}/{page}/{size}")
	public Result findNewList(@PathVariable String labelid,@PathVariable int page,@PathVariable int size){
		Pageable pageable = PageRequest.of(page-1,size);
		Page<Problem> pageData =  problemService.findNewList(labelid,pageable);
		return new Result(true,StatusCode.OK,"查询成功",new PageResult<Problem>(pageData.getTotalElements(), pageData.getContent()));
	}
	/**
	 * 等待回答列表
	 */
	@GetMapping("/waitlist/{labelid}/{page}/{size}")
	public Result findWaitList(@PathVariable String labelid,@PathVariable int page,@PathVariable int size){
		Pageable pageable = PageRequest.of(page-1,size);
		Page<Problem> pageData =  problemService.findWaitList(labelid,pageable);
		return new Result(true,StatusCode.OK,"查询成功",new PageResult<Problem>(pageData.getTotalElements(), pageData.getContent()));
	}
	

dao层

public interface ProblemDao extends JpaRepository<Problem,String>,JpaSpecificationExecutor<Problem>{
    /**
     * 根据标签id查询最新问题列表
     */
    @Query("select p from Problem p where p.id in(select problemid from Pl where labelid = ?1) order by p.createtime desc ")
    Page<Problem> newList(String labelId, Pageable pageable);

    /**
     * 根据标签id查询热门问题
     * @param labelId
     * @param pageable
     * @return
     */
    @Query("select p from Problem p where p.id in(select problemid from Pl where labelid = ?1) order by p.reply desc")
    Page<Problem> hotList(String labelId, Pageable pageable);

    /**
     * 根据标签id查询等待回答列表
     * @param labelId
     * @param pageable
     * @return
     */
    @Query("select p from Problem p where p.id in(select problemid from Pl where labelid = ?1) and p.reply = 0 order by p.createtime desc ")
    Page<Problem> waitList(String labelId, Pageable pageable);
}

 

四.文章微服务开发

需求分析: 文章审核 通过修改state的状态为1

点赞数 : 每次点赞,让数据库中thumbmp加一

Controller 层:

/**
     * 文章的审核
     * @param articleId
     * @return
     */
    @PutMapping("/examine/{articleId}")
    public Result examine(@PathVariable String articleId){
        articleService.examine(articleId);
        return new Result(true,StatusCode.OK,"审核成功");
    }
    /**
     * 文章的点赞
     */
    @PutMapping("/thumbup/{articleId}")
    public Result thumbup(@PathVariable String articleId){
        articleService.thumbup(articleId);
        return new Result(true,StatusCode.OK,"点赞成功");
    }

service层:

/**
     * 审核
     * @param articleId
     */
    @Transactional
    public void examine(String articleId) {
        articleDao.examine(articleId);
    }
​
    /**
     * 点赞数的实现
     * @param articleId
     */
    @Transactional
    public void thumbup(String articleId) {
        articleDao.updateThumbup(articleId);
    }

dao层:

public interface ArticleDao extends JpaRepository<Article,String>,JpaSpecificationExecutor<Article>{
    /**
     * 文章的审核
     * 第一种方法:先查询,然后修改
     * 第二中通过注解@modify  注意必须添加事物处理
     * 第三种我们通过jpa的快照机制
     */
    @Modifying
    @Query("update Article a set a.state = '1' where a.id = ?1")
    public void examine(String id);
    /**
     * 文章点赞功能的实现
     */
    @Modifying
    @Query("update Article  set thumbup=thumbup+1 where id =?1")
    public void updateThumbup(String id);
}

测试:可以成功的修改

注意:我们在通过第三个方法,利用jpa的一级缓存机制的时候先查询,然后进行设置stae的值为1 ,还有一定要添加事物控制,在service层

这样就可以了,事物会在提交的时候自动判断是否修改

2.缓存处理

通过reids缓存可以提高我们的查询效率,减少服务器的压力

docker上搭建redis服务

导入spring data redis的包

配置redis的host地址为我们的linux的地址

我们在文章的的service中,在通过id获得的时候添加判断,加入到缓存中

修改和删除时候,同时清除redis中的缓存

/**
	 * 根据ID查询实体
	 * @param id
	 * @return
	 */
	public Article findById(String id) {
		//1.首先从缓存中获得
		Article article = (Article) redisTemplate.opsForValue().get("article_"+id);
		//2.判断是否为空,如果为空,我们从数据库中查询
		if (article==null){
			article = articleDao.findById(id).get();
		//3.将数据库中查询的在放到缓存中
			redisTemplate.opsForValue().set("article_"+id,article);
		}
		//4.最后返回article
		return article;
	}
/**
	 * 修改
	 * @param article
	 */
	public void update(Article article) {
		//修改后清除缓存
		redisTemplate.delete("article_"+article.getId());
		articleDao.save(article);
	}

	/**
	 * 删除
	 * @param id
	 */
	public void deleteById(String id) {
		//修改后清除缓存
		redisTemplate.delete("article_"+id);
		articleDao.deleteById(id);
	}

五.缓存处理

上面我们介绍了redis的缓存,在这我们继续学习一种spring提供的缓存,springCache

核心就是将缓存的方法,作为key,查询的结果作为value,放到缓存中,当我们再次查询的时候就会,从缓存中获取.

常用注解:

@Cacheable-------使用这个注解的方法在执行后会缓存其返回结果。
@CacheEvict--------使用这个注解的方法在其执行前或执行后移除Spring Cache中的某些
元素。

需求:缓存根据id查询标签数据

1.在启动类上添加注解开启@EnabelCacheing

2.在方法上添加注解标签Cacheable  注意value属性是必须指定的,表示的是当前方法的返回值,会缓存到那个cache中

代码:

/**
	 * 根据ID查询实体
	 * @param id
	 * @return
	 */
	@Cacheable(value = "gethering",key = "#id")
	public Gathering findById(String id) {

		return gatheringDao.findById(id).get();
	}
/**
	 * 修改
	 * @param gathering
	 */
	@CacheEvict(value = "gethering",key = "#gathering.id")
	public void update(Gathering gathering) {
		gatheringDao.save(gathering);
	}

	/**
	 * 删除
	 * @param id
	 */
	@CacheEvict(value = "gethering",key = "#id")
	public void deleteById(String id) {
		gatheringDao.deleteById(id);
	}

六.总结

在项目中哪部分业务用到缓存?

1.在文章微服务模块,点赞的时候,我们将每次的点赞加一的数都保存到redis中,在每次修改和删除文章的时候进行删除缓存

2.活动微服务模块,我们通过springCache将获得信息缓存到spring中,每次直接从缓存中拿,减少数据库的访问压力
你说一下项目中是如何使用缓存的?

1.第一个通过redis实现缓存,将查询的结果存到缓存中

2.通过springCache进行缓存
说一下如何设置缓存过期时间?

redis中通过给定一个时间,然后描述它的单位,就ok了

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奋斗的小巍

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值