Hibernate一对多数据关联。指的是单向一对多数据关联一个用户有多个地址,在用户类TUser中包含地址类TAddress集合。
1.数据模型
2.表定义sql
- use sample;
- DROP TABLE T_Address;
- DROP TABLE T_User;
- CREATE TABLE T_User (
- id INT NOT NULL AUTO_INCREMENT
- , name VARCHAR(50)
- , age INT
- , PRIMARY KEY (id)
- );
- CREATE TABLE T_Address (
- id INT NOT NULL AUTO_INCREMENT
- , address VARCHAR(200)
- , zipcode VARCHAR(10)
- , tel VARCHAR(20)
- , type VARCHAR(20)
- , user_id INT NOT NULL
- , idx INT
- , PRIMARY KEY (id)
- , INDEX (user_id)
- , CONSTRAINT FK_T_Address_1 FOREIGN KEY (user_id)
- REFERENCES T_User (id)
- );
POJO类
TUser.java
- package cn.blogjava.start;
- import java.util.Set;
- public class TUser implements java.io.Serializable {
- // Fields
- private Integer id;
- private Integer age;
- private String name;
- private Set address;
- // Constructors
- public Integer getAge() {
- return age;
- }
- public void setAge(Integer age) {
- this.age = age;
- }
- public Set getAddress() {
- return address;
- }
- public void setAddress(Set address) {
- this.address = address;
- }
- /** default constructor */
- public TUser() {
- }
- /** constructor with id */
- public TUser(Integer id) {
- this.id = id;
- }
- // Property accessors
- public Integer getId() {
- return this.id;
- }
- public void setId(Integer id) {
- this.id = id;
- }
- public String getName() {
- return this.name;
- }
- public void setName(String name) {
- this.name = name;
- }
- }
TAddress.java
- 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 userId;
- private Integer idx;
- 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 Integer getUserId() {
- return userId;
- }
- public void setUserId(Integer userId) {
- this.userId = userId;
- }
- public String getZipcode() {
- return zipcode;
- }
- public void setZipcode(String zipcode) {
- this.zipcode = zipcode;
- }
- }
3.配置文件
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" />
- < SPAN>id>
- <property name="name" type="string" column="name" />
- <property name="age" type="java.lang.Integer" column="age" />
- <set name="address" table="t_address" cascade="all" order-by="zipcode asc">
- <key column="user_id">
- < SPAN>key>
- <one-to-many class="cn.blogjava.start.TAddress" />
- < SPAN>set>
- < SPAN>class>
- < SPAN>hibernate-mapping>
TAddress.hbm.xml
注意:没有配置user_id字段。
- 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" />
- < SPAN>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" />
- < SPAN>class>
- < SPAN>hibernate-mapping>
4.测试代码
- 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");
- TAddress addr2 = new TAddress();
- addr2.setTel("139");
- addr2.setZipcode("116001");
- addr2.setAddress("dalian");
- TAddress addr3 = new TAddress();
- addr3.setTel("136");
- addr3.setZipcode("100080");
- addr3.setAddress("beijing");
- //设置关联
- 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());
- }
- }
- }
说明:
一个问题,由于是单向关联,为了保持关联关系,我们只能通过主控方对被动方进行级联更新。如果被关联方的字段为NOT NULL属性,当Hibernate一对多创建或者更新关联关系时,可能出现约束违例。
例子中T_Address表中的user_id 为NOT NULL,如果在TAddress.hbm.xml映射了全部字段时。创建一个用户并赋予她地址信息,对于T_Address表而言,Hibernate一对多会执行两条sql语句来保存地址信息。
要执行两条SQL语句,是因为关联是单向的,就是说对于TAddress对象而言,并不知道自己应该与那一个TUser对象关联,只能先将user_id设为一个空值。
之后,根据配置文件
- <set name="address" table="t_address" cascade="all" order-by="zipcode asc">
- <key column="user_id">
- < SPAN>key>
- <one-to-many class="cn.blogjava.start.TAddress" />
- < SPAN>set>
Hibernate一对多数据关联是Hibernate中比较典型的问题,这里只是简单介绍。
【编辑推荐】