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”