数据库表关系:一对一/OneToOne
注:一下内容均属于转载引用,如有不适,请联系!谢谢
单边(外键唯一性方式):
--注解方式
@Entity
@Table(name="tb_card") //对应数据库表名
public class Card implements java.io.Serializable { //作为主类,从类正常字段,不包含card对象属性。
private static final long serialVersionUID = 1L;
@Id
@Column
private int id; //主键字段配置
@Column
private Date date;//普通字段配置
@OneToOne(cascade=CascadeType.ALL,fetch=FetchType.LAZY,targetEntity=Person.class) //基本配置
@JoinColumn(name="p_id",nullable=false,updatable=false)//指定一个外键(card表中的外键字段),也可以不指定(默认person_id形式)。
private Person person;
setter/getter省略
引用处:
http://www.cnblogs.com/void-m/p/6658078.html
http://blog.csdn.net/qq_33556185/article/details/51658171
--原始方式
person为主类,IdCard为从类
----------------------------------------------
public class IdCard {
private int id;
private String cardNo;
//。。。
}
IdCard.hbm.xml
//很普通的一个映射文件
<class name="domain1.IdCard" table="idcard">
<id name="id" column="id">
<!-- 主键生成策略 -->
<generator class="native">
</generator>
</id>
<!-- 一些常规属性 -->
<property name="cardNo"></property>
</class>
---------------------------------------------
public class Person {
private int id;
private String name;
private IdCard idCard; //对象成员
//...
}
//Person.hbm.xml
<class name="domain1.Person" table="person">
<id name="id" column="id">
<!-- 主键生成策略 -->
<generator class="native">
</generator>
</id>
<!-- 一些常规属性 -->
<property name="name"></property>
<!--跟多对一一样,只是增加了一个unique属性。这样就指定了这端为一了。
name指定对象成员名, column指定person表中外键字段
-->
<many-to-one name="idCard" column="cardId" unique=true></many-to-one>
</class>
引用处:
***单边(主键关联方式):***
--原始方式
person为主类,IdCard为从类
----------------------------------------
public class IdCard {
private int id;
private String cardNo;
//。。。
}
//IdCard.hbm.xml
//这个没什么好说的,因为是单向一对一,这个就正常写,他不用干什么。
<class name="domain1.IdCard" table="idcard">
<id name="id" column="id">
<!-- 主键生成策略 使用native,需要底层数据库自己设置主键的值哦,比如AUTO_INCREMENT -->
<generator class="native">
</generator>
</id>
<!-- 一些常规属性 -->
<property name="cardNo"></property>
----------------------------------------
public class Person {
private int id;
private String name;
private IdCard idCard;//体现一对一的关系。保存映射类的实例对象。
//。。。
}
//Person.hbm.xml
<hibernate-mapping>
<class name="domain1.Person" table="person">
<id name="id" column="id">
<!-- 重点在这里。主键生成策略 因为主键跟外键是同一个,所以直接在这里申明该主键就是外键,并且指向了idCard这个类 -->
<generator class="foreign">
<param name="property">idCard</param> //指定对象属性名
</generator>
</id>
<!-- 一些常规属性 -->
<property name="name"></property>
<!--由于在申明主键的时候已经将关系写清楚了,所以在这里没有column这个属性。
按平常的习惯,我们会在这里写上column="数据库中外键字段属性名称。"-->
<!--constrained属性:就是表明我们的主键当外键使用了。 这个属性两个作用,一是通知这种对应关系在上面已经写过了,所以这里才不需要写column,二是表明这种关系是什么,也就是主键当外键。
其实还有一个级联关系的作用。-->
<one-to-one name="idCard" constrained="true" cascade="all" ></one-to-one>
</class>
引用出:
http://www.cnblogs.com/greatfish/p/6239098.html?utm_source=itdadao&utm_medium=referral
http://www.cnblogs.com/whgk/p/6128395.html
-------------------------------------------------
--注解方式:暂时无
双边(外键唯一性方式):
--原始方式
public class Wife implements java.io.Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
private String name;
private Husband husband;
public class Husband implements java.io.Serializable {
private static final long serialVersionUID = 1L;
private Integer id;
private Wife wife;
private String name;
注:一对一双向关联比较特殊,不像单向关联,在hbm配置文件中仅仅使用one-to-one配置即可,这种情况下需要使用may-to-one和one-to-one来模拟一一对应,
既然是一一对应,所以在many-to-one的一段,要加上unique=true属性,从而保证其唯一性。这是Hibernate的机制吧,从项目经验来看,如果不这么做,
在同时修改了这两个实体,然后保存到库中时,总是报错,错误信息为session无法同步,或者外键id为NULL。使用了这样的配置后,就没有问题了。
配置:
Wife.hbm.xml
7. <hibernate-mapping>
8. <class name="com.linys.model.Wife" table="wife">
9. <id name="id" type="java.lang.Integer">
10. <column name="id" />
11. <generator class="native" />
12. </id>
13. <property name="name" type="java.lang.String">
14. <column name="name" length="50" not-null="true" />
15. </property>
16. <one-to-one name="husband" class="com.linys.model.Husband" property-ref="wife" cascade="all"/>
17. </class>
18. </hibernate-mapping>
Husband.hbm.xml:
7. <hibernate-mapping>
8. <class name="com.linys.model.Husband" table="husband">
9. <id name="id" type="java.lang.Integer">
10. <column name="id" />
11. <generator class="native" />
12. </id>
13. <property name="name" type="java.lang.String">
14. <column name="name" length="50" not-null="true" />
15. </property>
16. <may-to-one name="wife" class="com.linys.model.Wife" fetch="select"/>
17. <column name="wifeid" unique="true" not-null="true" />
18. </many-to-one>
19. </class>
20. </hibernate-mapping>
注:外键所依赖的那个表的配置文件(wife)使用one-to-one,外键所在的表(husband)用many-to-one,但是要指定unique为true从而保证其唯一性。
注意many这一端中的colum,配置的应该是外键所在表的外键列名,对应这里也就是husband表中的“wifeid”,需要与数据库中的数据表表中一致,切勿弄错。
one-to-one:指定在Wife这个类中用于双向关联的属性husbandproperty-ref: 在关联对象中用于与本对象关联的属性。注意:property-ref="wife"不能少,
否则会造成查询时关联查询失败!
引用处:
http://blog.csdn.net/sheen1991/article/details/41907385
http://blog.csdn.net/jialinqiang/article/details/8709275
--注解方式
@Entity
public class IdCard {
private String cardNo;
@Id
@GeneratedValue
private int id;
@OneToOne(mappedBy="idCard")
private Person person;
//setter、getter略
}
@Entity
public class Person {
private IdCard idCard;//引用IdCard对象
private String name;
@Id
@GeneratedValue
private int id;
@OneToOne
@JoinColumn(name="idCard") //为idCard对象指定外键
private IdCard idCard; //引用IdCard对象
private String name;
//setter、getter略
}
引用处:
http://blog.csdn.net/yyywyr/article/details/23620611
http://blog.csdn.net/u012152619/article/details/44095157
http://www.cnblogs.com/ShawnYuki/p/6363547.html
双 边(主键关联方式):
--注解方式
-----------------------------------
主键主控方:Article
@Table(name = "t_article2")
@Entity
public class Article {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
private String title;
@OneToOne(cascade = CascadeType.ALL,fetch = FetchType.LAZY,optional = false)
@PrimaryKeyJoinColumn//配置共享主键,否则会额外生成外键关联列
private ArticleContent articleContent;
//忽略get 和set方法
}
------------------------------------
引用主键方:ArticleContent。这是共享主键关联的关键配置地方所在类
@Table(name = "t_article_content")
@Entity
public class ArticleContent {
@Id
@GenericGenerator(name = "foreignKey" ,//生成器名称
strategy = "foreign",//使用hibernate的外键策略
parameters = @Parameter(value = "article",name = "property"))//指定成员属性中的article所在类的主键为本类的主键,这里的参数属性name必须为"property"
@GeneratedValue(generator = "foreignKey")//使用上述定义的id生成器
private Integer id;
@Lob
private String content;
//如果试图不加此注解来形成单向关联,会抛出异常,
//因为设置了共享主键这里是否配置mapperBy放弃维护关联关系已失去作用。
@OneToOne(cascade = CascadeType.ALL)
@PrimaryKeyJoinColumn//如果不加此注解,hibernate会在数据库默认生成一条article_id属性
private Article article;
//忽略get 和set方法
引用处:
http://blog.csdn.net/qwe6112071/article/details/51111174
http://blog.csdn.net/u012152619/article/details/44095157
–原始方式
直接看大牛博客,引用处:
http://www.cnblogs.com/whgk/p/6128395.html
http://www.cnblogs.com/hellokitty1/p/5050172.html
注意点:
引用出处:
http://www.blogjava.net/fancydeepin/archive/2012/10/13/hibernate_annotation_unidirectional_onetoone.html
http://www.blogjava.net/fancydeepin/archive/2012/10/13/hibernate_annotation_unidirectional_onetoone.html