JPA的本地查詢(native query)轉

JPA的本地查詢(native query

 

JPA支持本地查詢,所謂本地查詢,就是使用原生的sql語句(根據數據庫的不同,在sql的語法或結構方面可能有所區別)進行查詢數據庫的操作。

 

本地查詢主要使用EntityManager接口裏的方法:

public interface EntityManager {
   public void persist(Object entity);
   public <T> T find(Class <T> entityClass, Object primaryKey);
   public <T> T getReference(Class <T> entityClass, Object primaryKey);
   public <T> T merge(T entity);
   public void remove(Object entity);
   public void lock(Object entity, LockModeType lockMode);

   public void refresh(Object entity);
   public boolean contains(Object entity);
   public void clear( );

   public void joinTransaction( );
   public void flush( );
   public FlushModeType getFlushMode( );
   public void setFlushMode(FlushModeType type);

   public Query createQuery(String queryString);
  
public Query createNamedQuery(String name);

  
public Query createNativeQuery(String sqlString);
   public Query createNativeQuery(String sqlString, String resultSetMapping);
   public Query createNativeQuery(String sqlString, Class resultClass);


   public Object getDelegate( );

   public void close( );
   public boolean isOpen( );
}

 

createNativeQuery方法的三種形式,但用這個方法的缺點是,要將查詢的sql語句及返回結果集類型傳遞進去。還有一種方法是使用createNamedQuery,這樣就可以避免在這裏直接寫入sql語句以及返回的結果集類型等參數,而可以在相關的Entity類裏對這些信息進行配置。

 

//這裏只是傳遞進去一個string

Query q = em.createNamedQuery("ReturnOrderListWithFullScalarType");

//這裏是設定在sql中所需的參數

q.setParameter(1, customer.getId());

//得到結果集

List orderList = q.getResultList();

 

 

這個查詢主要是根據用戶的id 來獲取他名下的所有訂單。所以,在實體類 Order中,加入相關的native query annotation.

 

@NamedNativeQueries

(

    {

       @NamedNativeQuery(

           name="ReturnOrderListWithFullScalarType",

              query="select o.id as order_id,o.create_date as order_creation_date,o.description as order_description,o.sum_price as order_sum_total,

c.name as customer_name,c.ctype as customer_type,c.id as customer_id from orders o join customer c on o.cust_id=c.id where o.cust_id=?1",

           resultSetMapping="ReturnOrderListWithFullScalarType"),

        。。。。。。。。。。。。。可能還有更多的本地查詢設置

}

)

 

@NamedNativeQueries 如果在一個實體類中有多個NamedNativeQuery的話,必須使用該批註,並且將單個的NamedNativeQuery都作爲NamedNativeQueries數組中的一個元素。

@NamedNativeQuery,在這裏設置關於該本地查詢的信息。name表示傳遞進EntityManager.createNamedQuery(“name”)的參數,query表示實施本地查詢的sql語句,resultSetMapping表示返回結果集的映射方式。它的意思就是結果集將以哪種形式來保存。

 

接着,就要設置這個結果集的映射方式了。

 

@SqlResultSetMappings(

{

    @SqlResultSetMapping

    (

       name="ReturnOrderListWithFullScalarType",

       entities={},

       columns=

       {

           @ColumnResult(name="order_id"),

           @ColumnResult(name="order_creation_date"),

           @ColumnResult(name="order_description"),

           @ColumnResult(name="order_sum_total"),

           @ColumnResult(name="customer_id"),

           @ColumnResult(name="customer_name")

       }

    ),

       。。。。。。。。。。。。。可能還有更多的結果集映射設置

})

針對每一個本地查詢的返回值,都有一個結果集和它映射。它可以返回

1. 實體(包括不同類型的實體,即多個實體) Entity

2. 標量值 Scalar

3. 實體與標量值的組合 Entity+Scalar

 

默認情況下,JPA假設原生sql查詢中select語句將會:

1.      返回一個實體類型

2.      包含與返回的實體的所有字段或屬性相對應的所有列,即列名和實體屬性/字段名一樣

3.      查詢中沒有用列名別名,column alias,即沒有用 AS 指定別名

 

@SqlResultSetMappings,如果在一個實體類中有多個@NamedNativeQuery的話,必然就有多個結果集映射@SqlResultSetMapping。在這種情況下,必須使用該批註,並且將單個的SqlResultSetMapping都作爲SqlResultSetMappings數組中的一個元素。

@SqlResultSetMapping,關於結果集映射的詳細信息。

name 表示該結果集映射的名字,與@NamedNativeQuery中的resultSetMapping="ReturnOrderListWithFullScalarType"的值相對應。

entities表示查詢結果集會被映射進實體,如果有就要將所有返回的實體一一列出(這裏我們將結果集全部映射進標量,所以entities屬性是個空數組)。

columns表示將被映射進標量的結果集中的各個列。

 

這裏要說一下標量(Scalar)這個概念。在物理學上,標量與矢量(Vector)是相互對應的,矢量是既有方向又有大小的量,而標量是隻有大小的量。在此處,Scalar的含義與物理學上的定義差不多,Scalar可以認爲是一個沒有屬性/方法的單純的常量(可以想象爲java數據類型的primitive type),而與它相對的則是有方法/屬性的對象(object type)。那麼採用這種映射機制,我們從數據庫取來的每一條記錄的每一個字段,僅僅是被單純的作爲一個常量,保存在每一個columnResult中。

 

@ ColumnResult,就是指在sql語句中,將哪些查詢的列保存進來。每一個@ColumnResult對應一個列,name="order_id" ,注意,如果在select的時候,用AS 制定了列的別名,“order_id 則表示的是別名。

 

這種映射方式比較簡單,我們可以推測,得到的結果集List中,數據會是這樣:

[  {“1”, “2”, “3”,  …},  {“1”, “2”, “3”,  …}, ……  ]

 

經過運行測試程序,得到了我們的推論

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章