JWorld@TW the best professional Java site in Taiwan
      註冊 | 登入 | 全文檢索 | 排行榜  

» JWorld@TW » Object Relational Mapping  

按列印兼容模式列印這個話題 列印話題    把這個話題寄給朋友 寄給朋友    訂閱主題
reply to topicthreaded modego to previous topicgo to next topic
本主題所含的標籤
作者 為什麼 insert 之前要先 select ?
sai





發文: 265
積分: 1
於 2016-01-30 01:59 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
請教各位高手一個問題 … 謝謝!
我用 Hibernate 存取如下的兩個 table:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Department {
  private String oid;
  private String name;
  private String mgrid;
  private String poid;
  
  private Set<Employee> members;
        //getter & setter method ...
}
 
public class Employee implements Serializable {
  private String oid;
  private String eid;
  private String name;
  private String birthday;
        //getter & setter method ...
}


然後執行如下指令:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public class EmployeeTest {
  private Session session = null;
  private Transaction tx = null;
 
  @Before
  public void setUp() throws Exception {
    session = HibernateHelper.getSessionFactory().openSession();
    tx = session.beginTransaction();
  }
 
  @After
  public void tearDown() throws Exception {
    tx.commit();
    session.close();
  }
 
  @Test
  public void test() {
    Employee emp1 = new Employee();
    emp1.setOid("00001");
    emp1.setEid("000010");
    emp1.setName("第一人");
    emp1.setBirthday("19800305");
 
    Employee emp2 = new Employee();
    emp2.setOid("00001");
    emp2.setEid("000020");
    emp2.setName("第二十人");
    emp2.setBirthday("19850507");
 
    Set<Employee> members = new HashSet<Employee>();
    members.add(emp1);
    members.add(emp2);
    
    Department dept = new Department();
    dept.setOid("00001");
    dept.setName("最大部門");
    dept.setMembers(members);
    
    session.save(dept);
  }
}


我只是單純的想 insert 兩筆資料到 employee 及一筆資料到 department,
為什麼每次 hibernate 都會先 select employee ? (如下)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
Hibernate: 
  select
        employee_.EID,
        employee_.OID as OID4_,
        employee_.NAME as NAME4_,
        employee_.BIRTHDAY as BIRTHDAY4_ 
    from
        EMPLOYEE employee_ 
    where
        employee_.EID=?
Hibernate: 
  select
        employee_.EID,
        employee_.OID as OID4_,
        employee_.NAME as NAME4_,
        employee_.BIRTHDAY as BIRTHDAY4_ 
    from
        EMPLOYEE employee_ 
    where
        employee_.EID=?
Hibernate: 
        into
            DEPARTMENT
            (NAME, MGRID, POID, OID) 
        values
            (?, ?, ?, ?)
Hibernate: 
        into
            EMPLOYEE
            (OID, NAME, BIRTHDAY, EID) 
        values
            (?, ?, ?, ?)
Hibernate: 
        into
            EMPLOYEE
            (OID, NAME, BIRTHDAY, EID) 
        values
            (?, ?, ?, ?)


reply to postreply to post
整合勞保、公保及勞工、公務員的退休制度,讓年資可以帶著走,這樣可以讓公部門和私部門的人才有機會交流,才不會讓公部門變成一灘死水!
作者 Re:為什麼 insert 之前要先 select ? [Re:sai]
kentyeh





發文: 643
積分: 6
於 2016-01-30 03:56 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
Statickoverflow有人問了類似的問題,
使用persist()不會先SELECT,而使用save()會先SELECT.
大緻的意思是:
save()首先會先確定唯一值(PrimaryKey),然後資料會在flush()時才寫入資料庫,
所以無法保證在兩步驟的時間差內有沒有人把同一鍵值資料寫入資料庫,
而persist()則是把兩個動作,同時在flush()時一併做完,所以不用再SELECT一次


reply to postreply to post
作者 Re:為什麼 insert 之前要先 select ? [Re:kentyeh]
sai





發文: 265
積分: 1
於 2016-02-02 07:04 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
kentyeh wrote:
Statickoverflow有人問了類似的問題,
使用persist()不會先SELECT,而使用save()會先SELECT.
大緻的意思是:
save()首先會先確定唯一值(PrimaryKey),然後資料會在flush()時才寫入資料庫,
所以無法保證在兩步驟的時間差內有沒有人把同一鍵值資料寫入資料庫,
而persist()則是把兩個動作,同時在flush()時一併做完,所以不用再SELECT一次

非常感謝! Blush


reply to postreply to post
整合勞保、公保及勞工、公務員的退休制度,讓年資可以帶著走,這樣可以讓公部門和私部門的人才有機會交流,才不會讓公部門變成一灘死水!
作者 Re:為什麼 insert 之前要先 select ? [Re:kentyeh]
jenuls





發文: 49
積分: 0
於 2016-10-19 02:24 user profilesend a private message to userreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list
kentyeh wrote:
Statickoverflow有人問了類似的問題,
使用persist()不會先SELECT,而使用save()會先SELECT.
大緻的意思是:
save()首先會先確定唯一值(PrimaryKey),然後資料會在flush()時才寫入資料庫,
所以無法保證在兩步驟的時間差內有沒有人把同一鍵值資料寫入資料庫,
而persist()則是把兩個動作,同時在flush()時一併做完,所以不用再SELECT一次


那請問一下,什麼時候使用persist(), 什麼時候使用save() . 我的理解如下:
presist() 等同 save() + commit()的意思。因此只要你確認,在同一個transaction中沒有其它物件需要在同一個交易中儲存,就使用persist(); 等同於commit,直接寫入資料到資料庫。
若除了本物件外,還有其它物件需要在同一個交易中儲存,就不能使用peresist()。因此這樣就commit了。出了錯就無法rollback(); 因此在同一個交易中,若有多個物件要儲存,就必須使用save(), 到最後再加上Session.commit()指令.
不曉得對於persist() 或 save()的使用時機,我的理解對不對,還請各位前輩,不吝指教。另外我發現只要 Pk值產生
設為uuid.hex 。就不會有先產生select sql 再insert ,而是直接insert 。是不是因為uuid.hex產生的值絕對是唯一值,因此不須擔心主鍵重覆的問題。


reply to postreply to post
» JWorld@TW »  Object Relational Mapping

reply to topicthreaded modego to previous topicgo to next topic
  已讀文章
  新的文章
  被刪除的文章
Jump to the top of page

JWorld@TW 本站商標資訊

Powered by Powerful JuteForum® Version Jute 1.5.8