`
TriEyes
  • 浏览: 11061 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
社区版块
存档分类
最新评论

Learning Hibernate step by step -- 04 多对一关联关系映射

阅读更多
Java对象有很多关联关系映射,如多对一、一对一、多对多等,在数据库中表之间有主外键关联,Java对象的关联关系如何与数据表形成映射呢?首先来看多对一的映射关系。
一、背景
1. 一所学校有很多班级(Group),一个班级有若干学生(Student),学生和班级之间的映射就是多对一的关联关系,如图所示:
[img][/img]
2. 数据库中分别存在t_group表和t_student表,分别对应班级和学生,t_student表有一个外键,引用t_group的id字段,ER关系如图所示:
[img][/img]
二、建立域对象
1. 先在项目中建立两个独立的域对象,Group和Student,两个对象包含基本的信息,先不对两个对象做关联。两外再分别建立两个对象的Dao对象,负责与数据库交互。
Persistent.java
public class Persistent implements Serializable {
	private static final long serialVersionUID = 1L;
	private long id;
	public long getId() {
		return id;
	}
	public void setId(long id) {
		this.id = id;
	}
}

Group.java
public class Group extends Persistent {
	private static final long serialVersionUID = 1L;
	String grpName;

	public String getGrpName() {
		return grpName;
	}
	public void setGrpName(String grpName) {
		this.grpName = grpName;
	}
}

Student.java
public class Student extends Persistent {
	private static final long serialVersionUID = 1L;
	private String studNo;
	private String studName;
	private String studSex;
	public String getStudNo() {
		return studNo;
	}
	public void setStudNo(String studNo) {
		this.studNo = studNo;
	}
	public String getStudName() {
		return studName;
	}
	public void setStudName(String studName) {
		this.studName = studName;
	}
	public String getStudSex() {
		return studSex;
	}
	public void setStudSex(String studSex) {
		this.studSex = studSex;
	}
}

GroupDao.java
public class GroupDao {
	public long saveGroup(Object obj) {
		Session session = HibernateUtil.getSessionFactory().openSession();
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			Long retId = (Long)session.save(obj);
			tx.commit();
			return retId.longValue();
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			// DO NOT swallow the Exception in actual projects.
			// throw e;
			e.printStackTrace();
			return 0L;
		} finally {
			session.close();
		}
	}
}

StudentDao.java
public class StudentDao {
	public long saveStudent(Object obj) {
		Session session = HibernateUtil.getSessionFactory().openSession();
		Transaction tx = null;
		try {
			tx = session.beginTransaction();
			Long retId = (Long)session.save(obj);
			tx.commit();
			return retId.intValue();
		} catch (Exception e) {
			if (tx != null) {
				tx.rollback();
			}
			// DO NOT swallow the Exception in actual projects.
			// throw e;
			e.printStackTrace();
			return 0L;
		} finally {
			session.close();
		}
	}
}

三、建立映射文件
1. 分别建立Group和Student的映射文件
Group.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping 
	package="com.foobar.domain">
	<class name="Group" table="`T_Group`">
		<comment>Groups infomation.</comment>
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="grpName" 
				  not-null="true" 
				  column="`grp_name`"/>
	</class>
</hibernate-mapping>

Student.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping 
	package="com.foobar.domain">
	<class name="Student" table="`T_Student`">
		<comment>Students infomation.</comment>
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="studName" 
				  length="15" 
				  column="`stud_name`"/>
		<property name="studSex" 
				  not-null="true" 
				  length="1"
				  column="`stud_sex`"/>
	</class>
</hibernate-mapping>

2. 在Hibernate配置文件中引入映射文件
...
<mapping resource="com/foobar/conf/hbm/Group.hbm.xml"/>
<mapping resource="com/foobar/conf/hbm/Student.hbm.xml"/>
...

另外,我们加入如下属性,让程序在加载配置文件是自动创建表
<!-- mapping与ddl之间的关系-->
<property name="hibernate.hbm2ddl.auto">create</property>

四、建立测试程序,分别建立Group对象和Student对象,分别保存到数据库中
public class SchoolMgt {
	public static void main(String[] args) {
		GroupDao grpDao = new GroupDao();
		Group grp = new Group();
		StudentDao studDao = new StudentDao();
		Student stud = new Student();
		
		grp.setGrpName("Group A");
		if(grpDao.saveGroup(grp) != 0) {
			System.out.println("Group added successful!");
		}

		stud.setStudName("Zhangsan");
		stud.setStudNo("0001001");
		stud.setStudSex("F");
		if(studDao.saveStudent(stud) != 0) {
			System.out.println("Student added successful!");
		}
	}
}

观察控制台输出:
Group added successful!
Student added successful!
五、建立关联关系
1. 先建立对象的关联关系,在Student对象中增加Group对象的引用,代码如下(省略了setter和getter):
private Group group;
// setter and getter 

2. 在Student.hbm.xml中增加many-to-one的属性映射:
<many-to-one name="group" column="`group_id`"/>

3. 修改测试代码,将Group对象加入Student中,运行程序,控制台输出成功信息
...
stud.setGroup(grp);
...

4. 在数据库中,我们发现t_student表多了一个字段group_id,这是外键,引用表t_group的id字段,由此,Hibernate自动实现了对象多对一关系到数据库表关联关系的映射。
六、总结
1. many-to-one属性的相关参数
<many-to-one
        name="propertyName"                                          (1)
        column="column_name"                                         (2)
        class="ClassName"                                            (3)
        cascade="cascade_style"                                      (4)
        fetch="join|select"                                          (5)
        update="true|false"                                          (6)
        insert="true|false"                                          (6)
        property-ref="propertyNameFromAssociatedClass"               (7)
        access="field|property|ClassName"                            (8)
        unique="true|false"                                          (9)
        not-null="true|false"                                        (10)
        optimistic-lock="true|false"                                 (11)
        lazy="proxy|no-proxy|false"                                  (12)
        not-found="ignore|exception"                                 (13)
        entity-name="EntityName"                                     (14)
        formula="arbitrary SQL expression"                           (15)
        node="element-name|@attribute-name|element/@attribute|."
        embed-xml="true|false"
        index="index_name"
        unique_key="unique_key_id"
        foreign-key="foreign_key_name"
/>

解释如下:
(1). name: the name of the property.
(2). column (optional): the name of the foreign key column. This can also be specified by nested <column> element(s).
(3). class (optional - defaults to the property type determined by reflection): the name of the associated class.
(4). cascade (optional): specifies which operations should be cascaded from the parent object to the associated object.
(5). fetch (optional - defaults to select): chooses between outer-join fetching or sequential select fetching.
(6). update, insert (optional - defaults to true): specifies that the mapped columns should be included in SQL UPDATE and/or INSERT statements. Setting both to false allows a pure "derived" association whose value is initialized from another property that maps to the same column(s), or by a trigger or other application.
(7). property-ref (optional): the name of a property of the associated class that is joined to this foreign key. If not specified, the primary key of the associated class is used.
(8). access (optional - defaults to property): the strategy Hibernate uses for accessing the property value.
(9). unique (optional): enables the DDL generation of a unique constraint for the foreign-key column. By allowing this to be the target of a property-ref, you can make the association multiplicity one-to-one.
(10). not-null (optional): enables the DDL generation of a nullability constraint for the foreign key columns.
(11). optimistic-lock (optional - defaults to true): specifies that updates to this property do or do not require acquisition of the optimistic lock. In other words, it determines if a version increment should occur when this property is dirty.
(12). lazy (optional - defaults to proxy): by default, single point associations are proxied. lazy="no-proxy" specifies that the property should be fetched lazily when the instance variable is first accessed. This requires build-time bytecode instrumentation. lazy="false" specifies that the association will always be eagerly fetched.
(13). not-found (optional - defaults to exception): specifies how foreign keys that reference missing rows will be handled. ignore will treat a missing row as a null association.
(14). entity-name (optional): the entity name of the associated class.
(15). formula (optional): an SQL expression that defines the value for a computed foreign key.
参考文档:http://docs.jboss.org/hibernate/core/3.3/reference/en/html/mapping.html#mapping-declaration-manytoone
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics