2016年12月16日 星期五

Hibernate SQL - DML、DQL、JOIN 範例

SQL
參考:http://blog.csdn.net/vacblog/article/details/7769976

-Select
1.addEntity()
透過『addEntity()』將"table"與"實體類"關聯在一起
這樣可以融合SQL簡潔的語法與Hibernate的方便性

使用addEntity()的大前提
-查詢返回的是某個table的全部數據  
-該table有對應的映射實體

這時候才能透過addEntity()方法將查詢結果轉換成實體
Query query = session.createSQLQuery(
"SELECT * FROM user_account ua WHERE ua.account=:account AND ua.user_email=:emailAddress ")
.addEntity(UserAccountEntity.class) //結合entity的方式把資料傳回來,但使用時有前提
.setParameter("account", account)
.setParameter("emailAddress", emailAddress);
resultList = query.list();

2.使用別名的addEntity()
String sql = "select {myUser.*} from user_information myUser ORDER BY myUser.id";
SQLQuery query = session.createSQLQuery(sql);
query.addEntity("myUser", UserInformationEntity.class);

3.addScalar()
最基本的SQL查询就是取得一個物件的列表:
session.createSQLQuery("select * from person_inf").list();  
session.createSQLQuery("select id,name,age from person_inf").list();  

此時會返回一個Object陣列组成的List,陣列每個元素都是person_inf表的一個欄位值。Hibernate會使用ResultSetMetadata來判定返回的值的實際順序跟類型。
但是在JDBC中過多的使用ResultSetMetadata會降低程序的性能。為避免過多使用ResultSetMetadata或者指定更加明確的返回值類型,我們可以使用addScalar()方法提高效能
session.createSQLQuery("select * from person_inf")  
.addScalar("name",StandardBasicTypes.STRING)  
.addScalar("age",StandardBasicTypes.INT)  
.list();  

上述查询指定了:
-SQL查询欄位。
-要返回的欄位值和類型。
但是他仍然會返回Object陣列,但是此時不再使用ResultSetMetdata,而是明確的將\name和age按照String和int類型從resultset中取出。同時,也指明了就算query是使用*来查询的,可能獲得超過列出的這3個欄位,也僅僅會返回這3個欄位的值。

4. Join tables & 只傳回特定欄位值
Query query = session.createSQLQuery(
   "SELECT ua.f_service FROM user_account ua INNER JOIN service_account sa ON ua.f_service=sa.id
    WHERE sa.account=:serviceAccount AND ua.account=:account AND ua.user_email=:emailAddress ")
   
   .addScalar("f_service",StandardBasicTypes.INTEGER) 
   
   .setParameter("serviceAccount", serviceAccount)
   .setParameter("account", account)
   .setParameter("emailAddress", emailAddress);

resultList = query.list();

//get serviceId (createSQLQuery return Object[], but we only select f_service so only return an Object)

if (resultList.size() > 0) {
    Object aResult = resultList.get(0); //因為只有一個欄位值,所以傳回的並不是陣列,只是一個object
    serviceId = Integer.valueOf(String.valueOf(aResult));
}
下列語法也通用
Query query = session.createSQLQuery(
   "SELECT ua.f_service FROM user_account ua, service_account sa 
    WHERE ua.f_service=sa.id and sa.account=:serviceAccount AND ua.account=:account AND ua.user_email=:emailAddress ")
要是有『多個查詢值 select a,b,c......』會返回object[],使用下列方法接取
Object[] aResult = (Object[]) resultList.get(0);

5.透過addEntity、addScalar做join
http://blog.maxkit.com.tw/2014/03/hibernate-addentity-addscalar.html

沒有留言:

張貼留言