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

本文介绍如何使用JPA Specification进行灵活的多条件查询,通过具体示例展示了如何根据前端传递的不同参数组合,构建动态查询条件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

       第一次使用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()];
                //根据id 倒序排列
                query.orderBy(cb.desc(root.get("id")));
                //这句大概意思就是将上面拼接好的条件返回去
                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

评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值