hibernate系列(四)一对一关联关系

[size=medium]以Person类和IDCard类为例,这里仅仅说一种一对一关联关系,即Person类拥有IDCard,但是IDCard不含Person类,数据库库的表如下:[/size]

CREATE TABLE `hibernate`.`person` (
`id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(45) NULL,
`age` INT NULL,
`idcard_id` INT NULL,
PRIMARY KEY (`id`));


CREATE TABLE `hibernate`.`idcard` (
`id` INT NOT NULL AUTO_INCREMENT,
`number` INT NULL,
`content` VARCHAR(45) NULL,
PRIMARY KEY (`id`));

[size=medium]Person类如下:[/size]

public class Person {

private Long id;
private String name;
private Long age;
private IDCard idCard;
//省略get、set方法
}

[size=medium]Person类对应的Person.hbm.xml映射文件为:[/size]

<hibernate-mapping>
<class name="com.ligang.domain.Person" table="person">
<id name="id" column="id" type="long">
<generator class="identity"/>
</id>
<property name="name" column="name" type="string"/>
<property name="age" column="age" type="long"/>
<many-to-one name="idCard" class="com.ligang.domain.IDCard" column="idcard_id" cascade="save-update"></many-to-one>
</class>
</hibernate-mapping>

[size=medium]虽然是一对一但是,这种形式的一对一就是多对一的特例,所以仍然使用<many-to-one>的标签,其中的name指的是Person类的idCard属性,column指的是person表中的字段名为idcard_id,class指的是将IDCard类对应的表的主键的值作为idcard_id的值。cascade字段表示保存Person类时级联的保存IDCard类。
下面看下IDCard类:[/size]

public class IDCard {

private Long id;
private Long number;
private String content;
//省略get、set方法
}

[size=medium]IDCard类对应的IDCard.hbm.xml映射文件为:[/size]

<hibernate-mapping>
<class name="com.ligang.domain.IDCard" table="idcard">
<id name="id" column="id" type="long">
<generator class="identity"/>
</id>
<property name="number" column="number" type="long"/>
<property name="content" column="content" type="string"/>
</class>
</hibernate-mapping>

[size=medium]然后就是测试增添方法:[/size]

@Test
public void addPerson(){
Session session=hibernateDao.getSession();
Transaction tx=session.beginTransaction();

Person p=new Person();
p.setName("张三");
p.setAge(122L);

IDCard idCard=new IDCard();
idCard.setNumber(123445L);
idCard.setContent("你是一个人");

p.setIdCard(idCard);

session.save(p);

tx.commit();
session.close();
}

[size=medium]此时就会先保存IDCard对象,然后获取其主键并赋值给person表的idcard_id字段,然后增添Person对象。如下sql:[/size]

Hibernate: insert into hibernate.idcard (number, content) values (?, ?)
Hibernate: insert into hibernate.person (name, age, idcard_id) values (?, ?, ?)

[size=medium]更新如下:[/size]

@Test
public void updatePerson(){
Session session=hibernateDao.getSession();
Transaction tx=session.beginTransaction();

Person p=(Person) session.get(Person.class,6L);
p.setName("张三");
p.setAge(122L);

IDCard idCard=new IDCard();
idCard.setNumber(123445L);
idCard.setContent("你是一个人");

p.setIdCard(idCard);

session.save(p);

tx.commit();
session.close();
}

[size=medium]此时的sql如下:[/size]

Hibernate: select person0_.id as id1_3_0_, person0_.name as name2_3_0_, person0_.age as age3_3_0_, person0_.idcard_id as idcard_i4_3_0_ from hibernate.person person0_ where person0_.id=?
Hibernate: insert into hibernate.idcard (number, content) values (?, ?)
Hibernate: update hibernate.person set name=?, age=?, idcard_id=? where id=?

[size=medium]此时并没有删除原有的IDCard,只是根据Person再也找不到它了。目前我还不知道怎么设置来删除无用的IDCard。

获取:由Person的主键获取IDCard比较容易,但是如果想从IDCard主键获取Person呢?
首先更改IDCard类,添加person属性:[/size]

public class IDCard {

private Long id;
private Long number;
private String content;
private Person person;
//略get、set方法
}

[size=medium]然后更改上述的IDCard.hbm.xml映射文件如下:[/size]

<hibernate-mapping>
<class name="com.ligang.domain.IDCard" table="idcard">
<id name="id" column="id" type="long">
<generator class="identity"/>
</id>
<property name="number" column="number" type="long"/>
<property name="content" column="content" type="string"/>
<one-to-one name="person" property-ref="idCard"></one-to-one>
</class>
</hibernate-mapping>

[size=medium]添加了<one-to-one>标签,同时使用了property-ref属性,看下查询再解释:[/size]

@Test
public void getPerson(){
Session session=hibernateDao.getSession();
Transaction tx=session.beginTransaction();

IDCard idCard=(IDCard) session.get(IDCard.class,2L);
System.out.println(idCard.getPerson().getName());

tx.commit();
session.close();
}

[size=medium]查询的sql如下:[/size]

Hibernate: select idcard0_.id as id1_1_0_, idcard0_.number as number2_1_0_, idcard0_.content as content3_1_0_, person1_.id as id1_3_1_, person1_.name as name2_3_1_, person1_.age as age3_3_1_, person1_.idcard_id as idcard_i4_3_1_ from hibernate.idcard idcard0_ left outer join hibernate.person person1_ on idcard0_.id=person1_.idcard_id where idcard0_.id=?
张三

[size=medium]将Person查出来了,然后看下他是怎么查的,看下IDCard的<one-to-one name="person" property-ref="idCard">,name指的是IDCard的person属性,而property-ref指向了另一个类的属性,这里就是Person类的idCard属性,要想查出Person总要告诉hibernate idcard表的哪个字段和person表的哪个字段相连接吧,这里的property-ref="idCard",即指定了要和Person类的idCard属性所对应的字段相连接,默认是采用主键来和该字段相连接的,我不知道能否指定。即idcard表的主键id和Person类的idCard属性对应的字段idcard_id相连接,来查询Person,看sql语句:hibernate.idcard idcard0_ left outer join hibernate.person person1_ on idcard0_.id=person1_.idcard_id

上述一对一的关联关系是通过外键来连接,他们也可以使用相同的主键实现一对一。这里不再讲述。

若想转载请注明出处: [url]http://lgbolgger.iteye.com/blog/2125020[/url]
作者:iteye的乒乓狂魔[/size]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值