14基于外键双向一对一的关联映射
- 格式:doc
- 大小:51.00 KB
- 文档页数:4
【注解】hibernate关系映射级别注解关系映射级别注解一对一单向外键@OneToOne(cascade=CascadeType.ALL)@JoinColumn(name="pid",unique=true)注意:保存时应该先保存外键对象,再保存主表对象。
在主控方的外键对象上进行配置,@JoinColumn中配置的是外键的对应信息。
主控方:被控方:测试方法:一对一双向外键主控方的配置同一对一单向外键关联@OneToOne(mappedBy="card") //被控方双向关联,被控方必须设置mappedBy属性。
因为双向关联只能交给一方去控制,不可能在双方都设置外键保存关联关系,否则双方都无法保存。
主控方:被控方:测试方法:加深理解:一对一单向外键联合主键创建主键类主键类必须实现serializable接口,重写hashCode()和equals()方法主键类@Embeddable实体类@EmbeddedId测试方法:多对一单向外键多方持有一方的引用,比如:多个学生对应一个班级(多对一)@ManyToOne(cascade={CascadeType.ALL},fetch=FetchType.EAGER)@JoinColumn(name="dept_id",referencedColumnName="uuid")@JoinColumn中配置的是一方的对应信息。
示例中相当于在UserTest的dept_id列上添加了外键约束 参考的是classroom的uuid列多方:一方:测试方法:一对多单向外键一方持有多方的集合,一个班级有多个学生(一对多)。
@OneToMany(cascade={CascadeType.ALL},fetch=ZY) @JoinColumn(name="cid")一方:多方:测试方法:总结:多对一时候,多方设置EAGER,一方设置LAZY。
多对一关联映射在多的实体类中有一个类类型的属性. 在多的hbm.xml文件中有<many-to-one>标签<many-to-one name="group" column="tgroup" cascade=" all"><many-to-one />会在多的一端加入一个外键指向一的一端.这个外键是由<many-to-one>中的column属性定义的,如果忽略了这个属性那么默认的外键与实体的属性一致外键对应一的一端主键ID的值即: <many-to-one>会在many端表中增加一个字段tgroup 用来存放one端的对应id<many-to-one name="group" column="tgroup" cascade=" save-update">*cascade 表示级联对一个对象执行了操作之后,对其指定的级联对象也执行相同的操作有四种取值none(默认) , all ,save-update ,deletenone:在所有情况下都不执行级联操作,是其默认的属性all:在所有情况下都执行级联操作.save-update: 在存储和更新的时候执行级联操作delete: 在删除的时候执行级联操作一对一关联映射分为主键关联和外键关联主键关联默认是根据id关联的.不会生成多余字段*主键关联(单向关联) 可以根据外键表找到主键表生成的id一样,外键表的id来源于主键的id1.在外键类中配置主键类的类型的成员变量2.在外键类的hbm.xml文件中配置<class name="com.model.Person" table="person"><id name="id"><generator class="foreign"><param name="property">idcard</param></generator></id><property name="name"/><one-to-one name="idcard" constrained="true"></one-to-one></class>其中id的生成策略为foreign 表示值来源于其他主键,来源目标是其类类型属性(idcard)所对应类的主键id值<one-to-one name="idcard" constrained="true"></one-to-one><one-to-one> 默认根据主键(id)加载constrained="true"表示该类的主键(id)参照name配置所对应的类的主键(id).一对一得主键映射关系在保存时只要保存外键对象,会自动保存主键对象*主键关联(双向关联) 可以通过任何一方找到另一方其中一方的主键(id)作为外键参照另外一方的主键(id)主键方:<class name="com.model.IdCard" table="IdCard"><id name="id"><generator class="native"/></id><property name="number"></property><!—配置ONE-TO-ONE--><one-to-one name="person"></one-to-one></class>外键方:<class name="com.model.Person" table="person"><!—配置id生成策略参照idcard对应的类的主键生成策略--><id name="id"><generator class="foreign"><param name="property">idcard</param></generator></id><property name="name"/><!—配置ONE-TO-ONE- -><one-to-one name="idcard" constrained="true"></one-to-one></class>外键关联映射*唯一外键关联(单向) (是many-to-one的一个特例)在外键方会成一个字段来存储主键方的id值并且设置该字段唯一主键方:<class name="com.model.IdCard" table="IdCard"><id name="id"><generator class="native"/></id><property name="number"></property></class>外键方:<class name="com.model.Person" table="person"><id name="id"><generator class="native"/></id><property name="name"/><many-to-one name="idcard" unique="true" cascade="all"></many-to-one> </class> 这里设置该字段唯一*唯一外键关联(双向)在主键方加入<one-to-one name="person" property-ref="idcard"/>property-ref="idcard"属性表示关联外键表的字段,,指定加载方式为使用外键表的外键加载配置实例:主键方:<class name="com.model.IdCard" table="IdCard"><id name="id"><generator class="native"/></id><property name="number"></property><one-to-one name="person" property-ref="idcard"></one-to-one>外键方:<class name="com.model.Person" table="person"><id name="id"><generator class="native"/></id><property name="name"/><many-to-one name="idcard" unique="true"cascade="all"/></class>cascade="all"配置级联。
Hibernate 一对一外键双向关联一对一外键关联是一对多外键关联的特例,只是在多的一方加了个唯一性约束。
一、模型一个人对应一个地址。
/*================================================= =============*//* DBMS name: MySQL *//* Created on: 2008-12-9 0:12:54 *//*================================================= =============*/drop table if exists address;drop table if exists person;/*================================================= =============*//* Table: address *//*================================================= =============*/create table address(id bigint not null auto_increment comment 'ID',detail varchar(120) not null comment '详细地址',personid bigint comment '人的ID',primary key (id))type = InnoDB;alter table address comment '地址';/*================================================= =============*//* Table: person *//*================================================= =============*/create table person(id bigint not null auto_increment comment 'ID',name varchar(24) not null comment '姓名',primary key (id))type = InnoDB;alter table person comment '人';alter table address add constraint FK_Reference_4 foreign key (personid) references person (id) on delete restrict on update restrict;二、对象模型public class Person implements{private Long id;private String name;private Address address;public class Address implements{private Long id;private Person person;private String detail;三、映射文件<?xml version=""encoding="utf-8"?><!DOCTYPE hibernate-mapping PUBLIC "---><hibernate-configuration><session-factory><property name="">root</property><property name="">jdbc:</property><property name="dialect"></property><property name="">xiaohui</property><property name=""></property><property name="show_sql">true</property> <property name="format_sql">true</property> <mapping resource="entity/"/><mapping resource="entity/"/></session-factory></hibernate-configuration>四、测试importimport;import;import;public class Test {public static void main(String[] args) {savePerson();}public static void savePerson() {Person person = new Person("张三");Address address = new Address("XX街X号"); (address);(person);Session session = ();Transaction tx = ();(person);();}}运行日记:Hibernate:insertintoperson(name)values(?)Hibernate:insertinto(detail, personid) values(?, ?)。
Mybatis中的⾼级映射⼀对⼀、⼀对多、多对多学习hibernate的时候,⼩编已经接触多各种映射,mybatis中映射有到底是如何运转的,今天这篇博⽂,⼩编主要来简单的介绍⼀下mybatis中的⾼级映射,包括⼀对⼀、⼀对多、多对多,希望多有需要的⼩伙伴有帮助,⼩编主要从四个⽅⾯进⾏介绍,订单商品数据模型、⼀对⼀查询、⼀对多查询、多对多查询。
⼀、订单商品数据模型1、数据库执⾏脚本,如下所⽰:<span style="font-family:Comic Sans MS;font-size:18px;">CREATE TABLE items (id INT NOT NULL AUTO_INCREMENT,itemsname VARCHAR(32) NOT NULL COMMENT '商品名称',price FLOAT(10,1) NOT NULL COMMENT '商品定价',detail TEXT COMMENT '商品描述',pic VARCHAR(64) DEFAULT NULL COMMENT '商品图⽚',createtime DATETIME NOT NULL COMMENT '⽣产⽇期',PRIMARY KEY (id)) DEFAULT CHARSET=utf8;/*Table structure for table `orderdetail` */CREATE TABLE orderdetail (id INT NOT NULL AUTO_INCREMENT,orders_id INT NOT NULL COMMENT '订单id',items_id INT NOT NULL COMMENT '商品id',items_num INT DEFAULT NULL COMMENT '商品购买数量',PRIMARY KEY (id),KEY `FK_orderdetail_1` (`orders_id`),KEY `FK_orderdetail_2` (`items_id`),CONSTRAINT `FK_orderdetail_1` FOREIGN KEY (`orders_id`) REFERENCES `orders` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, CONSTRAINT `FK_orderdetail_2` FOREIGN KEY (`items_id`) REFERENCES `items` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION) DEFAULT CHARSET=utf8;/*Table structure for table `orders` */CREATE TABLE orders (id INT NOT NULL AUTO_INCREMENT,user_id INT NOT NULL COMMENT '下单⽤户id',number VARCHAR(30) NOT NULL COMMENT '订单号',createtime DATETIME NOT NULL COMMENT '创建订单时间',note VARCHAR(100) DEFAULT NULL COMMENT '备注',PRIMARY KEY (`id`),KEY `FK_orders_1` (`user_id`),CONSTRAINT `FK_orders_id` FOREIGN KEY (`user_id`) REFERENCES `t_user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION) DEFAULT CHARSET=utf8;/*Table structure for table `t_user` */CREATE TABLE t_user (id INT NOT NULL AUTO_INCREMENT,username VARCHAR(32) NOT NULL COMMENT '⽤户名称',birthday DATE DEFAULT NULL COMMENT '⽣⽇',sex CHAR(1) DEFAULT NULL COMMENT '性别',address VARCHAR(256) DEFAULT NULL COMMENT '地址',PRIMARY KEY (`id`)) DEFAULT CHARSET=utf8;</span>测试数据代码<span style="font-family:Comic Sans MS;font-size:18px;">/*Data for the table `items` */INSERT INTO items(itemsname,price,detail,pic,createtime) VALUES('台式机',3000.0,'该电脑质量⾮常好!',NULL,'2015-07-07 13:28:53'),('笔记本',6000.0,'笔记本性能好,质量好!',NULL,'2015-07-08 13:22:57'),('背包',200.0,'名牌背包,容量⼤质量好!',NULL,'2015-07-010 13:25:02');/*Data for the table `orderdetail` */INSERT INTO `orderdetail`(`orders_id`,`items_id`,`items_num`) VALUES(1,1,1),(1,2,3),(2,3,4),(3,2,3);/*Data for the table `orders` */INSERT INTO `orders`(`user_id`,`number`,`createtime`,`note`) VALUES(1,'1000010','2015-06-04 13:22:35',NULL),(1,'1000011','2015-07-08 13:22:41',NULL),(2,'1000012','2015-07-17 14:13:23',NULL),(3,'1000012','2015-07-16 18:13:23',NULL),(4,'1000012','2015-07-15 19:13:23',NULL),(5,'1000012','2015-07-14 17:13:23',NULL),INSERT INTO `t_user`(`username`,`birthday`,`sex`,`address`) VALUES('王五',NULL,'2',NULL),('张三','2014-07-10','1','北京市'),('张⼩明',NULL,'1','河南郑州'),('陈⼩明',NULL,'1','河南郑州'),('张三丰',NULL,'1','河南郑州'),('陈⼩明',NULL,'1','河南郑州'),('王五',NULL,NULL,NULL),('⼩A','2015-06-27','2','北京'),('⼩B','2015-06-27','2','北京'),('⼩C','2015-06-27','1','北京'),('⼩D','2015-06-27','2','北京');</span>2、数据模型分析思路(1).每张表记录的数据内容:分模块对每张表记录的内容进⾏熟悉,相当于你学习系统需求(功能)的过程;(2).每张表重要的字段设置:⾮空字段、外键字段;(3).数据库级别表与表之间的关系:外键关系;(4).表与表之间的业务关系:在分析表与表之间的业务关系时⼀定要建⽴在某个业务意义基础上去分析。
MyBatis的⼀对⼀关联关系映射1 什么是⼀对⼀、⼀对多映射?以⽤户和订单举例,⼀对⼀ : ⼀个订单只属于⼀个⽤户 ==> 订单对⽤户是⼀对⼀关系⼀对多 : ⼀个⽤户可以拥有多个订单 ==> ⽤户对订单是⼀对多关系注意:在MyBatis中,如果要完成多对多关系,其实就是两个⼀对多映射!接下来先讲解MyBatis的⼀对⼀映射如何实现。
2 建⽴表结构2.1 创建⽤户表CREATE TABLE `t_user` (`id` int(11) DEFAULT NULL,`username` varchar(50) DEFAULT NULL,`password` varchar(50) DEFAULT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf82.2 创建订单表CREATE TABLE `t_order` (`id` int(11) DEFAULT NULL,`orderno` varchar(100) DEFAULT NULL,`amount` double DEFAULT NULL,`user_id` int(11) DEFAULT NULL) ENGINE=InnoDB DEFAULT CHARSET=utf82.3 插⼊测试数据3 设计Pojo实体,建⽴关系3.1 ⽤户实体类package com.yiidian.domain;import java.util.List;/*** ⽤户实体* ⼀点教程⽹ - */public class User {private Integer id;private String username;public void setOrders(List<Order> orders) {this.orders = orders;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {ername = username;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}}3.2 订单实体类package com.yiidian.domain;/*** 订单实体* ⼀点教程⽹ - */public class Order {private Integer id;private String orderno;private Double amount;private User user;public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getOrderno() {return orderno;}public void setOrderno(String orderno) {this.orderno = orderno;}public Double getAmount() {return amount;}public void setAmount(Double amount) {this.amount = amount;}public User getUser() {return user;}public void setUser(User user) {er = user;}}Order实体类,通过user属性建⽴跟User实体的关系。
第一章测试1.下列哪些服务器是支持Java EE架构的?A:WebLogicB:GlassFishC:JbossD:IIS答案:ABC2.可响应HTTP请求的Servlet和JSP一般运行在JavaEE框架的哪个容器中?A:Web容器B:Applet容器C:EJB容器D:Application Client容器答案:A3.JavaEE框架中的常用技术里,用于进行名字和目录服务的技术是?A:RMIB:JSPC:JDBCD:JNDI答案:D4.JavaEE框架中的常用技术里,用于和面向消息的中间件相互通信的应用程序接口是?A:JMSB:ServletC:JavaMailD:JSP答案:A5.Jboss安装完成后,默认只能本地访问,不能通过外网进行访问。
A:对B:错答案:A第二章测试1.HttpServlet抽象类中,用来响应HTTP GET请求方法是?A:doPostB:doGetC:doDeleteD:doPut答案:B2.用标注来对Servlet类进行配置,说明该类是一个Servlet类,并定义其访问路径,所使用的标注是?A:@WebInitParamB:@WebServletC:@ManagedBeanD:@MultipartConfig答案:B3.Servlet监听器若想对session对象的创建和销毁进行监听,需要实现的接口是?A:ServeltRequestListenerB:ServletContextListenerC:HttpSessionListenerD:HttpSessionAttributeListener答案:C4.Servlet的初始化参数是什么类型的?A:ServletConfigB:GenericServletC:HttpServletD:ServletContext答案:A5.下列哪一个方法用于设置HttpServletResponse的内容类型A:setAttributeB:setParameterC:setContentTypeD:encodeURL答案:C第三章测试1.以下哪个jsp隐含对象可以实现在多次请求中共享数据?A:sessionB:requestC:pageContextD:page答案:A2.JSP页面在服务器上被执行之前,将首先被转译成?A:htmlB:jsp指令C:javascriptD:servlet答案:D3.在JSP中,哪个JSP动作可用于将请求转发给其他JSP页面?A:jsp:setPropertyB:jsp:includeC:jsp:useBeanD:jsp:forward答案:D4.在JSP中如果要导入java.util.*包,要使用什么指令?A:includeB:pageC:forwardD:taglib答案:B5.创建JSP应用程序时,配置文件web.xml应该在程序下的哪个目录中。
hibernate关联映射详解一对多关系 1.一对多关系(单向):在一端映射文件中加入:name= student keyumn= classes / one-to-many > /set 2.一对多关系(双向):(1).在一端映射文件中加入: setname= student keycolumn= classesid / one-to-many > /set (2).在多的一端加入: many-to-onename= classes column=classesid /many-to-one 多对一关系在多的一端加入:many-to-one name= classes column= classesid / 一对一关系 1. 一对一外键关联单向:(它其实就是一个多对一映射的一个特例,只是设置ue=”ue”)在维护关系一端的映射文件中加入:many-to-onename= card unique= true cascade= all /many-to-one 双向:在维护关系一端的映射文件中加入: many-to-onename= card unique= true cascade= all /many-to-one 在另一段的映射文件中加入: one-to-onename= users property-ref= card /one-to-one 因为 one-to-one name 标签默认是找关联主键,所以在这里需要property-ref= card 配置关联属性。
Cascade属性是级联的意思。
2. 一对一主键关联 a) 单向在维持关系一端的代码: classname= er_pk idname= id generator > paramname= property card_pk /param /generator /id propertyname= name unique= true /property one-to-onename= card_pk constrain= true /one-to-one /class 设置generator > constrained= true 设置该实体的主键是card_p的外键。
目录1.1 在Web应用中使用Hibernate技术----关联映射(MySQL) (2)1.1.1 一对一关联的实现方案 (2)1.1.2 设计示例中的相关数据库表 (5)1.1.3 采用JUnit单元测试实现 (25)1.1在Web应用中使用Hibernate技术----关联映射(MySQL)1.1.1一对一关联的实现方案1、一对一关联的实现方案(1)一对一关联(2)一对一关联在hibernate中有两种方式主键关联不需借助外部字段,直接通过两个表的主键进行关联。
此时必须保证两个表的主键值一致(也就是id数据的值相等),在Hibernate中通常是借助foreign 标识符生成器策略来完成。
简单来说,这种情况就是两个表的主键相等的内连接。
基于主键关联的单向一对一关联通常使用一个特定的id生成器foreign。
下面以“Address---》Person”的“一对一”的关联加以说明,其配置的方法。
<class name="Person"><id name="id" column="personId"><generator class="native"/></id></class><class name="Address"><id name="id" column="personId"><generator class="foreign"><param name="property">person</param></generator></id><one-to-one name="person" constrained="true"/></class>create table Person ( personId bigint not null primary key )create table Address ( personId bigint not null primary key )注意:在“主键关联”中使用“foreign”表示与外键共享主键,也就是与Person实体共享主键,而其中的“constrained”属性设定为true,则表示约束Address的主键必须与Person 中对应数据的主键相同。
Hibernate 映射关联关系一、映射多对一关联关系。
1.单向的多对一(1)以Customer 和Order 为例:一个用户可以发出多个订单,而一个订单只能属于一个客户。
从Order 到Customer 是多对一关联关系。
(2)创建Customer 和Order 表。
Create(3)用Intellij Idea 自动生成关联关系,以及对应的Entitiy.hbm.xml 和持久化类。
说明:其中Type 是用来修饰对应的Attribute Name 的。
在Order 端,定义Customer 类,一个订单属于一个客户。
而在Customer 端,一个客户可以有多个订单,因为是单向的,所以这里放弃属性的添加。
在Join Columns 定义了Order 和Customer 之间的关联关系,order 表中的customer_id 外键和customer 表中的customer_id 主键关联。
来看生成的Schema:没有勾选customer_id,是因为Intellij Idea 没法直接映射为Customer 类型的customer。
Order.hbm.xml使用<many-to-one> 节点来维护多对一关联关系。
name 属性:多这一端关联的一那一端的属性的名称。
class 属性:关联的一端的属性的类型。
column 属性:一那一端在多的一端对应的数据表中的外键。
可以任意命名,但需要和数据表中的字段对应。
(4)单向多对一的CRUD 以及需要注意的问题。
<1> 新增①先保存一的一端Customer,后保存多的一端Order。
Save.java打印SQL:Output结论:发送了3条INSERT 语句。
②先保存多的一端Order,再保存一的一端Customer。
Save2.java打印SQL:Output2结论:发送了3条INSERT 语句,2条UPDATE 语句。
总结:在单向多对一的关联关系下,先插入 1 的一端会减少SQL 语句的执行,性能更高。
双向一对一关联-----基于外键关联的双向一对一关联基于外键的双向一对一关联是一种比较常见的关联。
Hibernate通过<many-to-one>标记和<one-to-one>标记结合起来定义这种关联。
这种关联的映射文件与基于外键关联的单向一对一关联基本一致,区别在已有的<many-to-one>的基础上,在另一方增加<one-to-one>标记进行关联。
映射文件如下<hibernate-mapping><classname="hibernate.wizard.chapter8.Person3"table="C8_Person3"schema="dbo"><idname="personId"type="ng.String"column="personId"><generator class="assigned" /></id><!-- Associations --><many-to-one name="address"column="addressId"class="hibernate.wizard.chapter8.Address3"not-null="true"cascade="all"unique="true"/></class><classname="hibernate.wizard.chapter8.Address3"table="C8_Address3"schema="dbo"><idname="addressId"type="ng.String"column="addressId"><generator class="assigned" /></id><propertyname="addressName"type="ng.String"column="addressName"not-null="false"length="50"></property><!-- Associations --><one-to-onename="person"class="hibernate.wizard.chapter8.Person3"property-ref="address"/></class></hibernate-mapping>持久化类Person3类public class Person3 implements Serializable {private String personId;private String addressId;private Address3 address; //双向一对一关联public Person3(String personId, String addressId) { this.personId = personId;this.addressId = addressId;}public Person3(String personId,Address3 address){ this.personId = personId;this.addressId=address.getAddressId();this.address=address;}public Person3(String personId) {this.personId = personId;}public Person3() {}public String getPersonId() {return this.personId;}public void setPersonId(String personId) { this.personId = personId;}public String getAddressId() {return this.addressId;}public void setAddressId(String addressId) { this.addressId = addressId;}public String toString() {return new ToStringBuilder(this).append("personId", getPersonId()) .toString();}public Address3 getAddress() {return address;}public void setAddress(Address3 address) {this.address = address;}}Address3类public class Address3 implements Serializable {private String addressId;private String addressName;private Person3 person; //双向一对一关联public Address3(String addressId,String addressName) { this.addressId = addressId;this.addressName=addressName;}public Address3() {}public String getAddressId() {return this.addressId;}public void setAddressId(String addressId) {this.addressId = addressId;}public String toString() {return new ToStringBuilder(this).append("addressId", getAddressId()).toString();}public String getAddressName() {return addressName;}public void setAddressName(String addressName) {this.addressName = addressName;}public Person3 getPerson() {return person;}public void setPerson(Person3 person) {this.person = person;}测试类public class OneToOne3Test {Session session;Transaction tx;public static void main(String[] args) {OneToOne3Test util=new OneToOne3Test();util.insert();}public void insert(){try {session = HibernateUtil.getSession();} catch (HibernateException ex) {System.out.println(ex);}tx = session.beginTransaction();//开始事务Address3 addr=new Address3("0001","云山路");Person3 p=new Person3("00001");p.setAddressId(addr.getAddressId());p.setAddress(addr);addr.setPerson(p);session.save(p);session.flush();ArrayList result=(ArrayList)session.createQuery("fromhibernate.wizard.chapter8.Person3 as p" +" where p.personId='00001'").list();for (int i=0;i<result.size();i++){Person3 p1=(Person3)result.get(i);System.out.println("---personId---addressId---addressName---personId from Address3");System.out.println("---"+p1.getPersonId()+"---"+p1.getAddressId()+"---"+p1.getAddress().getAddressName()+"---"+p1.getAddress().getPerson() .getPersonId());}mit();//提交事务session.close();//关闭session}}测试结果如下初始化SessionFactory成功!!!!Hibernate: select address3x_.addressId, address3x_.addressName as addressN2_12_ from dbo.C8_Address3 address3x_ where address3x_.addressId=? Hibernate: insert into dbo.C8_Address3 (addressName, addressId) values (?, ?) Hibernate: insert into dbo.C8_Person3 (addressId, personId) values (?, ?) Hibernate: select person3x0_.personId as personId11_, person3x0_.addressId as addressId11_ from dbo.C8_Person3 person3x0_ whereperson3x0_.personId='00001'---personId---addressId---addressName---personId from Address3---00001---0001---云山路---00001。
共六种情况,分成两大类,每类有3个第一类: 1对1单向关联一对一,通过外健实现的单向关联是M:1的特例假设一个人只有一个办公室:Person(pid int primary key, pname char(10), office_id int references office(id));Office(oid int primary key, address char(10));CREATE TABLE `person` (`pid` int(11) NOT NULL DEFAULT '0',`pname` char(10) DEFAULT NULL,`office_id` int(11) DEFAULT NULL,PRIMARY KEY (`pid`),KEY `person_office_FK` (`office_id`),CONSTRAINT `person_office_FK` FOREIGN KEY (`office_id`) REFERENCES `office` (`oid`) );CREATE TABLE `office` (`oid` int(11) NOT NULL DEFAULT '0',`address` varchar(20) DEFAULT NULL,PRIMARY KEY (`oid`))对应的类:public class Person {private Integer pid;//主键private String pname;private Office office;//对应的办公室,单向关联public Integer getPid() {return pid;}public void setPid(Integer pid) {this.pid = pid;}public String getPname() {return pname;}public void setPname(String pname) {this.pname = pname;}public Office getOffice() {return office;}public void setOffice(Office office) {this.office = office;}}OFFICE类:public class Office {private Integer oid;//Office id为主键private String address;public Integer getOid() {return oid;}public void setOid(Integer oid) {this.oid = oid;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}}相应的映射文件:Person.hbm.xml<?xml version="1.0"encoding="utf-8"?><!DOCTYPE hibernate-mapping PUBLIC"-//Hibernate/Hibernate Mapping DTD 3.0//EN""/hibernate-mapping-3.0.dtd"><hibernate-mapping><class name="com.jpioneer.po.Person"table="person"><id name="pid"type="ng.Integer"><generator class="increment"></generator></id><property name="pname"type="ng.String"><column name="pname"></column></property><!-- Person类中的office属性对应的列是person表中的office_id,是外键--><!-- unique="true"表示一对一关系 --><many-to-one name="office"column="office_id"unique="true"></many-to-one></class></hibernate-mapping>Office.hbm.xml<?xml version="1.0"encoding="utf-8"?><!DOCTYPE hibernate-mapping PUBLIC"-//Hibernate/Hibernate Mapping DTD 3.0//EN""/hibernate-mapping-3.0.dtd"><hibernate-mapping><class name="com.jpioneer.po.Office"table="office"><id name="oid"type="ng.Integer"><generator class="increment"></generator></id><property name="address" type="ng.String"><column name="address"></column></property></class></hibernate-mapping>测试:public static void main(String[] args) {Session session = HibernateSessionFactory.getSession();Transaction tx = session.beginTransaction();Person p = new Person();p.setPname("张三");Office o = new Office();o.setAddress("北京");p.setOffice(o);//保存的顺序与效率有关session.save(o);session.save(p);mit();session.close();}一对一,通过主健实现的单向关联主健类不能主健生成策略,由关联类负责.假设一个人只有一个办公室:Person(pid int primary key references office(oid), pname char(10));//注意pid既是主健也是外键Office(oid int primary key, address char(10));CREATE TABLE `office` (`oid` int(11) NOT NULL DEFAULT '0',`address` varchar(20) DEFAULT NULL,PRIMARY KEY (`oid`))CREATE TABLE `person` (`pid` int(11) NOT NULL DEFAULT '0',`pname` char(10) DEFAULT NULL,PRIMARY KEY (`pid`),CONSTRAINT `person_ibfk_1` FOREIGN KEY (`pid`) REFERENCES `office` (`oid`))对应的类:与上同。
Hibernate一对一映射配置详解雪飘寒目录Hibernate一对一映射配置详解 (1)一、xml文件配置 (2)1. 主键关联 (3)2. 单方外键关联 (4)3. 双方外键关联 (5)二、注释方式配置(Annotation) (6)1、主键关联 (6)2. 单方外键关联 (7)3. 双方外键关联 (8)一对一关联分为主键关联与外键关联。
主键关联:不必加额外的字段,只是主表和辅表的主键相关联,即这两个主键的值是一样的。
外键关联:辅表有一个额外的字段和主表相关联,或者两个表都有额外的字段与对应表的相关联。
一、xml文件配置官方文档解释(1) name: 属性的名字。
(2) class (可选 - 默认是通过反射得到的属性类型):被关联的类的名字。
(3) cascade(级联) (可选):表明操作是否从父对象级联到被关联的对象。
(4) constrained(约束) (可选):表明该类对应的表对应的数据库表,和被关联的对象所对应的数据库表之间,通过一个外键引用对主键进行约束。
这个选项影响save()和delete()在级联执行时的先后顺序以及决定该关联能否被委托(也在schema export tool中被使用).(5) fetch (可选 - 默认设置为选择): 在外连接抓取或者序列选择抓取选择其一.(6) property-ref (可选):指定关联类的属性名,这个属性将会和本类的主键相对应。
如果没有指定,会使用对方关联类的主键。
(7) access (可选 - 默认是 property): Hibernate用来访问属性的策略。
(8) formula (可选):绝大多数一对一的关联都指向其实体的主键。
在一些少见的情况中,你可能会指向其他的一个或多个字段,或者是一个表达式,这些情况下,你可以用一个SQL公式来表示。
(可以在org.hibernate.test.onetooneformula找到例子)(9) lazy (可选 - 默认为 proxy): 默认情况下,单点关联是经过代理的。
一对一双向关联(外键关联)每个人己的身份证每张身份证对应着一个人部门通depart_id的员工员工通过外键depart_id能够找到自己所属的部门这是用户表user3的结构多对多双向关联public class Student {p rivate int id;p rivate String name;p rivate Set<Teacher> teachers; …………………………………. } public class Teacher {private int id;private String name;private Set<Student> students; ………………………………….}用户组知道自己有哪些用户:通过groupid就能查询到用户用户不知道自己所于哪个用户组多个订单对应一个客户:订单通过外键:customer_id能够找到自己的客户客户不知道自己有什么订单因为是单向关联public int getId() {id;return}…………………..}在t_jpa_user1表的映射如下结构:多对多单向关联学生老师public class Student1 {privateintid;privateStringname; …………………………………. } public class Teacher1 {private int id;private String name;private Set<Student1> students = new HashSet<Student1>(); ………………………………….}@Entity@Entity@Table(name="t_jpa_teacher2")@Table(name="t_jpa_Student2")public class Teacher2 {public class Student2 {privateintid;privateintid;privateStringname;privateStringname;private Set<Student2> students = new HashSet<Student2>(); ………………………………….@ManyToMany}@JoinTable(name="t_jpa_teacher_student",joinColumns={@JoinColumn(name="teacher_id")},inverseJoinColumns={@JoinColumn(name="student_id")})………………………………….}单向关系中的JoinColumn在单向关系中没有mappedBy,主控方相当于拥有指向另一方的外键的一方。
数据库设计中⼀对⼀、多对⼀、多对多关系依据外键的实现条件及⽅法下⾯以departments和staff_info表为例(为staff_info添加指向departments的外键)⼀个表的字段作为外键的条件:列值必须⾮空且唯⼀测试例⼦如下:mysql> create table departments (dep_id int(4),dep_name varchar(11));Query OK, 0 rows affected (0.02 sec)mysql> desc departments;+----------+-------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+----------+-------------+------+-----+---------+-------+| dep_id | int(4) | YES | | NULL | || dep_name | varchar(11) | YES | | NULL | |+----------+-------------+------+-----+---------+-------+rows in set (0.00 sec)# 创建外键不成功mysql> create table staff_info (s_id int,name varchar(20),dep_id int,foreign key(dep_id) references departments(dep_id));ERROR 1215 (HY000): Cannot add foreign key# 设置dep_id⾮空,仍然不能成功创建外键mysql> alter table departments modify dep_id int(4) not null;Query OK, 0 rows affected (0.02 sec)Records: 0 Duplicates: 0 Warnings: 0mysql> desc departments;+----------+-------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+----------+-------------+------+-----+---------+-------+| dep_id | int(4) | NO | | NULL | || dep_name | varchar(11) | YES | | NULL | |+----------+-------------+------+-----+---------+-------+rows in set (0.00 sec)mysql> create table staff_info (s_id int,name varchar(20),dep_id int,foreign key(dep_id) references departments(dep_id));ERROR 1215 (HY000): Cannot add foreign key constraint# 当设置字段为unique唯⼀字段时,设置该字段为外键成功mysql> alter table departments modify dep_id int(4) unique;Query OK, 0 rows affected (0.01 sec)Records: 0 Duplicates: 0 Warnings: 0mysql> desc departments;+----------+-------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+----------+-------------+------+-----+---------+-------+| dep_id | int(4) | YES | UNI | NULL | || dep_name | varchar(11) | YES | | NULL | |+----------+-------------+------+-----+---------+-------+rows in set (0.01 sec)mysql> create table staff_info (s_id int,name varchar(20),dep_id int,foreign key(dep_id) references departments(dep_id));Query OK, 0 rows affected (0.02 sec)特别注意:需要主外结合的两个表必须是使⽤同样的⼀个引擎类型:两个表必须都是innodb存储引擎添加外键的⽅法⼀般有两种⽅法,在创建表的时候添加,或者后期再添加创建时添加mysql> create table score(-> sid int not null auto_increment primary key,-> student_id int,-> corse_id int,-> number int not null,-> constraint fk_sid foreign key (student_id) references student(sid),-> constraint fk_corse_id foreign key (corse_id) references course(cid));-----------------------------------------------------------------------------------[CONSTRAINT symbol] FOREIGN KEY [id] (从表的字段1)REFERENCES tbl_name (主表的字段2)[ON DELETE {RESTRICT | CASCADE | SET NULL | NO ACTION}][ON UPDATE {RESTRICT | CASCADE | SET NULL | NO ACTION}CONSTRAINT symbol:可以给这个外键约束起⼀个名字,有了名字,以后找到它就很⽅便了。
Hibernate一对一主键关联映射本文将介绍两个对象之间是一对一的关系,如Person-IdCard(人-身份证号)和两种策略可以实现一对一的关联映射。
AD:*两个对象之间是一对一的关系,如Person-IdCard(人-身份证号)*有两种策略可以实现一对一的关联映射》主键关联:即让两个对象具有相同的主键值,以表明它们之间的一一对应关系;数据库不会有额外的字段来维护它们之间的关系,仅通过表的主键来关联》唯一外键关联:外键关联本来是用于多对一的配置,但是如果加上唯一的限制之后,也可以用来表示一对一关联映射1.主键关联映射(单向)实例场景:人-->身份证号(Person-->IdCard),从IdCard看不到Person对象对象模型:IdCard实体类:23456789 public class IdCard { private int id; private String cardNo; public int getId() { return id; } public void setId(int id) { this.id = id;10 }11 public String getCardNo() {12 return cardNo;13 }14 public void setCardNo(String cardNo) {15 this.cardNo = cardNo;16 }17 }Person实体类:18 public class Person {19 private int id;20 private String name;21 private IdCard idCard;//持有IdCard对象的引用22 public int getId() {23 return id;24 }25 public void setId(int id) {26 this.id = id;27 }28 public String getName() {29 return name;30 }31 public void setName(String name) {32 = name;33 }34 public IdCard getIdCard() {35 return idCard;36 }37 public void setIdCard(IdCard idCard) {38 this.idCard = idCard;39 }40 }IdCard实体映射文件:41 <hibernate-mapping>42 <class name=".hibernate.IdCard" table="t_idcard"> 43 <id name="id" column="id">44 <generator class="native"/>45 </id>46 <property name="cardNo"/>47 </class>48 </hibernate-mapping>Person实体映射文件:49 <hibernate-mapping>50 <class name=".hibernate.Person" table="t_person"> 51 <id name="id" column="id">52 <!--53 因为主键不是自己生成的,而是作为一个外键(来源于其它值),所以使用foreign生成策略54 foreign:使用另外一个相关联的对象的标识符,通常和<one-to-one>联合起来使用。
Hibernate关联关系映射配置 (2)一、一对一单向外键关联: (2)1.1目录结构 (2)1.2 Annotation方式 (2)1.3 XML方式 (4)1.4 Hibernate配置文件 (7)二、一对一双向外键关联 (7)2.1 Annotation方式 (7)2.2 XML方式 (9)三、一对一单向主键关联(不重要) (12)3.1 Annotation方式 (12)3.2 XML方式 (14)四、一对一双向主键关联(不重要) (16)4.1 Annotation方式 (16)3.2 XML方式 (19)五、组件映射 (21)5.1 Annotation方式 (21)5.2 XML方式 (23)六、多对一单向关联 (25)6.1 Annotation方式 (25)6.2 XML方式 (27)七、一对多单向关联 (29)7.1 Annotation方式 (29)7.2 XML方式 (31)八、一对多、多对一双向关联 (34)8.1 Annotation方式 (34)8.2 XML方式 (36)九、多对多单向关联 (39)8.1 Annotation方式 (39)8.2 XML方式 (41)十、多对多双向关联 (44)8.1 Annotation方式 (44)8.2 XML方式 (46)Hibernate 关联关系映射配置一、 一对一单向外键关联:1.1目录结构图1-1 目录结构图1.2 Annotation 方式1.2.1类图图1-2 类关联关系图1.2.2数据库表结构FK133651BB21A8E0C8H_HUSBAND_ID NAME WIFE_ID NUMBER(4)VARCHAR2(30 char)NUMBER(4)<pk><fk>H_WIFE_ID NAME NUMBER(4)VARCHAR2(30 char)<pk>图1-3数据库表结构图1.2.3 实体类package com.rongqq.hibernate3.annotation.entity;import java.math.BigDecimal;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.OneToOne;import javax.persistence.SequenceGenerator;@Entity(name="H_HUSBAND_")@SequenceGenerator(name="husband_seq_gene", sequenceName="HUSBAND_SEQ", allocationSize=1) public class Husband {private BigDecimal id;private String name;private Wife wife;@Id@Column(precision=4, scale=0)@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="husband_seq_gene")public BigDecimal getId() {return id;}@Column(length=30)public String getName() {return name;}@OneToOne//@JoinColumn(name="wife_id")//不写也没问题,自动生成的字段也叫wife_idpublic Wife getWife() {return wife;}public void setId(BigDecimal id) {this.id = id;}public void setName(String name) { = name;}public void setWife(Wife wife) {this.wife = wife;}}package com.rongqq.hibernate3.annotation.entity;import java.math.BigDecimal;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.SequenceGenerator;@Entity(name="H_WIFE_")@SequenceGenerator(name="wife_seq_gene", sequenceName="WIFE_SEQ")public class Wife {private BigDecimal id;private String name;@Id@Column(precision=4)@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="wife_seq_gene")public BigDecimal getId() {return id;}public void setId(BigDecimal id) {this.id = id;}@Column(length=30)public String getName() {return name;}public void setName(String name) { = name;}}1.3 XML方式1.3.1 类图图1-4 类关联关系图1.3.2 数据库表结构FKBE32645CF8BD16F4H_HUSBAND_XMLID NAME WIFE_ID NUMBER(4)VARCHAR2(30 char)NUMBER(19,2)<pk><ak,fk>H_WIFE_XMLID NAME NUMBER(4)VARCHAR2(30 char)<pk>图1-5数据库表结构图1.3.3 实体类package com.rongqq.hibernate3.xml.entity; import java.math.BigDecimal; public class XML_Husband { private BigDecimal id ; private String name ; private XML_Wife wife ; public BigDecimal getId() { return id ;}public String getName() { return name ; }public XML_Wife getWife() { return wife ; }public void setId(BigDecimal id) { this .id = id; }public void setName(String name) { this .name = name; }public void setWife(XML_Wife wife) { this .wife = wife; }}package com.rongqq.hibernate3.xml.entity; import java.math.BigDecimal; public class XML_Wife { private BigDecimal id ; private String name ; public BigDecimal getId() { return id ;}public void setId(BigDecimal id) {this.id = id;}public String getName() {return name;}public void setName(String name) { = name;}}1.3.4 对象关系映射文件<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC"-//Hibernate/Hibernate Mapping DTD 3.0//EN""/hibernate-mapping-3.0.dtd"><hibernate-mapping package="com.rongqq.hibernate3.xml.entity"><class name="XML_Husband"table="H_HUSBAND_XML"dynamic-update="true"><id name="id"type="big_decimal"><column name="id"precision="4"scale="0" /><generator class="sequence"><param name="sequence">H_STUDENT_SEQ_XML</param></generator></id><property name="name"length="30"></property><many-to-one name="wife"column="wife_id"unique="true"not-null="true" /><!--many-to-one是站在当前类XML_Husband的角度来看,XML_Husband与wife是多对一--> </class></hibernate-mapping><?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC"-//Hibernate/Hibernate Mapping DTD 3.0//EN""/hibernate-mapping-3.0.dtd"><hibernate-mapping package="com.rongqq.hibernate3.xml.entity"><class name="XML_Wife"table="H_Wife_XML"dynamic-update="true"><id name="id"><column name="id"precision="4"scale="0" /><generator class="sequence"><param name="sequence">H_STUDENT_SEQ_XML</param></generator></id><property name="name"length="30" /></class></hibernate-mapping>1.4 Hibernate配置文件<?xml version='1.0'encoding='utf-8'?><!DOCTYPE hibernate-configuration PUBLIC"-//Hibernate/Hibernate Configuration DTD 3.0//EN""/hibernate-configuration-3.0.dtd"><hibernate-configuration><session-factory><property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property><property name="connection.url">jdbc:oracle:thin:@127.0.0.1:1521:silence</property><property name="ername">cnuser</property><property name="connection.password">cn830306</property><property name="connection.pool_size">1</property><property name="current_session_context_class">thread</property><property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property><property name="show_sql">true</property><property name="format_sql">true</property><property name="dialect">org.hibernate.dialect.Oracle9Dialect</property><!--<property name="hbm2ddl.auto">update</property>--><mapping class="com.rongqq.hibernate3.annotation.entity.Husband" /><mapping class="com.rongqq.hibernate3.annotation.entity.Wife" /><mapping resource="com/rongqq/hibernate3/xml/entity/XML_Husband.hbm.xml" /><mapping resource="com/rongqq/hibernate3/xml/entity/XML_Wife.hbm.xml" /> </session-factory></hibernate-configuration>二、一对一双向外键关联2.1 Annotation方式2.1.1 类图图2-1类关联关系图2.1.2 数据库结构图FK133651BB21A8E0C8H_WIFE_ID NAME NUMBER(4)VARCHAR2(30 char)<pk>H_HUSBAND_ID NAME WIFE_ID NUMBER(4)VARCHAR2(30 char)NUMBER(4)<pk><fk>图2-2数据库表结构图2.1.3 实体类@Entity(name="H_HUSBAND_")@SequenceGenerator(name="husband_seq_gene", sequenceName="HUSBAND_SEQ", allocationSize=1) public class Husband {private BigDecimal id;private String name;private Wife wife;@Id@Column(precision=4, scale=0)@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="husband_seq_gene")public BigDecimal getId() {return id;}@Column(length=30)public String getName() {return name;}@OneToOne//@JoinColumn(name="wife_id")//不写也没问题,自动生成的字段也叫wife_idpublic Wife getWife() {return wife;}public void setId(BigDecimal id) {this.id = id;}public void setName(String name) { = name;}public void setWife(Wife wife) {this.wife = wife;}}@Entity(name="H_WIFE_")@SequenceGenerator(name="wife_seq_gene", sequenceName="WIFE_SEQ")public class Wife {private BigDecimal id;private String name;private Husband husband;@Id@Column(precision=4)@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="wife_seq_gene")public BigDecimal getId() {return id;}public void setId(BigDecimal id) {this.id = id;}@Column(length=30)public String getName() {return name;}public void setName(String name) { = name;}@OneToOne(mappedBy="wife")public Husband getHusband() {return husband;}public void setHusband(Husband husband) {this.husband = husband;}}2.2 XML方式2.2.1 类图图2-3 类关联关系图2.2.2 数据库结构图FKBE32645CF8BD16F4H_WIFE_XMLID NAME NUMBER(4)VARCHAR2(30 char)<pk>H_HUSBAND_XMLID NAME WIFE_ID NUMBER(4)VARCHAR2(30 char) NUMBER(4,2)<pk><fk>2.2.3 实体类package com.rongqq.hibernate3.xml.entity;import java.math.BigDecimal;public class XML_Husband {private BigDecimal id;private String name;private XML_Wife wife;public BigDecimal getId() {return id;}public String getName() {return name;}public XML_Wife getWife() {return wife;}public void setId(BigDecimal id) {this.id = id;}public void setName(String name) { = name;}public void setWife(XML_Wife wife) {this.wife = wife;}}package com.rongqq.hibernate3.xml.entity;import java.math.BigDecimal;public class XML_Wife {private BigDecimal id;private String name;private XML_Husband husband;public BigDecimal getId() {return id;}public void setId(BigDecimal id) {this.id = id;}public String getName() {return name;}public void setName(String name) { = name;}public XML_Husband getHusband() {return husband;}public void setHusband(XML_Husband husband) {this.husband = husband;}}2.2.4 对象关系映射文件<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC"-//Hibernate/Hibernate Mapping DTD 3.0//EN""/hibernate-mapping-3.0.dtd"><hibernate-mapping package="com.rongqq.hibernate3.xml.entity"><class name="XML_Husband"table="H_HUSBAND_XML"dynamic-update="true"> <id name="id"type="big_decimal"><column name="id"precision="4"scale="0"/><generator class="sequence"><param name="sequence">H_STUDENT_SEQ_XML</param></generator></id><property name="name"length="30"></property><many-to-one name="wife"unique="true"not-null="true"><column name="wife_id"precision="4"></column></many-to-one></class></hibernate-mapping><?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC"-//Hibernate/Hibernate Mapping DTD 3.0//EN""/hibernate-mapping-3.0.dtd"><hibernate-mapping package="com.rongqq.hibernate3.xml.entity"><class name="XML_Wife"table="H_Wife_XML"dynamic-update="true"><id name="id"><column name="id"precision="4"scale="0"/><generator class="sequence"><param name ="sequence">H_STUDENT_SEQ_XML </param ></generator ></id ><property name ="name" length ="30" /><!-- 这里的wife 是XML_Husband 类中的属性名,表示这里的关联关系已经由Husband 的对象 映射文件的wife 属性上定义过了 --><one-to-one name ="husband" property-ref ="wife" /></class > </hibernate-mapping >三、一对一单向主键关联(不重要)3.1 Annotation 方式3.1.1类图图3-1 类关联关系图3.1.2 数据库表结构H_WIFE_ID NAME NUMBER(4)VARCHAR2(30 char)<pk>H_HUSBAND_ID NAME NUMBER(4)VARCHAR2(30 char)<pk>图3-2 数据库表结构图3.1.3 实体类package com.rongqq.hibernate3.annotation.entity; import java.math.BigDecimal; import javax.persistence.Column; import javax.persistence.Entity;import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.OneToOne;import javax.persistence.PrimaryKeyJoinColumn; import javax.persistence.SequenceGenerator; @Entity (name="H_HUSBAND_")@SequenceGenerator (name="husband_seq_gene", sequenceName="HUSBAND_SEQ", allocationSize=1) public class Husband {private BigDecimal id ;private String name;private Wife wife;@Id@Column(precision=4, scale=0)@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="husband_seq_gene") public BigDecimal getId() {return id;}@Column(length=30)public String getName() {return name;}@OneToOne@PrimaryKeyJoinColumnpublic Wife getWife() {return wife;}public void setId(BigDecimal id) {this.id = id;}public void setName(String name) { = name;}public void setWife(Wife wife) {this.wife = wife;}}package com.rongqq.hibernate3.annotation.entity;import java.math.BigDecimal;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.SequenceGenerator;@Entity(name="H_WIFE_")@SequenceGenerator(name="wife_seq_gene", sequenceName="WIFE_SEQ")public class Wife {private BigDecimal id;private String name;@Id@Column(precision=4)@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="wife_seq_gene") public BigDecimal getId() {return id;}public void setId(BigDecimal id) {this.id = id;}@Column(length=30)public String getName() {return name;}public void setName(String name) { = name;}}注:只生成了表,但是没有外键约束,具体实现还需要查找3.2 XML方式3.2.1 类图图3-3 类关联关系图3.2.2 数据库表结构FKBE32645CA8BE0706H_WIFE_XMLID NAME NUMBER(4)VARCHAR2(30 char)<pk>H_HUSBAND_XMLID NAME NUMBER(4)VARCHAR2(30 char)<pk,fk>图3-4 数据库表结构图3.2.3 实体类package com.rongqq.hibernate3.xml.entity;import java.math.BigDecimal;public class XML_Husband {private BigDecimal id;private String name;private XML_Wife wife;public BigDecimal getId() {return id;}public String getName() {return name;}public XML_Wife getWife() {return wife;}public void setId(BigDecimal id) {this.id = id;}public void setName(String name) { = name;}public void setWife(XML_Wife wife) {this.wife = wife;}}package com.rongqq.hibernate3.xml.entity;import java.math.BigDecimal;import com.rongqq.hibernate3.annotation.entity.Husband;public class XML_Wife {private BigDecimal id;private String name;public BigDecimal getId() {return id;}public void setId(BigDecimal id) {this.id = id;}public String getName() {return name;}public void setName(String name) { = name;}}3.2.4 对象映射文件<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC"-//Hibernate/Hibernate Mapping DTD 3.0//EN""/hibernate-mapping-3.0.dtd"><hibernate-mapping package="com.rongqq.hibernate3.xml.entity"><class name="XML_Husband"table="H_HUSBAND_XML"dynamic-update="true"> <id name="id"type="big_decimal"><column name="id"precision="4"scale="0"/><generator class="foreign"><!-- 指明具体参考哪一个外键,因为一张表可能存在多个外键--><param name="property">wife</param></generator></id><property name="name"length="30"></property><one-to-one name="wife"constrained="true"></one-to-one></class></hibernate-mapping><?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC"-//Hibernate/Hibernate Mapping DTD 3.0//EN""/hibernate-mapping-3.0.dtd"><hibernate-mapping package="com.rongqq.hibernate3.xml.entity"><class name="XML_Wife"table="H_Wife_XML"dynamic-update="true"><id name="id"><column name="id"precision="4"scale="0"/><generator class="sequence"><param name="sequence">H_STUDENT_SEQ_XML</param></generator></id><property name="name"length="30"/></class></hibernate-mapping>四、一对一双向主键关联(不重要)4.1 Annotation方式4.1.1 类图图4-1 类关联关系图4.1.2 数据库表结构H_WIFE_ID NAME NUMBER(4)VARCHAR2(30 char)<pk>H_HUSBAND_ID NAME NUMBER(4)VARCHAR2(30 char)<pk>图4-2 数据库表结构图4.1.3 实体类package com.rongqq.hibernate3.annotation.entity;import java.math.BigDecimal;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.OneToOne;import javax.persistence.PrimaryKeyJoinColumn;import javax.persistence.SequenceGenerator;@Entity(name="H_HUSBAND_")@SequenceGenerator(name="husband_seq_gene", sequenceName="HUSBAND_SEQ", allocationSize=1) public class Husband {private BigDecimal id;private String name;private Wife wife;@Id@Column(precision=4, scale=0)@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="husband_seq_gene")public BigDecimal getId() {return id;}@Column(length=30)public String getName() {return name;}@OneToOne@PrimaryKeyJoinColumnpublic Wife getWife() {return wife;}public void setId(BigDecimal id) {this.id = id;}public void setName(String name) { = name;public void setWife(Wife wife) {this.wife = wife;}}package com.rongqq.hibernate3.annotation.entity;import java.math.BigDecimal;import javax.persistence.Column;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.OneToOne;import javax.persistence.PrimaryKeyJoinColumn;import javax.persistence.SequenceGenerator;@Entity(name="H_WIFE_")@SequenceGenerator(name="wife_seq_gene", sequenceName="WIFE_SEQ")public class Wife {private BigDecimal id;private String name;private Husband husband;@Id@Column(precision=4)@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="wife_seq_gene") public BigDecimal getId() {return id;}public void setId(BigDecimal id) {this.id = id;}@Column(length=30)public String getName() {return name;}public void setName(String name) { = name;}@OneToOne@PrimaryKeyJoinColumnpublic Husband getHusband() {return husband;}public void setHusband(Husband husband) {this.husband = husband;}注:同样不产生关联关系,具体实现待查3.2 XML方式4.2.1 类图图4-3 类关联关系图4.2.2 数据库表结构FKBE32645CA8BE0706H_WIFE_XMLID NAME NUMBER(4)VARCHAR2(30 char)<pk>H_HUSBAND_XMLID NAME NUMBER(4)VARCHAR2(30 char)<pk,fk>图4-4 数据库表结构图4.2.3 实体类package com.rongqq.hibernate3.xml.entity;import java.math.BigDecimal;public class XML_Husband {private BigDecimal id;private String name;private XML_Wife wife;public BigDecimal getId() {return id;}public String getName() {return name;}public XML_Wife getWife() {return wife;}public void setId(BigDecimal id) {this.id = id;}public void setName(String name) { = name;}public void setWife(XML_Wife wife) {this.wife = wife;}}package com.rongqq.hibernate3.xml.entity;import java.math.BigDecimal;public class XML_Wife {private BigDecimal id;private String name;private XML_Husband husband;public BigDecimal getId() {return id;}public void setId(BigDecimal id) {this.id = id;}public String getName() {return name;}public void setName(String name) { = name;}public XML_Husband getHusband() {return husband;}public void setHusband(XML_Husband husband) {this.husband = husband;}}4.2.4 对象映射文件<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC"-//Hibernate/Hibernate Mapping DTD 3.0//EN""/hibernate-mapping-3.0.dtd"><hibernate-mapping package="com.rongqq.hibernate3.xml.entity"><class name="XML_Husband"table="H_HUSBAND_XML"dynamic-update="true"> <id name="id"type="big_decimal"><column name="id"precision="4"scale="0"/><generator class="foreign"><param name="property">wife</param></generator></id ><property name ="name" length ="30"></property ><one-to-one name ="wife " constrained ="true "></one-to-one ></class > </hibernate-mapping > <?xml version ="1.0"?><!DOCTYPE hibernate-mapping PUBLIC"-//Hibernate/Hibernate Mapping DTD 3.0//EN""/hibernate-mapping-3.0.dtd"> <hibernate-mapping package ="com.rongqq.hibernate3.xml.entity"> <class name ="XML_Wife" table ="H_Wife_XML" dynamic-update ="true"> <id name ="id"> <column name ="id" precision ="4" scale ="0" /> <generator class ="sequence"><param name ="sequence">H_STUDENT_SEQ_XML </param ></generator ></id ><property name ="name" length ="30" /><one-to-one name ="husband" property-ref ="wife "></one-to-one ></class > </hibernate-mapping >五、组件映射5.1 Annotation 方式5.1.1类图图5-1 类关联关系图5.1.2 数据库表结构H_HUSBAND_ID NAME AGEWIFENAMENUMBER(4)VARCHAR2(30 char)NUMBER(3)VARCHAR2(255 char)<pk>图5-2 数据库表结构图5.1.3 实体类package com.rongqq.hibernate3.annotation.entity; import java.math.BigDecimal;import javax.persistence.Column;import javax.persistence.Embedded;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.GenerationType;import javax.persistence.Id;import javax.persistence.SequenceGenerator;@Entity(name="H_HUSBAND_")@SequenceGenerator(name="husband_seq_gene", sequenceName="HUSBAND_SEQ", allocationSize=1) public class Husband {private BigDecimal id;private String name;private Wife wife;@Id@Column(precision=4, scale=0)@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="husband_seq_gene")public BigDecimal getId() {return id;}@Column(length=30)public String getName() {return name;}@Embeddedpublic Wife getWife() {return wife;}public void setId(BigDecimal id) {this.id = id;}public void setName(String name) { = name;}public void setWife(Wife wife) {this.wife = wife;}}package com.rongqq.hibernate3.annotation.entity;import java.math.BigDecimal;import javax.persistence.Column;public class Wife {private String name;private BigDecimal age;@Column(name="wifeName")public String getName() { return name ;}public void setName(String name) { this .name = name; }@Column (precision=3) public BigDecimal getAge() { return age ; }public void setAge(BigDecimal age) { this .age = age; }}5.2 XML 方式5.2.1类图图5-3 类关联关系图5.2.2 数据库表结构H_HUSBAND_XMLID NAMEWIFENAME AGENUMBER(4)VARCHAR2(30 char)VARCHAR2(255 char)NUMBER(3,2)<pk>图5-4 数据库表结构图5.2.3 实体类package com.rongqq.hibernate3.xml.entity; import java.math.BigDecimal; public class XML_Husband { private BigDecimal id ; private String name ; private XML_Wife wife ; public BigDecimal getId() { return id ;}public String getName() { return name ;}public XML_Wife getWife() {return wife;}public void setId(BigDecimal id) {this.id = id;}public void setName(String name) { = name;}public void setWife(XML_Wife wife) {this.wife = wife;}}package com.rongqq.hibernate3.xml.entity;import java.math.BigDecimal;public class XML_Wife {private String name;private BigDecimal age;public String getName() {return name;}public void setName(String name) { = name;}public BigDecimal getAge() {return age;}public void setAge(BigDecimal age) {this.age = age;}}5.2.4 对象映射文件<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC"-//Hibernate/Hibernate Mapping DTD 3.0//EN""/hibernate-mapping-3.0.dtd"><hibernate-mapping package="com.rongqq.hibernate3.xml.entity"><class name="XML_Husband"table="H_HUSBAND_XML"dynamic-update="true"> <id name="id"type="big_decimal"><column name="id"precision="4"scale="0"/><generator class="foreign"><param name="property">wife</param></generator></id><property name ="name" length ="30"></property > <component name ="wife"> <property name ="name" column ="WIFENAME " /><property name ="age" column ="AGE" precision ="3" /></component ></class > </hibernate-mapping >六、多对一单向关联6.1 Annotation 方式6.1.1 类图(说明:一个人具备多套房子的所有权,这么多套房子属于这个人)图6-1 类关联关系图6.1.2 数据库表结构FK5822AD3634FDD6C8H_PERSON_ID NAME NUMBER(21)VARCHAR2(255 char)<pk>H_HOUSE_ID POSITION PERSON_ID NUMBER(20)VARCHAR2(255 char)NUMBER(21)<pk><fk>图6-2 数据库表结构图6.1.3 实体类package com.rongqq.hibernate3.annotation.entity; import java.math.BigDecimal; import javax.persistence.Column; import javax.persistence.Entity;import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id;import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.SequenceGenerator; @Entity (name="H_HOUSE_")。
word目录1关系映射11.1单向关联11.1.1 一对一外键单向关联11.1.2 一对一主键单向关联51.1.3 一对多外键单向关联61.1.4 多对一外键单向关联101.2双向关联141.2.1 一对一外键双向关联141.2.2 一对一主键双向关联171.2.3 一对多外键双向关联181.2.4 多对多双向关联211关系映射1.1单向关联1.1.1一对一外键单向关联1、模型介绍一个人〔Person〕对应一个地址〔Address〕。
2、实体〔无getter和setter〕Peronprivate Long oid;private String personid;private String name;private Address addressfk;Addressprivate Long oid;private String addressid;private String addressdetail;3、表模型以下是地址表表1地址表以下是人物表,其中addressid是外键引用地址表的addressid表2人物表4、映射文件<hibernate-mapping package=".test.fkoo"><class name="Address" table="address"><id name="oid"><generator class="native" /></id><property name="addressid" unique="true" not-null="true" /> <property name="addressdetail" not-null="true" /></class></hibernate-mapping><hibernate-mapping package=".test.fkoo"><class name="Person" table="person"><id name="oid"><generator class="native" /></id><property name="personid" unique="true" not-null="true" /><property name="name" not-null="true" /><!--用来映射关联PO column是Address在该表中的外键列名,增加unique 是唯一的--><!--下面的addressid只是名字而已,manytoone自动关联address方的主键不过取个有实际意义的名字让表结构更清晰--><many-to-one name="addressfk" column="addressid" unique="true" not-null="true"/></class></hibernate-mapping>5、测试方法public class Test {public static void main(String[] args) {Session s = HibernateUtil.getSession();try {s.beginTransaction();Person p = new Person();p.setName("xuwei");p.setPersonid("200610801232");Address a = new Address();a.setAddressid("杨家冲6号");a.setAddressdetail("某某市大安区");p.setAddressfk(a);s.save(a);s.save(p);s.getTransaction().mit();} catch (HibernateException e) {e.printStackTrace();s.getTransaction().rollback();} finally {s.close();}}}6、测试结果a、s.save(a);s.save(p);正常保存b、s.save(p);s.save(a);异常发生,异常信息:not-null property references a null or transient value c、s.save(a)能够插入,但信息不全,只插入一条记录。