转自: http://blog.csdn.net/a19881029/article/details/17481749
2张表之间通过主键形成一对一映射关系,如一个人只能有一张身份证:
t_identity_card表建表语句:
- CREATE TABLE `t_identity_card` (
- `id` int(11) NOT NULL,
- `identity` int(11) NOT NULL,
- PRIMARY KEY (`id`)
- ) ENGINE=InnoDB DEFAULT CHARSET=gb2312;
t_person表建表语句:
- CREATE TABLE `t_person` (
- `id` int(11) NOT NULL,
- `name` varchar(255) NOT NULL,
- `age` int(11) NOT NULL,
- PRIMARY KEY (`id`),
- CONSTRAINT `FK_ID` FOREIGN KEY (`id`) REFERENCES `t_identity_card` (`id`)
- ) ENGINE=InnoDB DEFAULT CHARSET=gb2312;
hibernate.cfg.xml:
- <?xml version='1.0' encoding='utf-8'?>
- <!DOCTYPE hibernate-configuration PUBLIC
- "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
- "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
- <hibernate-configuration>
- <session-factory>
- <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
- <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
- <property name="connection.url">jdbc:mysql://localhost:3306/mydb</property>
- <property name="connection.username">root</property>
- <property name="connection.password">196428</property>
- <property name="hibernate.show_sql">true</property>
- <mapping resource="com/po/IdentityCard.hbm.xml" />
- <mapping resource="com/po/Person.hbm.xml" />
- </session-factory>
- </hibernate-configuration>
单向一对一主键关联:
t_identity_card表:
- public class IdentityCard implements Serializable {
- private static final long serialVersionUID = 1L;
- private int id;
- private int identity;
- private Person person;
- public int getId() {
- return id;
- }
- public void setId(int id) {
- this.id = id;
- }
- public int getIdentity() {
- return identity;
- }
- public void setIdentity(int identity) {
- this.identity = identity;
- }
- public Person getPerson() {
- return person;
- }
- public void setPerson(Person person) {
- this.person = person;
- }
- }
由于t_identity_card表使用foreign主键生成策略,故在t_identity_card表的配置文件中必须配置主键生成表t_person,这样在向t_identity_card表中插入数据时才能找到所需的主键值,所以单向一对一主键关联中只有t_person<-t_identity_card,没有t_person->t_identity_card
- <?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.po.IdentityCard" table="t_identity_card">
- <id name="id" column="id" type="integer">
- <generator class="foreign">
- <param name="property">person</param>
- </generator>
- </id>
- <property name="identity" column="identity" type="integer"/>
- <one-to-one name="person" class="com.po.Person"/>
- </class>
- </hibernate-mapping>
t_person表:
- public class Person implements Serializable {
- private static final long serialVersionUID = 1L;
- private int id;
- private String name;
- private int age;
- 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 int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- }
- <?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.po.Person" table="t_person">
- <id name="id" column="id" type="integer">
- <generator class="assigned"/>
- </id>
- <property name="name" column="name" type="string"/>
- <property name="age" column="age" type="integer"/>
- </class>
- </hibernate-mapping>
测试一下:
- public class Test {
- public static void main(String[] args) {
- Configuration conf = new Configuration();
- SessionFactory sessionFactory = conf.configure().buildSessionFactory();
- Session session = sessionFactory.openSession();
- IdentityCard identityCard = new IdentityCard();
- identityCard.setIdentity(123456);
- Person person = new Person();
- person.setId(1);
- person.setName("sean");
- person.setAge(25);
- identityCard.setPerson(person);
- Transaction tran = session.beginTransaction();
- session.save(identityCard);
- tran.commit();
- IdentityCard identityCard2 = (IdentityCard)session.get(IdentityCard.class, 1);
- Person person2 = identityCard2.getPerson();
- System.out.println(person2.getName());
- session.close();
- }
- }
测试结果为:
- Hibernate: insert into t_identity_card (identity, id) values (?, ?)
- sean
只向t_identity_card表中插入了数据,t_person表为空,由于没有设置关联关系的cascade属性,在持久化一张表的时候,并不会级联的持久化另一张表
将t_identity_card表的映射文件中的关联关系修改为:<one-to-one name="person" class="com.po.Person"cascade="all" />
- Hibernate: select person_.id, person_.name as name1_, person_.age as age1_
- from t_person person_ where person_.id=?
- Hibernate: insert into t_identity_card (identity, id) values (?, ?)
- Hibernate: insert into t_person (name, age, id) values (?, ?, ?)
- sean
双向一对一主键关联:
这时需要对t_person表的配置做一些修改:
- public class Person implements Serializable {
- private static final long serialVersionUID = 1L;
- private int id;
- private String name;
- private int age;
- private IdentityCard identityCard;//新增
- 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 int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- public IdentityCard getIdentityCard() {
- return identityCard;
- }
- public void setIdentityCard(IdentityCard identityCard) {
- this.identityCard = identityCard;
- }
- }
- <?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.po.Person" table="t_person">
- <id name="id" column="id" type="integer">
- <generator class="native"/>
- </id>
- <property name="name" column="name" type="string"/>
- <property name="age" column="age" type="integer"/>
- <!--新增-->
- <one-to-one name="identityCard" class="com.po.IdentityCard" cascade="all" />
- </class>
- </hibernate-mapping>
测试一下:
- public class Test {
- public static void main(String[] args) {
- Configuration conf = new Configuration();
- SessionFactory sessionFactory = conf.configure().buildSessionFactory();
- Session session = sessionFactory.openSession();
- IdentityCard identityCard = new IdentityCard();
- identityCard.setIdentity(123456);
- Person person = new Person();
- person.setId(1);
- person.setName("sean");
- person.setAge(25);
- identityCard.setPerson(person);
- person.setIdentityCard(identityCard);
- Transaction tran = session.beginTransaction();
- session.save(identityCard);
- tran.commit();
- Person person_tmp = (Person)session.get(Person.class, 1);
- IdentityCard id_card_tmp = person_tmp.getIdentityCard();
- System.out.println(id_card_tmp.getIdentity());
- id_card_tmp = (IdentityCard)session.get(IdentityCard.class, 1);
- person_tmp = id_card_tmp.getPerson();
- System.out.println(person_tmp.getName());
- session.close();
- }
- }
测试结果为:
- Hibernate: select person_.id, person_.name as name1_, person_.age
- as age1_ from t_person person_ where person_.id=?
- Hibernate: insert into t_identity_card (identity, id) values (?, ?)
- Hibernate: insert into t_person (name, age, id) values (?, ?, ?)
- 123456
- sean
Hibernate首先持久化了identityCard对象,将测试代码中的session.save(identityCard)修改为session.save(person),再次测试:
- Hibernate: insert into t_person (name, age, id) values (?, ?, ?)
- Exception in thread "main" org.hibernate.exception.ConstraintViolationException:
- Could not execute JDBC batch update
- ......
- Caused by: java.sql.BatchUpdateException: Cannot add or update a child row:
- a foreign key constraint fails (`mydb`.`t_person`, CONSTRAINT `FK_ID`
- FOREIGN KEY (`id`) REFERENCES `t_identity_card` (`id`))
- ......
Hibernate这次首先持久化了person对象,由于t_person表中的id字段建立了外键关系,故持久化失败,删除掉t_person表中id字段的外键关系之后,插入正常:
- Hibernate: insert into t_person (name, age, id) values (?, ?, ?)
- Hibernate: insert into t_identity_card (identity, id) values (?, ?)
- 123456
- sean