Jpa操作数据库之动态SQL语句的使用

第一次使用Jpa,之前都是使用的SSM,现在公司换框架为SpringBoot,随之持久层也换为了Jpa,个人感觉Jpa跟Hibernate使用有些相似,好了,废话不多说,上需求,一个表里包含字段[name 名称,cityid 城市ID  , parent 父级ID],前台根据这三个字段实现条件查询,这三个参数都不是必须传的,可能前台只给一个,也可能会给多个,按照前台传参去查询数据,如果用以前的SSM获取很简单,一个动态SQL就搞定了,但是JPA就没有那么简单了,下面上代码:

//请忽略SchoolRepository,这只是我给自己的Dao层起的名字,主要是要实现JpaSpecificationExecutor这个接口
public interface SchoolRepository extends JpaRepository<SchoolEntity,Long> ,JpaSpecificationExecutor<SchoolEntity> {


}

上面的代码相当于我们之前的Dao层 ,这是一个接口,实现了JpaRepository与今天的主角JpaSpecificationExecutor,后面这个接口里面有我们需要的方法,我们既然继承了他,当然就可以使用他的方法。

这样我们的Dao层就好了,只需要多继承一个JpaSpecificationExecutor接口即可,下面我们就来写我们Service层了

public List<SchoolEntity> selectschool(SchoolParam schoolParam) {
        /**root :我们要查询的类型
         * query:添加查询条件
         * cb: 构建条件
         * specification为一个匿名内部类
         */
        Specification<SchoolEntity> specification=new Specification<SchoolEntity>() {
            @Override
            public Predicate toPredicate(Root<SchoolEntity> root,
                                         CriteriaQuery<?> query,
                                         CriteriaBuilder cb) {
                //我理解为创建一个条件的集合
                List<Predicate> predicates = new ArrayList<Predicate>();
                //判断传过来的CityId是否为null,如果不为null就加到条件中
                if(schoolParam.getCityId()!=null){
                   /** cb.equal()相当于判断后面两个参数是否一致
                    *root相当于我们的实体类的一个路径,使用get可以获取到我们的字段,因为我的cityid为Long类型
                    * 所以是as(Long.class)
                    *如果为Int,就是as(Integer.class) 第二个参数为前台传过来的参数,这句话就相当于
                    * 数据库字段的值cityid = 前台传过来的值schoolParam.getCityId()
                    */
                    predicates.add(cb.equal(root.get("cityid").as(Long.class),schoolParam.getCityId()));
                }
                if(schoolParam.getName()!=null){
                    //这里相当于数据库字段 name like %前台传过来的值%
                    predicates.add(cb.like(root.get("name"),"%"+schoolParam.getName()+"%"));
                }
                if(schoolParam.getParent()!=null){
                    //这里相当于数据库字段 parent(也是Long类型) = 前台传过来的值schoolParam.getParent()
                    predicates.add(cb.equal(root.get("parent").as(Long.class),schoolParam.getParent()));
                }
                //创建一个条件的集合,长度为上面满足条件的个数
                Predicate[] pre = new Predicate[predicates.size()];
                //这句大概意思就是将上面拼接好的条件返回去
                return query.where(predicates.toArray(pre)).getRestriction();

            }
        };   //这里我们按照返回来的条件进行查询,就能得到我们想要的结果
             List<SchoolEntity> list= schoolRepository.findAll(specification);
             System.out.println("查询返回的结果为"+list);
             return list;
    }

至此,我们的Service就写好了,其实很简单,我一开始走了不少弯路,测试就不写了,大家可以自己测试下

如果还有疑问的话,给大家推荐一个关于Jpa的视频,里面讲的很详细,大家可以去看看 (慕课网)https://www.imooc.com/video/14540

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享