关闭

hibernate进阶之路之一对一映射(二)

115人阅读 评论(1) 收藏 举报

        上篇博客简单介绍了hibernate,并实现了一个基本映射,本篇博客将更加详细介绍映射相关内容。本文介绍一对一映射。一对一关联有两种策略:1、主键和主键关联;2、唯一外键关联,其实是多对一关联,但是把多的一端的外键设置成唯一;

        1、主键主键关联:明确需求,创建实体:

        一个用户只能有一个身份证号,那么user和idCard就是一对一关联,

        首先看主键和主键关联,在user端维护关系,创建两个实体:

        user:

public class User{

	private int id;
	
	private String name;
	
	private IdCard idCard;//idCard的引用
       
         //省略getter、setter

}
       idCard:

public class IdCard {
	
	private int id;
	
	private String cardNo;

        //省略getter、setter
}

        2、创建实体映射文件(全局配置文件在上篇博客已经介绍到,实体映射文件写好之后,加到全局配置文件的mapping标签中):

         idCard.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>
	<class name="com.tgb.hibernate.IdCard" table="t_idCard">
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="cardNo"/>
	</class>
</hibernate-mapping>
        User.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>
	<class name="com.tgb.hibernate.User" table="t_user">
		<id name="id">
			<!-- foreign表示一对一共享主键,两个id值一样, -->
			<generator class="foreign">
				<param name="property">idCard</param>
			</generator>
		</id>
		<property name="name"/>
		<!-- 
			constrained=true,则表明存在外键与关联表对应,并且关联表中肯定存在对应的键与其对应
		 -->
		<one-to-one name="idCard" constrained="true"/>
	</class>
</hibernate-mapping>

constrained="true",表示User的主键同时是个外键,会生成外键约束语句,这样的单项关联时,如果是false不会使用lazy,会采用left join的方式查出来,true则是延迟加载。而且true的时候save和delete的顺序也是固定的了。save时先增加关联表,delete相反。

        如果是双向关联,则需要在idCard的映射文件中,添加<one-to-one/>标签,关联User。

3、生成数据库表:

         t_idcard:

               

        t_user:

        

t_user表中没有外键约束。

4、测试类:

(简写,只写了逻辑代码):

</pre><p><pre name="code" class="java">	session.beginTransaction();
			
	IdCard idCard = new IdCard();
	idCard.setCardNo("1304545453453");
			
	User user = new Person();
        
        user.setName("张三");
	
 	//建立关联user.setIdCard(idCard);
	session.save(user);
	session.getTransaction().commit();


这样就在t_user和t_idCard表分别保存了一条记录,而且两个id是一样的。

        二、唯一外键关联方法:

        单向关联:

User.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>
	<class name="com.tgb.hibernate.User" table="t_user">
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="name"/>
		<many-to-one name="idCard" unique="true"/>
	</class>
</hibernate-mapping>
注意使用的是many-to-one标签,而且必须使用unique="true"来限制,表示唯一性。

idCard.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>
	<class name="com.tgb.hibernate.IdCard" table="t_idCard">
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="cardNo"/>
	</class>
</hibernate-mapping>
生成的数据库表(有了外键约束):

t_user:


测试就不再写了,要注意的是重点关注映射文件。

       

        双向关联:

        必须在上面的idCard.hbm.xml中添加:<one-to-one name="person" property-ref="idCard"/>

property-ref="idCard"指定了关系字段的名称。

  

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:84192次
    • 积分:2888
    • 等级:
    • 排名:第12342名
    • 原创:116篇
    • 转载:0篇
    • 译文:0篇
    • 评论:656条
    最新评论