十、一对一

四、一对一

 

一对一分为,基于主键的一对一,和基于外键的一对一。

基于主键的一对一,指的是,idCard表的主键就是外键,它的值参考person表的id,而不需要重新生成一个字段来记录到底这个idCard是指向哪个person的。

而基于外键的一对一,指的是,personid我们自定,idCardid我们也自定。我们要根据用户的代码idCard.setPerson(),在idCard表中新增成一个字段person,来记录到底这个idCard是属于哪个person的。

 

1.基于主键的一对一

 

 

基于主键的一对一:

person表中,person_id是主键,在IdCard表中,card_id不仅是主键,也是外键--它的值是复制Person_id的。

 

①创建domain

 

 

 

②创建(domain).hbm.xml

<hibernate-mapping package="com.myz.domain">

<class name="Person" table="person">

<id name="id" type="java.lang.Integer">

<!-- 手动分配id号 -->

<generator class="assigned"></generator>

</id>

<property name="name" type="java.lang.String">

<column name="name" length="64"></column>

</property>

 

<!-- 配置person和idCard属性是一对一的关系 -->

<one-to-one name="idCard"></one-to-one>

</class>

</hibernate-mapping>

 

 

<hibernate-mapping package="com.myz.domain">

<class name="IdCard" table="idCard">

<id name="id" type="java.lang.Integer">

<!-- 因为我们这里是基于主键的一对一,说明Idcard的主键是依赖于Person的id的,所以这个主键既是主键,又是外键 -->

<generator class="foreign">

<!-- 这里的person指的是跟哪个属性一对一 -->

<param name="property">person</param>

</generator>

</id>

<property name="cardtime" type="java.util.Date">

<column name="cardtime" length="64"></column>

</property>

 

<!-- 配置IdCard和person属性是一对一的关系 -->

<one-to-one name="person"></one-to-one>

</class>

</hibernate-mapping>

 

 

③关系详解

 

 

④创建hibernate.hbm.xml,并让hibernate帮我们创建数据库

<session-factory>

<property name="dialect">

org.hibernate.dialect.MySQLDialect

</property>

<property name="connection.url">

jdbc:mysql://localhost:3306/test1

</property>

<property name="connection.username">root</property>

<property name="connection.password">123456</property>

<property name="connection.driver_class">com.mysql.jdbc.Driver</property>

<property name="myeclipse.connection.profile">mysql</property>

<property name="show_sql">true</property>

<property name="hbm2ddl.auto">update</property>

 

<mapping resource="com/myz/domain/Person.hbm.xml" />

<mapping resource="com/myz/domain/IdCard.hbm.xml" />

 

</session-factory>

 

⑤测试

session=HibernateUtil.getCurrentSession();

ts=session.beginTransaction();

 

Person p1=new Person();

p1.setId(1);

p1.setName("孙悟空");

IdCard idCard=new IdCard();

idCard.setCardtime(new Date());

 

//表示这个idCard这个对象是属于p1这个对象的

//因为先有person再有idCard,后有的对象设置属性值为先有的对象

idCard.setPerson(p1);

 

//先有人再有idcard,保存也是先保存先有的对象

session.save(p1);

session.save(idCard);

 

ts.commit();

 

这时数据库虽然有person表和idCard表,而且idCard表主键确实也根据person主键确定,但是idCard表却没有外键,idCardid应该既是主键又是外键才对,这是因为我们没有让hibernate帮我们自动生成外键,在Idcard.hbm.xml处修改:

<one-to-one name="person" constrained="true"></one-to-one>

constrained默认为false,表示不生成外键

此时再执行操作,发现idcard表生成了外键。跟person表的主键相对应。

总结:

配置domain.hbm.xml的时候 ,一个属性一个属性往下配,如果是主键就写到<id>里去,如果是普通属性就写到<property>里去,如果是对象属性就写到一对一里去。哪个值需要参考别的表的值,生成策略就是foreign。哪个表需要生成外键,就在一对一里写上constrained="true"

 

2.基于外键的一对一

 

与基于主键的一对一不同的是,虽然domain结构一样,我们想自己给idCard指定id,而让它给我们自动生成一个实实在在的外键person,指向personid

 

①创建domain对象

②创建Person.hbm.xml

③创建idCard.hbm.xml

<class name="IDCard" table="sqlIDCard">

<id name="cardId" type="java.lang.Integer">

<column name="sqlCardId"></column>

<generator class="assigned">

</generator>

</id>

 

<property name="cardTime" type="java.util.Date">

<column name="sqlCardTime"></column>

</property>

//由于多个外键可以指向同一个主键,所以是many-to-one

//由于一张身份证只能归一人持有,所以需要添加unique,防止多个外键指向同一个主键

//所以即使这个是一对一的关系,我们还是使用many-to-one

<many-to-one name="person" unique="true"></many-to-one>

</class>

 

④测试

public static void main(String[] args) {

// TODO Auto-generated method stub

Session session=null;

Transaction ts=null;

try {

session=HibernateUtil.getCurrentSession();

ts=session.beginTransaction();

 

Person p1=new Person();

p1.setPersonId(8);

p1.setPersonName("jack");

IDCard idCard=new IDCard();

idCard.setCardId(101);

idCard.setCardTime(new Date());

idCard.setPerson(p1);

 

session.save(idCard);

session.save(p1);

 

 

ts.commit();

} catch (Exception e) {

// TODO: handle exception

e.printStackTrace();

ts.rollback();

}finally{

if(ts.isActive()) ts=null;

if(session.isOpen()) session.close();

}

}

 

 

⑤查看mysql

IdCard表总共有三个字段,idnameperson。系统自动生成了一个字段,person。是外键,它指向person表的id

posted @ 2018-02-07 09:08  菜鸡蔡文姬  阅读(167)  评论(0编辑  收藏  举报