【spring data jpa】jpa中criteria拼接in查询

商品类型查询条件构造

 示例代码:

 

public static Specification<GoodsType> where(final GoodsType goodsType){
        
        
        return new Specification<GoodsType>() {
            
            @Override
            public Predicate toPredicate(Root<GoodsType> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                
                List<Predicate> predicates = new ArrayList<Predicate>();  
                //名字+拼音
                String name = goodsType.getName();
                if(StringUtils.isNotBlank(name)){
                    Predicate like1 = cb.like(root.<String>get("name"), "%" + name +"%");
                    Predicate like2 = cb.like(root.<String>get("pyAll"), "%" + PingYinUtil.getPingYin(name) +"%");
                    Predicate like3 = cb.like(root.<String>get("pyHead"), "%" + PingYinUtil.getPinYinHeadChar(name) +"%");
                    predicates.add(cb.or(like1,like2,like3));
                }
                
                //uid
                String uid = goodsType.getUid();
                if(StringUtils.isNotBlank(uid)){
                    predicates.add(cb.equal(root.<String>get("uid"),uid));
                }
                
                //parentUid
                String parentUid = goodsType.getParentUid();
                if(StringUtils.isNotBlank(parentUid)){
                    predicates.add(cb.equal(root.<String>get("parentUid"),parentUid));
                    
                }
                //启用 状态
                Integer enabledFlag = goodsType.getEnabledFlag();
                if (enabledFlag != null){
                    predicates.add(cb.equal(root.get("enabledFlag"),enabledFlag));
                }

                //层级
                Integer floor = goodsType.getFloor();
                if (floor != null){
                    predicates.add(cb.equal(root.get("floor"),floor));
                }
                
                //对外编码
                String outerCode = goodsType.getOuterCode();
                if(StringUtils.isNotBlank(outerCode)){
                    
                    predicates.add(cb.equal(root.<String>get("outerCode"),outerCode));
                }
                //对外id
                String outerId = goodsType.getOuterId();
                if(StringUtils.isNotBlank(outerId)){
                    predicates.add(cb.equal(root.<String>get("outerId"),outerId));
                }
                
                //租户ID
                String tid = goodsType.getTenementId(); 
                if(StringUtils.isNotBlank(tid)){
                    predicates.add(cb.equal(root.<String>get("tenementId"),tid));
                }
                
                String typeUidArrStr = goodsType.getTypeUidArrStr();
                if (StringUtils.isNotBlank(typeUidArrStr)) {
                    In<String> in = cb.in(root.<String>get("parentUid"));
                    String[] split = typeUidArrStr.split(",");
                    for (String string : split) {
                        in.value(string);
                    }
                    predicates.add(in);
                }
                
                

                //未被删除 且  启用状态无视
                predicates.add(cb.equal(root.get("delFlag"),GoodsType.DEL_FLAG_EXIST));
                
                return query.where(predicates.toArray(new Predicate[predicates.size()])).getRestriction();
            }
        };
        
    }

 

转载于:https://www.cnblogs.com/sxdcgaq8080/p/9625797.html

