(7)hibernate中OneToMany單向
阿新 • • 發佈:2018-12-13
OneToMany:在One一方新增外來鍵,比如Message和Comment,就在Message這一方新增set
Message.hbm.xml:
<hibernate-mapping> <class name="model.Message" table="MESSAGE"> <id name="id" type="int"> <column name="ID" /> <generator class="native" /> </id> <property name="content" type="java.lang.String"> <column name="CONTENT" /> </property> <property name="title" type="java.lang.String"> <column name="TITLE" /> </property> <set name="comments" lazy="extra"> <key> <column name="M_ID" /> </key> <one-to-many class="model.Comment" /> </set> </class> </hibernate-mapping>
其中set裡面的key用來指定在對方(Comment)的外來鍵名稱,<one-to-many/>裡面的class表示set裡面的物件型別
package model; import java.util.HashSet; import java.util.Set; public class Message { private int id; private String content; private String title; private Set<Comment> comments; public Message() { comments=new HashSet<Comment>(); } public void addComment(Comment comment) { comments.add(comment); } public Set<Comment> getComments() { return comments; } public void setComments(Set<Comment> comments) { this.comments = comments; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } }
void test() { Session s=null; try { s=HibernateUtil.getSession(); s.beginTransaction(); Comment c1=new Comment(); c1.setContent("dewesf"); s.save(c1); Comment c2=new Comment(); c2.setContent("fsdFSDFSD"); s.save(c2); Message msg=new Message(); msg.setTitle("test"); msg.setContent("testtest"); msg.addComment(c1); msg.addComment(c2); s.save(msg); s.getTransaction().commit(); } catch (Exception e) { // TODO 自動生成的 catch 塊 e.printStackTrace(); s.getTransaction().rollback(); }finally { HibernateUtil.closeSession(s); } }
在msg類中新增addComment方法,便於往集合加入元素,結果發5條sql,3條插入(save),2條更新(往集合新增元素,改變了快取中的msg物件,就會發出更新,為什麼是2條?因為往集合新增元素實際上是在comment中設定msg_id,新增幾個元素就發出幾條update的sql語句)
void test1() {
Session s=null;
try {
s=HibernateUtil.getSession();
s.beginTransaction();
Message msg=s.load(Message.class, 1);
for(Comment c:msg.getComments()) {
System.out.println(c.getContent());
}
s.getTransaction().commit();
} catch (Exception e) {
// TODO 自動生成的 catch 塊
e.printStackTrace();
s.getTransaction().rollback();
}finally {
HibernateUtil.closeSession(s);
}
}
load延遲載入,一開始只需要msg物件,就只發一條sql(這條sql除了comments屬性其他屬性都通用),然後需要msg裡面的comments就需要再發一條sql,所以2條sql
void test2() {
Session s=null;
try {
s=HibernateUtil.getSession();
s.beginTransaction();
Message msg=s.load(Message.class, 1);
System.out.println(msg.getComments().size());
s.getTransaction().commit();
} catch (Exception e) {
// TODO 自動生成的 catch 塊
e.printStackTrace();
s.getTransaction().rollback();
}finally {
HibernateUtil.closeSession(s);
}
}
獲取size同樣也是2條sql,一條取普通屬性,一條取comments,如果需要用到size,用select count(ID)較為智慧,效率較高,所以可以在set裡面設定lazy=“extra”