jpa動態查詢與多表聯合查詢

weixin_34071713發表於2019-01-08

jpa操作單表時簡單明瞭,省去了sql的拼寫,但如果需要多表聯查的時候就不行了。

1.當jpa需要聯表查詢的時候 用到@Query註解,自定義sql 其中nativeQuery=true,指定使用原生sql進行查詢

 @Query(value = "select user.* from user left join role   on ( user.role_id=role.id) where  user.sex=?1  and  role.name is not null;", nativeQuery = true)
    List<User> findUserBy(String sex);

上面的sql用到了left join on 那就說明一下其用法,通常情況下,多表查詢都會使用select * from a,b where a.xx=b.xx;

left join on +多條件 先利用on 後面進行兩表匹配,然後利用where後面的條件進行篩選,最後選出符合條件的結果。

a left join b on(a.xx=b.xx) where 篩選條件;

2.spring data jpa使用@Query更新實體類

用到jpa自定義sql,需要寫資料庫時 需要加上 @Modifying(clearAutomatically = true)

    @Modifying(clearAutomatically = true)
    @Query("update user set user.name=?1 where id=?2")
    void updateName(String name,Integer id);

@Modifying原始碼

@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.METHOD, ElementType.ANNOTATION_TYPE })
@Documented
public @interface Modifying {

	/**
	 * Defines whether we should clear the underlying persistence context after executing the modifying query.
	 * 
	 * @return
	 */
	boolean clearAutomatically() default false;
}

clearAutomatically,預設為false,表示在執行修改查詢後是否清除底層持久化上下文

執行完modifying query, EntityManager可能會包含過時的資料,因為EntityManager不會自動清除實體。 只有新增clearAutomatically屬性,EntityManager才會自動清除實體物件。

3.jpa 動態條件查詢

首先需要實現 JpaSpecificationExecutor<T> 介面

public List<User> queryUserList(User request)
return userRepository.findAll((Specification<User>) (root, query, criteriaBuilder) -> {
            List<Predicate> predicates = new ArrayList<>();
            if (request != null) {
                if (StringUtils.isNotBlank(request.getUserName())) {
                    predicates.add(criteriaBuilder.equal(root.get("userName"), ProcessStatusEnum.fromName(request.getUsername())));
                }
                

                if (request.getCreateDate() != null && request.getCreateDate().isValidated()) {
                    predicates.add(criteriaBuilder.greaterThanOrEqualTo(root.get("StartDate"), request.getStartDate()));
                    predicates.add(criteriaBuilder.lessThanOrEqualTo(root.get("EndDate"), request.getEndDate()));
                }
            }
            return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
        }, new Sort(Sort.Direction.DESC, "id"));}

以上方法呼叫了 List<T> findAll(@Nullable Specification<T> spec, Sort sort);

轉載於:https://my.oschina.net/u/2263272/blog/2998764

相關文章