2016年12月15日 星期四

Hibernate HQL - DML、DQL、JOIN 範例

HQL
-Select 
1.利用 ? 設定 sql 中的參數,搭配 query.setParameter("第幾個問號",變數);
Session session = BackendHibernateUtil.getSession();
List resultList = new LinkedList<>();
try {
     Query query = session.createQuery("FROM CtrlSourceAreaEntity WHERE source_type = ?");
     query.setParameter(0,sourceType);
     resultList = query.list();
} catch (HibernateException e) {
     log.error("XMLParserDAO @querySourceAreaId Fail:", e);
} finally {
     session.close();
}
return resultList;
2.利用 :Name 設定參數
"FROM CtrlSourceAreaEntity WHERE source_type = :sourceType"
 query.setParameter("sourceType",sourceType);

3.SQL Query In 設定參數
Query query = session.createQuery("FROM ScheduleDownloadEntity WHERE status in (:statusNames)  ORDER BY create_time ");
query.setParameterList("statusNames", statusList);
resultList = query.list();

-Update
1.executeUpdate()是執行DML的意思
 Query query = session.createQuery("UPDATE UserAccountEntity SET password = ? where f_service = ? AND account = ? AND user_email = ?");
 query.setParameter(0, userPasswordMD5);
 query.setParameter(1, serviceId);
 query.setParameter(2, account);
 query.setParameter(3, emailAddress);
 query.executeUpdate(); //這句是commit的意思

-Delete
1.executeUpdate() 是執行DML的意思

2.executeUpdate() 會傳回 int 影響的資料筆數
Query query = session.createQuery("DELETE EdititemEntity WHERE kind = ? AND post_time BETWEEN  ? AND ? ");
query.setParameter(0, taskNumber);
query.setParameter(1, startDate);
query.setParameter(2, endDate);
int resultCount = query.executeUpdate(); //可以取得DML影響的資料筆數

-Insert
1.將傳進來的 entity 實體 透過 session.save() 的方式把資料存進DB
public void insertData(EdititemEntity edititemEntity) {
Session session = Opv_lyHibernateUtil.getSession(); //Hibernate Session Connect
Transaction tx = session.beginTransaction(); //一組交易
try {
     session.save(edititemEntity); //將傳進來的Entity存進DB(透過Hibernate專屬方法)
     tx.commit(); //交易確認
} catch (HibernateException e) {
     tx.rollback(); //交易取消
     log.error("CategoryDAO @insertData Fail,newsId={},error={}", edititemEntity.getId(), e);
} finally {
     session.close();
}
}

HQL-Join

參考:
http://openhome.cc/Gossip/HibernateGossip/ManyToOne.html

多對一:
一個簡單的實體與實體間之關係為『多對一』的關係,例如『使用者』與『房間』的關係就是多對一的關係,多個使用者使用同一房間。

範例目標:

A:每個 user 有特定的 serviceId(f_service) ,多個user會對上同一個serviceId,希望透過HQL的方式,取得user時,順便取得service_account




1.實體設定(UserAccountEntity)

-在多對一的情況下,『多』的實體才需要特別設定,『一』的部份不用調整,因此我們只調整UserAccount
-UserAccountEntity.class
UserAccountEntity類別中有一serviceAccountEntity屬性,將參考至serviceAccountEntity實例,多個User實例可共同參考一個service實例











2.設定檔(UserAccountEntity.hbm.xml)
- class="絕對路徑""
- column="f_service" → userAccount的f_service(FK)會去參考到serviceAccount的id(PK),兩張table才會連結在一起
- cascade表示主控方(User)進行save-pdate、delete等 相關操作時,被控 方(Room)是否也一併進行相關操作,簡單的說,也就是您儲存或更新User實例時,被參考到的Room實例是否一併對資料庫發生儲存或操作,設定為 all,表示主控方任何操作,被控方也進行對應操作。

-把原先的fService先註解掉



-設定mana-to-one的參數















3.查詢結果
- 重要:INNER JOIN 是 userAccount實體中的serviceAccount屬性




- 結果
每個傳回的結果都帶有UserAccountEntity & ServiceAccountEntity

沒有留言:

張貼留言