Hibernate一对多数据关联。指的是单向一对多数据关联一个用户有多个地址,在用户类TUser中包含地址类TAddress集合。
Hibernate如果上手了,那么所谓的一对多,多对一,多对多,一对一这些关系,应该很快能理解.下面主要介绍Hibernate一对多的问题。
1.由TUser对象将自身的id赋给addr.user_id,这样导致addr属性值变动,在事物提交的时候,会进行update。
- 1.
1)当save该用户的时候,
- insert into t_address (user_id, address, zipcode, tel) value (null, "HongKong", "233123", "1123")
- 1.
2)当tx.commit()时:
- update t_address user_id="1", address="HongKong", zipcode="233123",tel="1123" where id=2;
这样,在save user时,就会出现约束违例。
调整方法:
可以在定义数据表字段时候,不加NOT NULL约束。或者在开始为user_id随意赋一个非空值(因为还要update,不正确也没关系),或者将user_id字段从TAddress.hbm.xml中删除(本例就是这样实现)。但是这些都是权宜之计,用两条SQL语句完成一次数据库操作,性能低下。而双向一对多解决了这个问题。
下面来实现双向关联:修改配置文件 TUser.hbm.xml
xml version="1.0"?>
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="cn.blogjava.start.TUser" table="T_User" catalog="sample"
dynamic-update="true" dynamic-insert="true"
>
<id name="id" type="integer">
<column name="id" />
<generator class="native" />
id>
<property name="name" type="string" column="name" />
<property name="age" type="java.lang.Integer" column="age" />
<set
name="address"
table="t_address"
inverse="true"
cascade="all"
order-by="zipcode asc"
>
<key column="user_id">
key>
<one-to-many class="cn.blogjava.start.TAddress" />
set>
class>
hibernate-mapping>
- 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.
设定inverse="true",表明将TUser类作为被动类,将数据关联的维护工作交给关联对象TAddress来管理。
在one-to-many模型中,将many一方设为主控方有助于性能的改善。(让总理记住每个人困难,但是每个人记住总理方便)
TAddress.hbm.xml
xml version="1.0"?>
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="cn.blogjava.start.TAddress" table="T_Address" catalog="sample">
<id name="id" type="integer">
<column name="id" />
<generator class="native" />
id>
<property name="address" type="string" column="address" />
<property name="zipcode" type="string" column="zipcode" />
<property name="tel" type="string" column="tel" />
<property name="type" type="string" column="type" />
<property name="idx" type="java.lang.Integer" column="idx" />
<many-to-one
name="user"
class="cn.blogjava.start.TUser"
cascade="none"
outer-join="auto"
update="true"
insert="true"
access="property"
column="user_id"
not-null="true"
/>
class>
hibernate-mapping>
- 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.
2.对TAddress.java做如下改造:去掉user_id字段,增加user字段,和getter,setter方法。
package cn.blogjava.start;
import java.io.Serializable;
public class TAddress implements Serializable {
private Integer id;
private String address;
private String zipcode;
private String tel;
private String type;
private Integer idx;
private TUser user;
public TUser getUser() {
return user;
}
public void setUser(TUser user) {
this.user = user;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public Integer getIdx() {
return idx;
}
public void setIdx(Integer idx) {
this.idx = idx;
}
public String getTel() {
return tel;
}
public void setTel(String tel) {
this.tel = tel;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getZipcode() {
return zipcode;
}
public void setZipcode(String zipcode) {
this.zipcode = zipcode;
}
}
- 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.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
3.测试代码
既然TUser不维护关联关系,需要TAddress需要自己来维护TUser,所以需要addr.setUser(user);
package cn.blogjava.start;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import junit.framework.Assert;
import junit.framework.TestCase;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
public class HibernateTest extends TestCase {
Session session = null;
protected void setUp() {
try {
Configuration config = new Configuration().configure();
SessionFactory sessionFactory = config.buildSessionFactory();
session = sessionFactory.openSession();
} catch (HibernateException e) {
e.printStackTrace();
}
}
protected void tearDown() {
try {
session.close();
} catch (HibernateException e) {
e.printStackTrace();
}
}
/** *//**
* 对象持久化测试(Insert方法)
*/
public void testInsert() {
Transaction tran = null;
try {
TUser user = new TUser();
user.setName("byf");
user.setAge(new Integer(26));
TAddress addr = new TAddress();
addr.setTel("1123");
addr.setZipcode("233123");
addr.setAddress("HongKong");
addr.setUser(user);
TAddress addr2 = new TAddress();
addr2.setTel("139");
addr2.setZipcode("116001");
addr2.setAddress("dalian");
addr2.setUser(user);
TAddress addr3 = new TAddress();
addr3.setTel("136");
addr3.setZipcode("100080");
addr3.setAddress("beijing");
addr3.setUser(user);
//设置关联
HashSet set = new HashSet();
set.add(addr);
set.add(addr2);
set.add(addr3);
user.setAddress(set);
tran = session.beginTransaction();
//插入user信息
session.save(user);
session.flush();
tran.commit();
Assert.assertEquals(user.getId().intValue()>0 ,true);
} catch (HibernateException e) {
e.printStackTrace();
Assert.fail(e.getMessage());
if(tran != null) {
try {
tran.rollback();
} catch (Exception e1) {
e1.printStackTrace();
}
}
}
}
/** *//**
* 对象读取测试(Select方法)
*/
public void testSelect(){
String hql = " from TUser where name='byf'";
try {
List userList = session.createQuery(hql).list();
TUser user = (TUser)userList.get(0);
System.out.println("user name is " + user.getName());
for (Iterator iter = user.getAddress().iterator(); iter.hasNext();) {
TAddress addr = (TAddress) iter.next();
System.out.println("user address is " + addr.getAddress());
}
Assert.assertEquals(user.getName(), "byf");
} catch (Exception e) {
e.printStackTrace();
Assert.fail(e.getMessage());
}
}
}
- 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.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
- 81.
- 82.
- 83.
- 84.
- 85.
- 86.
- 87.
- 88.
- 89.
- 90.
- 91.
- 92.
- 93.
- 94.
- 95.
- 96.
- 97.
- 98.
- 99.
- 100.
- 101.
- 102.
- 103.
- 104.
- 105.
- 106.
- 107.
- 108.
- 109.
- 110.
- 111.
- 112.
- 113.
- 114.
- 115.
以上介绍Hibernate一对多数据关联。
【编辑推荐】