【SSH快速进阶】——Hibernate一对一映射(one-to-one)——唯一外键关联

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huyuyang6688/article/details/50253847

  接着上篇文章,唯一外键关联,就是给一对一关联关系中某个对象加一个外键。比如这里给t_person表添加一个外键,指向t_idcard的主键,并且规定t_person中的外键idCard唯一,也可以达到一对一映射的效果。

一对一单向关联映射


  Po对象:

  IdCard .java

public class IdCard {
    private int id;
    private String cardNo;  
    //getter、setter
}

  Person.java

public class Person {
    private int id;
    private String name;
    private IdCard idCard;
    //getter、setter
}

  映射文件:

  IdCard.hbm.xml

<hibernate-mapping package="org.hibernate.test" >
    <class name="com.danny.hibernate.IdCard" table="t_idCard">
        <id name="id">
            <generator class="native"/>
        </id>
        <property name="cardNo"/>
    </class>
</hibernate-mapping>

  Person.hbm.xml

<hibernate-mapping package="org.hibernate.test" >
    <class name="com.danny.hibernate.Person" table="t_person">
        <id name="id" type="int">
            <generator class="native">
            </generator>
        </id>
        <property name="name"/>
        <many-to-one name="idCard"  unique="true"/>     
    </class>
</hibernate-mapping>

  与上篇文章中主键关联不同的是,t_person的主键生成策略为 native ,不再以外键形式关联到t_idcard的主键了,而是用<many-to-one>标签重新与t_idcard建立了多对一的关系,这样就会在t_person表中生成一个外键关联到t_idcard的主键,并且unique="true"会对此外键生成唯一约束

  建表时生成的sql语句为:

drop table if exists t_idCard
drop table if exists t_person
create table t_idCard (id integer not null auto_increment, cardNo varchar(255), primary key (id))
create table t_person (id integer not null auto_increment, name varchar(255), idCard integer unique, primary key (id))
alter table t_person add index FK785BED80F7C7B4CE (idCard), add constraint FK785BED80F7C7B4CE foreign key (idCard) references t_idCard (id)

  至此,唯一外键关联就已经配好了,下面进行测试。

插入测试

session.beginTransaction();     
IdCard idCard=new IdCard();
idCard.setCardNo("123456789");
session.save(idCard);           
Person person=new Person();
person.setName("danny");
person.setIdCard(idCard);           
session.save(person);
session.getTransaction().commit();

  由于t_person生成策略为native,跟t_idcard无关,所以在第四行代码中先执行了session.save(idCard),目的是把idCard变为变为transient状态,否则在清理脏数据时会报错:“org.hibernate.TransientObjectException: object references an unsaved transient instance”

  插入的数据如下:

  插入时执行的sql语句:

insert into t_idCard (cardNo) values (?)
insert into t_person (name, idCard) values (?, ?)

查询测试

Person person=(Person)session.load(Person.class, 1);
System.out.println("person的name:"+person.getName());
System.out.println("person的cardNo:"+person.getIdCard().getCardNo());

  实际执行sql语句:

select person0_.id as id0_0_, person0_.name as name0_0_, person0_.idCard as idCard0_0_ from t_person person0_ where person0_.id=?
select idcard0_.id as id1_0_, idcard0_.cardNo as cardNo1_0_ from t_idCard idcard0_ where idcard0_.id=?

  执行结果

person的name:danny
person的cardNo:123456789

一对一双向关联映射


  双向关联和上一篇文章道理一样,也很简单,Person.java和Person.hbm.xml都不用改动,在IdCard中添加一个person属性,配置文件中与t_person的关系为one-to-one。

  Po对象:

  IdCard .java

public class IdCard {
    private int id;
    private String cardNo;  
    private Person person;
    //getter、setter
}

  映射文件:

  IdCard.hbm.xml

<hibernate-mapping package="org.hibernate.test" >
    <class name="com.danny.hibernate.IdCard" table="t_idCard">
        <id name="id">
            <generator class="native"/>
        </id>
        <property name="cardNo"/>
        <one-to-one name="person" property-ref="idCard"/>
    </class>
</hibernate-mapping>

  因为这里配置的实质是一张身份证只对应一位公民,所以用<one-to-one>标签,property-ref="idCard"指t_idcard的主键与t_person中的idCard字段对应。


  唯一外键关联较主键关联映射的好处就是,万一哪天需求变了,这两个对象的关系由一对一变为多对一,那么直接把外键唯一的约束去掉就行。

  而且唯一外键关联其实就是多对一关联的一种特殊情况,下面将会介绍多对一关联的情况。 【 转载请注明出处——胡玉洋《【SSH快速进阶】——Hibernate一对一映射(one-to-one)——唯一外键关联》】

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏java系列博客

oracle 中start with ... connect by prior 子句的用法

1732
来自专栏lgp20151222

ResultSet相关ResultSetMetaData详细

DatabaseMetaData 有关整个数据库的信息:表名、表的索引、数据库产品的名称和版本、数据库支持的操作。 ResultSet 关于某个表的信息或一...

1502
来自专栏杨建荣的学习笔记

pl/sql中的参数模式(r4笔记第54天)

在平时的工作中,可能通过pl/sql传入参数来做一些特定的操作,参数模式一般有In,out.in out这几种 比如dbms_sqltune下的PREPARE_...

3154
来自专栏kevindroid

room的使用-以demo为例

4053
来自专栏杨建荣的学习笔记

简单实用的sql小技巧(第二篇)(r3笔记第86天)

ASCII和CHR 在平时的工作中,可能会在sql或者pl/sql块中嵌入特殊字符,比如空格,回车之类。这个时候可以使用ascii和chr来做字符和ascii码...

3028
来自专栏Danny的专栏

【SSH快速进阶】——Hibernate一对一映射(one-to-one)——主键关联映射

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huyuyang6688/article/...

1512
来自专栏Java进阶之路

IK分词器访问远程词典功能实现

IKAnalyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包。从2006年12月推出1.0版开始,IKAnalyzer已经推出了3个大版本。最...

2602
来自专栏Python

Django---ORM操作大全

前言 Django框架功能齐全自带数据库操作功能,本文主要介绍Django的ORM框架 到目前为止,当我们的程序涉及到数据库相关操作时,我们一般都会这么搞:...

91310
来自专栏更流畅、简洁的软件开发方式

分页控件之分页算法 —— for SQL Server 版。

上两篇随笔: 我的分页控件(未完,待续)——控件件介绍及思路 我自己写的一个分页控件(源码和演示代码)PostBack分页版 for vs2003、SQL ...

2289
来自专栏乐沙弥的世界

PL/SQL 游标变量

    游标变量与游标相似,有其共性,也有其不同点。就其共性来说两者都是指向多行查询的结果集中的当前行。都要经历声明,打开,检索与关闭的过程。所不同的是游标与游...

864

扫码关注云+社区

领取腾讯云代金券