04.Hibernate一对一关联
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了04.Hibernate一对一关联,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含7314字,纯文字阅读大概需要11分钟。
内容图文
前言:本文主要介绍使用Hibernate映射一对一的关联关系的两种方式:使用外键映射、使用主键映射。
1.数据库表的一对一关联关系
本文根据客户信息表(tb_customer)和地址信息表(tb_address)来说明其一对一的关系,每一个客户都有一个家庭住址,而每一个地址都对应一个客户。
(1)使用外键映射的数据库表说明
数据库表模型图如下:
数据库建表语句如下:
CREATE TABLE tb_customer
(
id bigint NOT NULL auto_increment COMMENT ‘ID‘ ,
name varchar ( 50 ) NOT NULL COMMENT ‘客户名称‘ ,
home_address bigint COMMENT ‘客户家庭地址‘ ,
PRIMARY KEY ( id )
) COMMENT = ‘客户信息表‘ ;
CREATE TABLE tb_address
(
id bigint NOT NULL auto_increment COMMENT ‘ID‘ ,
zipcode varchar ( 50 ) NOT NULL COMMENT ‘邮政编码‘ ,
address varchar ( 200 ) NOT NULL COMMENT ‘地址‘ ,
PRIMARY KEY ( id )
) COMMENT = ‘地址信息表‘ ;
-- 可选的外键约束
ALTER TABLE tb_customer ADD CONSTRAINT fk_tb_customer_tb_address_1 FOREIGN KEY ( home_address ) REFERENCES tb_address ( id );
(2)使用主键映射的数据库表关系
数据库表模型图如下:
数据库建表语句如下:
CREATE TABLE tb_customer
(
id bigint NOT NULL auto_increment COMMENT ‘ID‘ ,
name varchar ( 50 ) NOT NULL COMMENT ‘客户名称‘ ,
PRIMARY KEY ( id )
) COMMENT = ‘客户信息表‘ ;
CREATE TABLE tb_address
(
id bigint NOT NULL auto_increment COMMENT ‘ID‘ ,
zipcode varchar ( 50 ) NOT NULL COMMENT ‘邮政编码‘ ,
address varchar ( 200 ) NOT NULL COMMENT ‘地址‘ ,
PRIMARY KEY ( id )
) COMMENT = ‘地址信息表‘ ;
-- 可选的外键约束
- ALTER TABLE tb_address ADD CONSTRAINT fk_tb_address_tb_customer_1 FOREIGN KEY (id) REFERENCES tb_customer (id);
(3)编写实体类如下
虽然使用外键关联与使用主键关联在数据库层面上表结构不同,但是对于实体类来说这种关联关系是一样的,所以实体类是一样的,代码如下:
package model ;
public class Address
{
private Long id ;
private String zipcode ;
private String address ;
private Customer customer ;
@Override
public String toString ()
{
return "Address [, zipcode=" + zipcode + ", address=" + address + ", customer=" + customer . getName () + "]" ;
}
// 省略setter、getter...
}
package model ;
public class Customer
{
private Long id ;
private String name ;
private Address homeAddress ;
@Override
public String toString ()
{
return "Customer [, name=" + name + ", homeAddress=" + homeAddress . getAddress () + "]" ;
}
// 省略setter、getter...
}
注意:这里的toString()方法只输出实体类的基本属性,如:", homeAddress="+ homeAddress.getAddress(),而不输出整个实体类(", homeAddress="+ homeAddress),是因为这样做很容易造成循环输出,形成死循环!
2.按照外键映射一对一关联
使用外键映射一对一关联需要使用many-to-one元素和one-to-one元素,并且在外键方使用many-to-one元素配置外键。配置如下:
<hibernate-mapping package = "model" >
<class name = "Address" table = "tb_address" >
<id name = "id" >
<generator class = "native" ></generator>
</id>
<property name = "zipcode" column = "zipcode" />
<property name = "address" column = "address" />
<one-to-one name = "customer" class = "model.Customer" property-ref = "homeAddress" />
</class>
</hibernate-mapping>
<hibernate-mapping package = "model" >
<class name = "Customer" table = "tb_customer" >
<id name = "id" >
<generator class = "native" ></generator>
</id>
<property name = "name" column = "name" />
<many-to-one name = "homeAddress" class = "model.Address" column = "home_address" unique = "true" cascade = "all" />
</class>
</hibernate-mapping>
根据上面配置需要注意一下几点:
- 在外键方使用 many-to-one 元素配置外键,如: <many-to-one column = "home_address" 。
- 在外键参照的主键方要使用one-to-one元素映射关联对象,如:<one-to-onename="customer"class="model.Customer"。
- 在many-to-one元素中要配置unique属性值为true,表明每个Customer对象都有唯一的Address对象关联,形成一对一。
-
在many-to-one元素中建议配置cascade属性值为all,表明保存、更新、删除Customer对象会级联操作Address对象。
- 在one-to-one元素中要配置property-ref属性值为homeAddress,表明建立了从Customer对象的homeAddress属性到Address对象的关系。
编写如下的测试程序,测试关联关系,程序代码以及打印结果如下:
public static void main ( String [] args )
{
Customer customer ;
Address address ;
Configuration cfg = new Configuration ();
cfg . configure ();
ServiceRegistry sr = new ServiceRegistryBuilder (). applySettings ( cfg . getProperties ()). buildServiceRegistry ();
SessionFactory sf = cfg . buildSessionFactory ( sr );
System . out . println ( "连接数据库" );
Session session = sf . openSession ();
Transaction transaction = session . beginTransaction ();
try
{
customer = new Customer ();
address = new Address ();
customer . setName ( "测试客户01" );
address . setZipcode ( "123456" );
address . setAddress ( "湖北省武汉市" );
customer . setHomeAddress ( address );
address . setCustomer ( customer );
session . save ( customer );
//配置使用了级联保存transaction . commit ();
}
catch ( Exception e )
{
transaction . rollback ();
System . out . println ( "错误:" + e );
}
finally
{
session . close ();
System . out . println ( "关闭数据库" );
}
System . exit ( 0 );
}
连接数据库
Hibernate : insert into tb_address ( zipcode , address ) values (?, ?)
Hibernate : insert into tb_customer ( name , home_address ) values (?, ?)
关闭数据库
注意:由于配置了级联保存,所以调用session.save(customer)时,会保存customer和address两个对象!
3.按照主键映射一对一关联
使用主键映射一对一关联只需要使用one-to-one元素配置,配置如下:
<hibernate-mapping package = "model" >
<class name = "Address" table = "tb_address" >
<id name = "id" >
<generator class = "foreign" >
<param name = "property" > customer </param>
</generator>
</id>
<property name = "zipcode" column = "zipcode" />
<property name = "address" column = "address" />
<one-to-one name = "customer" class = "model.Customer" constrained = "true" />
</class>
</hibernate-mapping>
<hibernate-mapping package = "model" >
<class name = "Customer" table = "tb_customer" >
<id name = "id" >
<generator class = "native" ></generator>
</id>
<property name = "name" column = "name" />
<one-to-one name = "homeAddress" class = "model.Address" cascade = "all" />
</class>
</hibernate-mapping>
对于上面配置需要注意一下几点:
- 在Address对象的映射配置中的one-to-one元素属性constrained="true",表示tb_address表的ID主键同时作为外键参照tb_customer表的ID主键,此时Address对象的OID生成策略必须使用foreign。
- Address主键生成使用了foreign策略,Hibernate就会保证对象与关联的对象共享同一个OID。
-
在Customer对象映射配置文件中建议配置cascade="all",表明保存、更新、删除Customer对象会级联操作Address对象。
再次运行前面的测试程序,控制台输出结果如下:
连接数据库
Hibernate : insert into tb_customer ( name ) values (?)
Hibernate : insert into tb_address ( zipcode , address ) values (?, ?)
关闭数据库
4.相关配置详解
(1)
one-to-one
节点配置详解
<one-to-one name = "PropertyName"
access = "field|property"
class = "ClassName"
property-ref = "PropertyNameFromAssociatedClass"
constrained = "true|false"
formula = "arbitrary SQL expression"
cascade = "all|none|save-update|delete"
fetch = "join|select"
outer-join = "true|false"
foreign-key = "foreign-key"
lazy = "true|false"
embed-xml = "true|false"
entity-name = "EntityName"
node = "element-name" />
如上展示了one-to-one节点常用的配置,是面对其配置进行详细的说明:
- name :实体类属性名。
- access : 默认的实体类属性访问模式,取值为 property 表示访问getter、setter方法间接访问实体类字段, 取值为 field表示直接访问实体类字段(类成员变量)。
- class : 关联的类的名字,默认是通过反射得到属性类型。
- property-ref : 指定关联类的一个属性,这个属性将会和本外键相对应。如果没有指定,会使用对方关联类的主键。
- constrained :表示使用主键关联一对一关系,一张表的主键同时也是外键,参照另一张表的主键。
- formula : 一个SQL表达式,定义了这个计算属性的值,计算属性没有和它对应的数据库字段。
- cascade : 指明哪些操作会从父对象级联到关联的对象。
- fetch : 参数指定了关联对象抓取的方式是select查询还是join查询,默认为select。fetch="join"等同于outer-join="true",fetch="select"等同于 outer-join = "false" 。
- outer-join : 设置Hibernate是否使用外连接获取关联的数据,设置成true可以减少SQL语句的条数。
- foreign-key : 关联的数据库外键名。
- lazy : 是否采用延迟加载策略。
- embed-xml : 如果 embed-xml = "true" ,则对应于被关联实体或值类型的集合的XML树将直接嵌入拥有这些关联的实体的XML树中,默认值为 true 。
- entity-name : Hibernate3新增特性,用于动态模型(Dynamic Model)支持。 Hibernate3允许一个类进行多次映射(前提是映射到不同的表)。
- node: 配置说明。
-------------------------------------------------------------------------------------------------------------------------------
原文:http://www.cnblogs.com/LiZhiW/p/4279005.html
内容总结
以上是互联网集市为您收集整理的04.Hibernate一对一关联全部内容,希望文章能够帮你解决04.Hibernate一对一关联所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。
来源:【匿名】