Spring-Data-Jpa projection用法
阿新 • • 發佈:2019-02-09
進行資料查詢時,有時候並不需要把全部欄位查詢出來,只要查詢部分的欄位即可。那麼就需要使用到Sping-Data-Jpa中的projection功能了。
前提:有使用者表和訂單表,使用者與訂單的關係是1對多關係。訂單表的模型bean:
@Entity
@Table(name = "t_order")
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@ManyToOne(targetEntity = User.class)
@JoinColumn (name = "user_id")
private User user;
private String orderName;
private String orderNumber;
@Convert(converter = DateToDateTimeConverter.class)
private DateTime createTime;
@Convert(converter = DateToDateTimeConverter.class)
private DateTime updateTime;
get/set方法略...
}
1、使用介面定義需要獲取的欄位,如獲取訂單名稱和對應的使用者id和使用者名稱稱,定義好需要獲取的欄位對應的get方法:
public interface OrderQueryDTO {
public Long getUserId();
public String getOrderName();
public String getUsername();
}
db查詢:
@Query("select orderName , user.userId ,user.username from Order where id = ?1")
<T> T findOrderWithUserNameByOrderId(Long id, Class<T> target);
使用:
OrderQueryDTO order2 = orderReadRepository.findOrderWithUserNameByOrderId(1L, OrderQueryDTO.class);
log.info("2=====使用介面作為projection===" + order2 + "," + order2.getClass().getName());
執行後對應的log:
select order0_.order_name as col_0_0_, order0_.user_id as col_1_0_, user1_.username as col_2_0_ from t_order order0_, t_user user1_ where order0_.user_id=user1_.user_id and order0_.id=?
2=====使用介面作為projection==={userId=1, orderName=orderName, username=user0},com.sun.proxy.$Proxy105
2、使用Bean作為DTO,如只需要查詢訂單名稱欄位,則定義如下bean,注意需要使用構造方法。
public class OrderQueryDTO2 {
private String orderName;
public OrderQueryDTO2(String orderName) {
super();
this.orderName = orderName;
}
get/set方法
}
db方法定義:
OrderQueryDTO2 findOrderNameById(Long id);
使用:
OrderQueryDTO2 order5 = orderReadRepository.findOrderNameById(1L);
log.info("5=====findOrderNameById 跟方法名無關,而是根據返回的bean的欄位來的===" + order5.getOrderName());
查詢結果:
Hibernate: select order0_.order_name as col_0_0_ from t_order order0_ where order0_.id=?
5=====findOrderNameById 跟方法名無關,而是根據返回的bean的欄位來的===orderName
根據sql可以看出只查詢了訂單名稱這一個欄位
3、查詢單個欄位,如查詢使用者id,需要使用@Query設定sql
/**
* 自定義查詢欄位,注意這裡查詢使用的是bean對應的屬性欄位而不是資料庫欄位
* @param username
* @return
*/
@Query("select userId from User where username = ?1")
Long findUserIdByUsername(String username);
總結:projection方式有如下三種
- 使用構造方法進行設定的bean
- 使用介面定義,自定義get方法
- 自定義sql,返回需要的欄位