Hibernate关联映射之多对一、一对一映射
来源:互联网 发布:suse linux yum配置 编辑:程序博客网 时间:2024/06/05 22:39
多对一关联映射
原理是在多的一端加入外键指向一的一端。采用<many-to-one>标签。cascade(级联)属性,作用是两个对象连锁操作,取值有none(默认)、all、sava-update(推荐)、delete。示例:
User实体
public class User {private int id;private String name;private String password;private Date birthday;private Group group;public User() {}public User(String name, String password, Date birthday) {this.name = name;this.password = password;this.birthday = birthday;}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getPassword() {return password;}public void setPassword(String password) {this.password = password;}public Date getBirthday() {return birthday;}public void setBirthday(Date birthday) {this.birthday = birthday;}public Group getGroup() {return group;}public void setGroup(Group group) {this.group = group;}User.hbm.xml
<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping><class name="com.zero.hibernate.vo.User" table="t_user"><id name="id" column="userID"><generator class="native" /><!-- 主键 --><!-- native/uuid --></id><property name="name" type="string" length="30" unique="true"not-null="true" /><property name="password" /><property name="birthday" type="date" /><many-to-one name="group" column="groupId" cascade="save-update"></many-to-one></class></hibernate-mapping>Group实体:
public class Group {private String id;private String name;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}}Group.hbm.xml
<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping><class name="com.zero.hibernate.vo.Group" table="t_group"><id name="id" column="id"><generator class="native" /><!-- 主键 --></id><property name="name" type="string" length="30" unique="true"not-null="true" /></class></hibernate-mapping>生成的建表指令:(<many-to-one>会加字段)
drop table if exists t_group drop table if exists t_user create table t_group ( id varchar(255) not null auto_increment, name varchar(30) not null, primary key (id)) create table t_user ( userID integer not null auto_increment, name varchar(30) not null, password varchar(255), birthday date, groupId varchar(255), primary key (userID) ) alter table t_group add constraint UK_sw96rg1m1r6q8cp787dx7ugru unique (name) alter table t_user add constraint UK_g8gqk4e142wekcb1t6d3v2mwx unique (name) alter table t_user add constraint FK_7ktm6l2qkykpqrf6oq01ys8wy foreign key (groupId) references t_group (id)测试:
//在没设置cascade="save-update"情况下Group group = new Group();group.setName("AAAAAAAA");User u1 = new User("aaa","123",new Date());u1.setGroup(group);User u2 = new User("aaa","123",new Date());u2.setGroup(group);session.save(u1);session.save(u2);//在清理缓存是发生错误TransientObjectException.//因为Group为Transient状态,没有被session,在数据库中没有匹配的数据//而User为Persistent状态,在清理缓存时hibernate在缓存中无法找到Group对象
//在没设置cascade="save-update"情况下Group group = new Group();group.setName("AAAAAAAA");session.save(group);User u1 = new User("aaa","123",new Date());u1.setGroup(group);User u2 = new User("aaa","123",new Date());u2.setGroup(group);session.save(u1);session.save(u2);//可以正确的保存数据//因为Group和User都是Persistent状态的对象//所以在hibernate清理缓存时在session中可以找到关联对象
//在设置cascade="save-update"情况下Group group = new Group();group.setName("AAAAAAAA");User u1 = new User("aaa","123",new Date());u1.setGroup(group);User u2 = new User("aaa","123",new Date());u2.setGroup(group);session.save(u1);session.save(u2);session.save(user1);session.save(user2);//没有抛出TransientObjectException异常//因为使用了级联特性//hibernate会首先保存User的关联对象对象Group//Group和User就都是Persistent状态的对象了
一对一关联映射
方式一. 让两个实体的主键一样,无需要加入多余的字段
1.单向关联Person----->IDCard
Person实体:public class Person {private int id;private String name;private IDCard IDCard;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public IDCard getIDCard() {return IDCard;}public void setIDCard(IDCard iDCard) {IDCard = iDCard;}}Person.hbm.xml
<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping><class name="com.zero.hibernate.vo.Person" table="t_person"><id name="id"><!-- 采用foreign生成策略,foreign会取得关联对象的标识 --><generator class="foreign"><!-- property 指关联对象 --><param name="property">IDCard</param></generator></id><property name="name" /><!-- one-to-one指示hibernate如何加载其关联对象,默认根据主键加载, 也就是拿到关系字段值, 根据对端的主键来加载关联对象 constrained="true表示,当前主键(Person的主键)还是一个外键, 参照了对端的主键(IDCard的主键),也就是会生成外键约束语句 --><one-to-one name="IDCard" constrained="true" /></class></hibernate-mapping>IDCard实体:
public class IDCard {private int id;private String cardNum;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getCardNum() {return cardNum;}public void setCardNum(String cardNum) {this.cardNum = cardNum;}}IDCard.hbm.xml
<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping><class name="com.zero.hibernate.vo.IDCard" table="t_IDCard"><id name="id"><generator class="native"/></id><property name="cardNum"/></class></hibernate-mapping>生成的建表指令:(<one-to-one>不会加字段)
alter table t_person drop foreign key FK_q2gx6s9cco0dl5pd4b0xexsad drop table if exists t_IDCard drop table if exists t_person create table t_IDCard ( id integer not null auto_increment, cardNum varchar(255), primary key (id) ) create table t_person ( id integer not null, name varchar(255), primary key (id) ) alter table t_person add constraint FK_q2gx6s9cco0dl5pd4b0xexsad foreign key (id) references t_IDCard (id)测试:
IDCard idCard = new IDCard();idCard.setCardNum("123456789");Person person = new Person();person.setName("萧");// 建立关联person.setIDCard(idCard);// 没有抛出TransientObjectException// 是由一对一关联映射的特性决定的,它必须先保存关联对象IdCard// 这样它采用foreign映射策略才能取得关联对象的标识// 也就是它默认了cascade属性session.save(person);
IDCard idCard = new IDCard();idCard.setCardNum("12234567");Person person = new Person();person.setName("zero");// 建立关联person.setIDCard(idCard);// 只能将IdCard保存,不能将Person保存// 因为关系的维护端在Person端,IDCard不知道Person的存在session.save(idCard);
2. 双向关联Person<----->IDCard.
需要在IDCard加入<one-to-one>标签,指示hibernate将关联对象Person根据主键加载上来. 这里的<one-to-one>不影响存储,只影响加载。Person实体:
public class Person {private int id;private String name;private IDCard IDCard;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public IDCard getIDCard() {return IDCard;}public void setIDCard(IDCard iDCard) {IDCard = iDCard;}}Person.hbm.xml
<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping><class name="com.zero.hibernate.vo.Person" table="t_person"><id name="id"><!-- 采用foreign生成策略,foreign会取得关联对象的标识 --><generator class="foreign"><!-- property 指关联对象 --><param name="property">IDCard</param></generator></id><property name="name" /><!-- one-to-one指示hibernate如何加载其关联对象,默认根据主键加载, 也就是拿到关系字段值, 根据对端的主键来加载关联对象 constrained="true表示,当前主键(Person的主键)还是一个外键, 参照了对端的主键(IDCard的主键),也就是会生成外键约束语句 --><one-to-one name="IDCard" constrained="true" /></class></hibernate-mapping>IDCard实体:
public class IDCard {private int id;private String cardNum;private Person person;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getCardNum() {return cardNum;}public void setCardNum(String cardNum) {this.cardNum = cardNum;}public Person getPerson() {return person;}public void setPerson(Person person) {this.person = person;}}IDCard.hbm.xml
<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping><class name="com.zero.hibernate.vo.IDCard" table="t_IDCard"><id name="id"><generator class="native" /></id><property name="cardNum" /><one-to-one name="person" /></class></hibernate-mapping>生成的建表指令:
alter table t_person drop foreign key FK_q2gx6s9cco0dl5pd4b0xexsad drop table if exists t_IDCard drop table if exists t_person create table t_IDCard ( id integer not null auto_increment, cardNum varchar(255), primary key (id) ) create table t_person ( id integer not null, name varchar(255), primary key (id) ) alter table t_person add constraint FK_q2gx6s9cco0dl5pd4b0xexsad foreign key (id) references t_IDCard (id)测试:
IDCard idCard = new IDCard();idCard.setCardNum("12234567");Person person = new Person();person.setName("zero");// 建立关联person.setIDCard(idCard);// 只能将IdCard保存,不能将Person保存// 因为关系的维护端还是在Person端session.save(idCard);
方式二. 唯一外键关联映射
1.单向关联Person----->IDCard
一对一唯一外键关联映射其实是多对一的特例,采用<many-to-one>标签来映射,指定多的一端unique为true,这样就限制了多的一端的多重性为一,就是这样来映射的。Person实体:
public class Person {private int id;private String name;private IDCard IDCard;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public IDCard getIDCard() {return IDCard;}public void setIDCard(IDCard iDCard) {IDCard = iDCard;}}Person.hbm.xml
<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping><class name="com.zero.hibernate.vo.Person" table="t_person"><id name="id"><generator class="native" /></id><property name="name" /><many-to-one name="IDCard" unique="true" /></class></hibernate-mapping>IDCard实体:
public class IDCard {private int id;private String cardNum;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getCardNum() {return cardNum;}public void setCardNum(String cardNum) {this.cardNum = cardNum;}}IDCard.hbm.xml
<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping><class name="com.zero.hibernate.vo.IDCard" table="t_IDCard"><id name="id"><generator class="native" /></id><property name="cardNum" /></class></hibernate-mapping>生成的建表指令:
alter table t_person drop foreign key FK_84cux32o4j1hukfr5khsx0cjedrop table if exists t_IDCarddrop table if exists t_person create table t_IDCard ( id integer not null auto_increment, cardNum varchar(255), primary key (id) ) create table t_person ( id integer not null auto_increment, name varchar(255), IDCard integer, primary key (id)) alter table t_person add constraint UK_84cux32o4j1hukfr5khsx0cje unique (IDCard) alter table t_person add constraint FK_84cux32o4j1hukfr5khsx0cje foreign key (IDCard) references t_IDCard (id)测试:
IDCard idCard = new IDCard();idCard.setCardNum("123456789");Person person = new Person();person.setName("萧");// 建立关联person.setIDCard(idCard);//抛出TransientObjectException//因为IdCard为Transient状态session.save(person);
IDCard idCard = new IDCard();idCard.setCardNum("123456789");session.save(idCard);Person person = new Person();person.setName("萧");// 建立关联person.setIDCard(idCard);session.save(person);//保存成功
2. 双向关联Person<----->IDCard.
一对一唯一外键双向关联在IDCard端采用<one-to-one>标签映射,必须指定<one-to-one>标签中的property-ref属性为关系字段的名称。Person实体:
public class Person {private int id;private String name;private IDCard IDCard;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public IDCard getIDCard() {return IDCard;}public void setIDCard(IDCard iDCard) {IDCard = iDCard;}}Person.hbm.xml
<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping><class name="com.zero.hibernate.vo.Person" table="t_person"><id name="id"><generator class="native" /></id><property name="name" /><many-to-one name="IDCard" unique="true" /></class></hibernate-mapping>IDCard实体:
public class IDCard {private int id;private String cardNum;private Person person;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getCardNum() {return cardNum;}public void setCardNum(String cardNum) {this.cardNum = cardNum;}public Person getPerson() {return person;}public void setPerson(Person person) {this.person = person;}}IDCard.hbm.xml
<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping><class name="com.zero.hibernate.vo.IDCard" table="t_IDCard"><id name="id"><generator class="native" /></id><property name="cardNum" /><one-to-one name="person" property-ref="IDCard"/></class></hibernate-mapping>生成的建表指令:
alter table t_person drop foreign key FK_84cux32o4j1hukfr5khsx0cje drop table if exists t_IDCard drop table if exists t_person create table t_IDCard ( id integer not null auto_increment, cardNum varchar(255), primary key (id) ) create table t_person ( id integer not null auto_increment, name varchar(255), IDCard integer, primary key (id) ) alter table t_person add constraint UK_84cux32o4j1hukfr5khsx0cje unique (IDCard) alter table t_person add constraint FK_84cux32o4j1hukfr5khsx0cje foreign key (IDCard) references t_IDCard (id)测试:
Person person = (Person)session.load(Person.class, 1);System.out.println("person.name=" + person.getName());System.out.println("person.cardNo=" + person.getIDCard().getCardNum());IDCard idCard = (IDCard)session.load(IDCard.class, 1);System.out.println("idCard.cardNum = " + idCard.getCardNum());System.out.println("idCard.person.name = " + idCard.getPerson().getName());//均可以查询出结果
0 0
- Hibernate关联映射之多对一、一对一映射
- Hibernate映射之多对一关联映射
- hibernate关联映射:多对一、一对一
- hibernate之多对一关联映射
- 【Hibernate步步为营】--关联映射之多对一
- 【Hibernate步步为营】--关联映射之多对一
- Hibernate关联映射之多对一单向关联映射
- 【HIbernate】(五)关联映射之多对一映射
- 【HIbernate】(五)关联映射之多对一映射
- Hibernate 关联映射 之多对一关联(一)
- hibernate关联映射之多对一单向关联
- 关联映射之多对一
- Hibernate关联关系映射 一对一 一对多 多对一
- Hibernate(2)关联映射之多对一
- 【Hibernate系列】(五):关联映射之多对一
- hibernate一对一关联映射--
- hibernate一对一关联映射
- hibernate一对一关联映射
- bestCoder 2015 百度之星程序设计大赛 资格赛 1006单调区间
- 478A - Initial Bet
- 态度
- C++调用HTTP实现方式
- 欢迎使用CSDN-markdown编辑器
- Hibernate关联映射之多对一、一对一映射
- socket实现大型文件传输
- matlab报错”xlswrite函数的Object returned error code: 0x800A03EC
- log4j 加载顺序
- java获取服务器一些信息的方法
- 关于mysql 的for update
- Elasticsearch 初探及window下集群的搭建
- EJB+JPA CRUD实现
- dfvsdf