Spring Data JPA中,使用HQL(Hibernate Query Language)实现联合查询是一种常见需求,尤其在处理多个实体之间的关联数据时。HQL是一种面向对象的查询语言,类似于SQL,但它操作的是持久化对象及其属性,而不是直接操作数据库表。 ### 使用HQL实现联合查询 1. **定义实体类之间的关联关系** 在使用HQL进行联合查询之前,必须确保实体类之间已经正确地定义了关联关系。常见的关联类型包括`@OneToOne`、`@OneToMany`、`@ManyToOne`和`@ManyToMany`。这些注解用于描述实体之间的关系,并在数据库中映射为相应的外键约束。 ```java @Entity public class Order { @Id private Long id; @ManyToOne @JoinColumn(name = "customer_id") private Customer customer; // 其他字段和方法 } @Entity public class Customer { @Id private Long id; private String name; @OneToMany(mappedBy = "customer") private List<Order> orders; // 其他字段和方法 } ``` 2. **编写HQL查询语句** 在定义好实体类之间的关联关系后,可以使用HQL编写联合查询语句。HQL支持多种类型的联合查询,包括`JOIN`、`LEFT JOIN`、`INNER JOIN`等。以下是一个使用`JOIN`进行联合查询的示例: ```java String hql = "SELECT o FROM Order o JOIN o.customer c WHERE c.name = :customerName"; TypedQuery<Order> query = entityManager.createQuery(hql, Order.class); query.setParameter("customerName", "John Doe"); List<Order> orders = query.getResultList(); ``` 在这个例子中,`JOIN o.customer c`表示将`Order`实体与`Customer`实体进行联合查询,并通过`c.name`筛选出特定客户的订单。 3. **使用`@Query`注解在Repository中定义HQL查询** Spring Data JPA允许在Repository接口中使用`@Query`注解来定义自定义的HQL查询。这种方式可以简化查询的调用过程,并且可以与Spring Data JPA的分页、排序等功能结合使用。 ```java public interface OrderRepository extends JpaRepository<Order, Long> { @Query("SELECT o FROM Order o JOIN o.customer c WHERE c.name = :customerName") List<Order> findOrdersByCustomerName(@Param("customerName") String customerName); } ``` 在这个例子中,`findOrdersByCustomerName`方法可以通过传入的`customerName`参数来查找所有属于该客户的订单。 4. **处理联合查询的结果** HQL查询的结果可以是单个实体、多个实体的组合,或者是特定字段的投影。如果需要返回多个实体的组合,可以使用`Object[]`或自定义的DTO(Data Transfer Object)类来封装结果。 ```java @Data public class OrderCustomerDTO { private Long orderId; private String customerName; public OrderCustomerDTO(Long orderId, String customerName) { this.orderId = orderId; this.customerName = customerName; } } @Repository public class OrderRepositoryImpl implements OrderRepositoryCustom { @PersistenceContext private EntityManager entityManager; @Override public List<OrderCustomerDTO> findOrderAndCustomerNames() { String hql = "SELECT new com.example.dto.OrderCustomerDTO(o.id, c.name) FROM Order o JOIN o.customer c"; return entityManager.createQuery(hql, OrderCustomerDTO.class).getResultList(); } } ``` 在这个例子中,`OrderCustomerDTO`是一个自定义的DTO类,用于封装查询结果中的订单ID和客户名称。 5. **优化联合查询的性能** 在进行联合查询时,可能会遇到性能问题,尤其是在处理大量数据时。为了优化性能,可以考虑以下几种方法: - **使用`fetch`进行预加载**:通过在HQL中使用`fetch`关键字,可以一次性加载关联的实体,避免多次查询数据库。 ```java String hql = "SELECT o FROM Order o FETCH JOIN o.customer c WHERE c.name = :customerName"; ``` - **使用分页**:如果查询结果集较大,可以使用分页功能来减少每次查询返回的数据量。 ```java @Query("SELECT o FROM Order o JOIN o.customer c WHERE c.name = :customerName") Page<Order> findOrdersByCustomerName(@Param("customerName") String customerName, Pageable pageable); ``` - **使用索引**:确保数据库中的关联字段上有适当的索引,以加快查询速度。 6. **处理复杂的联合查询逻辑** 对于更复杂的联合查询逻辑,可以使用`Criteria API`或`JPQL`拼接工具来构建动态查询。`Criteria API`提供了一种类型安全的方式来构建查询,适用于需要根据条件动态生成查询语句的场景。 ```java public List<Order> findOrdersByCustomerNameAndStatus(String customerName, String status) { CriteriaBuilder cb = entityManager.getCriteriaBuilder(); CriteriaQuery<Order> cq = cb.createQuery(Order.class); Root<Order> orderRoot = cq.from(Order.class); Join<Order, Customer> customerJoin = orderRoot.join("customer"); Predicate customerNamePredicate = cb.equal(customerJoin.get("name"), customerName); Predicate statusPredicate = cb.equal(orderRoot.get("status"), status); cq.where(customerNamePredicate, statusPredicate); return entityManager.createQuery(cq).getResultList(); } ``` 在这个例子中,`Criteria API`用于构建一个包含两个条件的查询:客户名称和订单状态。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值