2016年12月15日 星期四

Hibernate HQL - DML、DQL、JOIN 範例

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

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

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

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

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

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

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

沒有留言:

張貼留言