hibernate 关系映射
one-to-one主要有三种实现方式
1.通过外键方式实现
以学生和电脑为例(Student-Computer)
建表sql语句:
Student.java:
Computer.java:
Student.hbm.xml:
Computer.hbm.xml:
测试类:
2.通过主键方式实现(一个表的主键由另一个表的主键决定),在这里Computer的主键由Student的主键决定。
Student.hbm.xml:
Comuter.hbm.xml:
TestMainKey.java:
3.通过关系表实现:
1.通过外键方式实现
以学生和电脑为例(Student-Computer)
建表sql语句:
- CREATE DATABASE `onetoone`
- CHARACTER SET 'utf8';
- USE `onetoone`;
- DROP TABLE IF EXISTS `student`;
- CREATE TABLE `student` (
- `id` int(11) NOT NULL auto_increment,
- `name` varchar(255) NOT NULL,
- PRIMARY KEY (`id`)
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
- DROP TABLE IF EXISTS `computer`;
- CREATE TABLE `computer` (
- `id` int(11) NOT NULL auto_increment,
- `name` varchar(255) NOT NULL,
- `student_id` int(11) ,
- foreign key (`student_id`) references student(`id`),
- PRIMARY KEY (`id`)
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
- CREATE DATABASE `onetoone`
- CHARACTER SET 'utf8';
- USE `onetoone`;
- DROP TABLE IF EXISTS `student`;
- CREATE TABLE `student` (
- `id` int(11) NOT NULL auto_increment,
- `name` varchar(255) NOT NULL,
- PRIMARY KEY (`id`)
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
- DROP TABLE IF EXISTS `computer`;
- CREATE TABLE `computer` (
- `id` int(11) NOT NULL auto_increment,
- `name` varchar(255) NOT NULL,
- `student_id` int(11) ,
- foreign key (`student_id`) references student(`id`),
- PRIMARY KEY (`id`)
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Student.java:
- package com.domain;
- public class Student implements java.io.Serializable {
- private Integer id;
- private String name;
- private Computer computer;
- public Student() {
- }
- public Student(String name) {
- this.name = name;
- }
- public Integer getId() {
- return this.id;
- }
- public void setId(Integer id) {
- this.id = id;
- }
- public String getName() {
- return this.name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public Computer getComputer() {
- return computer;
- }
- public void setComputer(Computer computer) {
- this.computer = computer;
- }
- }
- package com.domain;
- public class Student implements java.io.Serializable {
- private Integer id;
- private String name;
- private Computer computer;
- public Student() {
- }
- public Student(String name) {
- this.name = name;
- }
- public Integer getId() {
- return this.id;
- }
- public void setId(Integer id) {
- this.id = id;
- }
- public String getName() {
- return this.name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public Computer getComputer() {
- return computer;
- }
- public void setComputer(Computer computer) {
- this.computer = computer;
- }
- }
Computer.java:
- package com.domain;
- public class Computer implements java.io.Serializable {
- private Integer id;
- private Student student;
- private String name;
- public Computer() {
- }
- public Computer(String name) {
- this.name = name;
- }
- public Computer(Student student, String name) {
- this.student = student;
- this.name = name;
- }
- public Integer getId() {
- return this.id;
- }
- public void setId(Integer id) {
- this.id = id;
- }
- public Student getStudent() {
- return this.student;
- }
- public void setStudent(Student student) {
- this.student = student;
- }
- public String getName() {
- return this.name;
- }
- public void setName(String name) {
- this.name = name;
- }
- }
- package com.domain;
- public class Computer implements java.io.Serializable {
- private Integer id;
- private Student student;
- private String name;
- public Computer() {
- }
- public Computer(String name) {
- this.name = name;
- }
- public Computer(Student student, String name) {
- this.student = student;
- this.name = name;
- }
- public Integer getId() {
- return this.id;
- }
- public void setId(Integer id) {
- this.id = id;
- }
- public Student getStudent() {
- return this.student;
- }
- public void setStudent(Student student) {
- this.student = student;
- }
- public String getName() {
- return this.name;
- }
- public void setName(String name) {
- this.name = name;
- }
- }
Student.hbm.xml:
- <?xml version="1.0" encoding="utf-8"?>
- <!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.domain.Student" table="student" catalog="onetoone">
- <id name="id" type="java.lang.Integer">
- <column name="id" />
- <generator class="native" />
- </id>
- <property name="name" type="java.lang.String">
- <column name="name" not-null="true" />
- </property>
- <!-- class可以不写,因为根据name的值computer(属性),会通过反射自动找到属于哪个类的 -->
- <one-to-one cascade="delete,save-update" name="computer" class="com.domain.Computer" property-ref="student"></one-to-one>
- </class>
- </hibernate-mapping>
- <?xml version="1.0" encoding="utf-8"?>
- <!DOCTYPE <span class="hilite1"><span style="background-color: #ffff00;">hibernate</span></span>-mapping PUBLIC "-//<span class="hilite1"><span style="background-color: #ffff00;">Hibernate</span></span>/<span class="hilite1"><span style="background-color: #ffff00;">Hibernate</span></span> Mapping DTD 3.0//EN"
- "http://<span class="hilite1"><span style="background-color: #ffff00;">hibernate</span></span>.sourceforge.net/<span class="hilite1"><span style="background-color: #ffff00;">hibernate</span></span>-mapping-3.0.dtd">
- <<span class="hilite1"><span style="background-color: #ffff00;">hibernate</span></span>-mapping>
- <class name="com.domain.Student" table="student" catalog="onetoone">
- <id name="id" type="java.lang.Integer">
- <column name="id" />
- <generator class="native" />
- </id>
- <property name="name" type="java.lang.String">
- <column name="name" not-null="true" />
- </property>
- <!-- class可以不写,因为根据name的值computer(属性),会通过反射自动找到属于哪个类的 -->
- <<span class="hilite2"><span style="background-color: #55ff55;">one-to-one</span></span> cascade="delete,save-update" name="computer" class="com.domain.Computer" property-ref="student"></<span class="hilite2"><span style="background-color: #55ff55;">one-to-one</span></span>>
- </class>
- </<span class="hilite1"><span style="background-color: #ffff00;">hibernate</span></span>-mapping>
Computer.hbm.xml:
- <?xml version="1.0" encoding="utf-8"?>
- <!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.domain.Computer" table="computer" catalog="onetoone">
- <id name="id" type="java.lang.Integer">
- <column name="id" />
- <generator class="native" />
- </id>
- <property name="name" type="java.lang.String">
- <column name="name" not-null="true" />
- </property>
- <!-- many开头的是代表该表持有外键 -->
- <many-to-one name="student" class="com.domain.Student" unique="true">
- <column name="student_id" />
- </many-to-one>
- </class>
- </hibernate-mapping>
- <?xml version="1.0" encoding="utf-8"?>
- <!DOCTYPE <span class="hilite1"><span style="background-color: #ffff00;">hibernate</span></span>-mapping PUBLIC "-//<span class="hilite1"><span style="background-color: #ffff00;">Hibernate</span></span>/<span class="hilite1"><span style="background-color: #ffff00;">Hibernate</span></span> Mapping DTD 3.0//EN"
- "http://<span class="hilite1"><span style="background-color: #ffff00;">hibernate</span></span>.sourceforge.net/<span class="hilite1"><span style="background-color: #ffff00;">hibernate</span></span>-mapping-3.0.dtd">
- <<span class="hilite1"><span style="background-color: #ffff00;">hibernate</span></span>-mapping>
- <class name="com.domain.Computer" table="computer" catalog="onetoone">
- <id name="id" type="java.lang.Integer">
- <column name="id" />
- <generator class="native" />
- </id>
- <property name="name" type="java.lang.String">
- <column name="name" not-null="true" />
- </property>
- <!-- many开头的是代表该表持有外键 -->
- <many-to-one name="student" class="com.domain.Student" unique="true">
- <column name="student_id" />
- </many-to-one>
- </class>
- </<span class="hilite1"><span style="background-color: #ffff00;">hibernate</span></span>-mapping>
测试类:
- package com.domain;
- import org.hibernate.Query;
- import org.hibernate.Session;
- import com.util.HibernateSessionFactory;
- public class Test {
- public static void main(String[] args){
- Session session = HibernateSessionFactory.getSession();
- //save
- Student student = new Student();
- student.setName("student9");
- Computer computer = new Computer();
- computer.setName("Intel 9");
- //computer.setStudent(student)和student.setComputer(computer);都必须要
- computer.setStudent(student);
- student.setComputer(computer);
- session.save(student);
- /**
- 执行的sql:
- Hibernate: insert into onetoone.student (name) values (?)
- Hibernate: insert into onetoone.computer (name, student_id) values (?, ?)
- */
- //
- session.beginTransaction().commit();
- //query
- // String hql = "from Student where name=?";
- // Query query = session.createQuery(hql);
- // query.setString(0, "student3");
- //
- // Student student = (Student)query.uniqueResult();
- // System.out.println(student.getId() + " : " + student.getComputer().getName());
- //delete
- // Student student = (Student)session.load(Student.class, new Integer(1));
- // session.delete(student);
- // session.beginTransaction().commit();
- /**
- 执行的sql为:
- Hibernate: select student0_.id as id0_1_, student0_.name as name0_1_, computer1_.id as id1_0_, computer1_.name as name1_0_, computer1_.student_id as student3_1_0_ from onetoone.student student0_ left outer join onetoone.computer computer1_ on student0_.id=computer1_.student_id where student0_.id=?
- Hibernate: delete from onetoone.computer where id=?
- Hibernate: delete from onetoone.student where id=?
- */
- session.close();
- }
- }
- package com.domain;
- import org.<span class="hilite1"><span style="background-color: #ffff00;">hibernate</span></span>.Query;
- import org.<span class="hilite1"><span style="background-color: #ffff00;">hibernate</span></span>.Session;
- import com.util.HibernateSessionFactory;
- public class Test {
- public static void main(String[] args){
- Session session = HibernateSessionFactory.getSession();
- //save
- Student student = new Student();
- student.setName("student9");
- Computer computer = new Computer();
- computer.setName("Intel 9");
- //computer.setStudent(student)和student.setComputer(computer);都必须要
- computer.setStudent(student);
- student.setComputer(computer);
- session.save(student);
- /**
- 执行的sql:
- <span class="hilite1"><span style="background-color: #ffff00;">Hibernate</span></span>: insert into onetoone.student (name) values (?)
- <span class="hilite1"><span style="background-color: #ffff00;">Hibernate</span></span>: insert into onetoone.computer (name, student_id) values (?, ?)
- */
- //
- session.beginTransaction().commit();
- //query
- // String hql = "from Student where name=?";
- // Query query = session.createQuery(hql);
- // query.setString(0, "student3");
- //
- // Student student = (Student)query.uniqueResult();
- // System.out.println(student.getId() + " : " + student.getComputer().getName());
- //delete
- // Student student = (Student)session.load(Student.class, new Integer(1));
- // session.delete(student);
- // session.beginTransaction().commit();
- /**
- 执行的sql为:
- <span class="hilite1"><span style="background-color: #ffff00;">Hibernate</span></span>: select student0_.id as id0_1_, student0_.name as name0_1_, computer1_.id as id1_0_, computer1_.name as name1_0_, computer1_.student_id as student3_1_0_ from onetoone.student student0_ left outer join onetoone.computer computer1_ on student0_.id=computer1_.student_id where student0_.id=?
- <span class="hilite1"><span style="background-color: #ffff00;">Hibernate</span></span>: delete from onetoone.computer where id=?
- <span class="hilite1"><span style="background-color: #ffff00;">Hibernate</span></span>: delete from onetoone.student where id=?
- */
- session.close();
- }
- }
2.通过主键方式实现(一个表的主键由另一个表的主键决定),在这里Computer的主键由Student的主键决定。
Student.hbm.xml:
- <?xml version="1.0" encoding="utf-8"?>
- <!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.domain.Student" table="student" catalog="onetoone">
- <id name="id" type="java.lang.Integer">
- <column name="id" />
- <generator class="native" />
- </id>
- <property name="name" type="java.lang.String">
- <column name="name" not-null="true" />
- </property>
- <!-- class可以不写,因为根据name的值computer(属性),会通过反射自动找到属于哪个类的
- <one-to-one cascade="delete,save-update" name="computer" class="com.domain.Computer" property-ref="student"></one-to-one>
- -->
- <one-to-one name="computer"/>
- </class>
- </hibernate-mapping>
- <?xml version="1.0" encoding="utf-8"?>
- <!DOCTYPE <span class="hilite1"><span style="background-color: #ffff00;">hibernate</span></span>-mapping PUBLIC "-//<span class="hilite1"><span style="background-color: #ffff00;">Hibernate</span></span>/<span class="hilite1"><span style="background-color: #ffff00;">Hibernate</span></span> Mapping DTD 3.0//EN"
- "http://<span class="hilite1"><span style="background-color: #ffff00;">hibernate</span></span>.sourceforge.net/<span class="hilite1"><span style="background-color: #ffff00;">hibernate</span></span>-mapping-3.0.dtd">
- <<span class="hilite1"><span style="background-color: #ffff00;">hibernate</span></span>-mapping>
- <class name="com.domain.Student" table="student" catalog="onetoone">
- <id name="id" type="java.lang.Integer">
- <column name="id" />
- <generator class="native" />
- </id>
- <property name="name" type="java.lang.String">
- <column name="name" not-null="true" />
- </property>
- <!-- class可以不写,因为根据name的值computer(属性),会通过反射自动找到属于哪个类的
- <<span class="hilite2"><span style="background-color: #55ff55;">one-to-one</span></span> cascade="delete,save-update" name="computer" class="com.domain.Computer" property-ref="student"></<span class="hilite2"><span style="background-color: #55ff55;">one-to-one</span></span>>
- -->
- <<span class="hilite2"><span style="background-color: #55ff55;">one-to-one</span></span> name="computer"/>
- </class>
- </<span class="hilite1"><span style="background-color: #ffff00;">hibernate</span></span>-mapping>
Comuter.hbm.xml:
- <?xml version="1.0" encoding="utf-8"?>
- <!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.domain.Computer" table="computer" catalog="onetoone">
- <id name="id" type="java.lang.Integer">
- <column name="id" />
- <!--generator class="native" /-->
- <!--Computer的主键由Student的主键决定,可以看成是外键-->
- <generator class="foreign">
- <param name="property">student</param>
- </generator>
- </id>
- <property name="name" type="java.lang.String">
- <column name="name" not-null="true" />
- </property>
- <!-- many开头的是代表该表持有外键
- <many-to-one name="student" class="com.domain.Student" unique="true">
- <column name="student_id" />
- </many-to-one> -->
- <one-to-one name="student"/>
- </class>
- </hibernate-mapping>
- <?xml version="1.0" encoding="utf-8"?>
- <!DOCTYPE <span class="hilite1"><span style="background-color: #ffff00;">hibernate</span></span>-mapping PUBLIC "-//<span class="hilite1"><span style="background-color: #ffff00;">Hibernate</span></span>/<span class="hilite1"><span style="background-color: #ffff00;">Hibernate</span></span> Mapping DTD 3.0//EN"
- "http://<span class="hilite1"><span style="background-color: #ffff00;">hibernate</span></span>.sourceforge.net/<span class="hilite1"><span style="background-color: #ffff00;">hibernate</span></span>-mapping-3.0.dtd">
- <<span class="hilite1"><span style="background-color: #ffff00;">hibernate</span></span>-mapping>
- <class name="com.domain.Computer" table="computer" catalog="onetoone">
- <id name="id" type="java.lang.Integer">
- <column name="id" />
- <!--generator class="native" /-->
- <!--Computer的主键由Student的主键决定,可以看成是外键-->
- <generator class="foreign">
- <param name="property">student</param>
- </generator>
- </id>
- <property name="name" type="java.lang.String">
- <column name="name" not-null="true" />
- </property>
- <!-- many开头的是代表该表持有外键
- <many-to-one name="student" class="com.domain.Student" unique="true">
- <column name="student_id" />
- </many-to-one> -->
- <<span class="hilite2"><span style="background-color: #55ff55;">one-to-one</span></span> name="student"/>
- </class>
- </<span class="hilite1"><span style="background-color: #ffff00;">hibernate</span></span>-mapping>
TestMainKey.java:
- package com.domain;
- import org.hibernate.Session;
- import com.util.HibernateSessionFactory;
- public class TestMainKey {
- public static void main(String[] args){
- Session session = HibernateSessionFactory.getSession();
- //save
- Student student = new Student();
- student.setName("student15");
- Computer computer = new Computer();
- computer.setName("Intel 15");
- computer.setStudent(student);
- // student.setComputer(computer);
- //因为save 2个表,所以不需要双向赋值
- session.save(student);
- session.save(computer);
- session.beginTransaction().commit();
- session.close();
- }
- }
- package com.domain;
- import org.<span class="hilite1"><span style="background-color: #ffff00;">hibernate</span></span>.Session;
- import com.util.HibernateSessionFactory;
- public class TestMainKey {
- public static void main(String[] args){
- Session session = HibernateSessionFactory.getSession();
- //save
- Student student = new Student();
- student.setName("student15");
- Computer computer = new Computer();
- computer.setName("Intel 15");
- computer.setStudent(student);
- // student.setComputer(computer);
- //因为save 2个表,所以不需要双向赋值
- session.save(student);
- session.save(computer);
- session.beginTransaction().commit();
- session.close();
- }
- }
3.通过关系表实现:
- DROP TABLE IF EXISTS `st`;
- create table stu_com(
- stu_id int not null,
- com_id int not null
- )ENGINE=InnoDB DEFAULT CHARSET=utf8;
- DROP TABLE IF EXISTS `st`;
- create table stu_com(
- stu_id int not null,
- com_id int not null
- )ENGINE=InnoDB DEFAULT CHARSET=utf8;
- <!--optional="true"的意思是只有当stu_id 和 com_id 都不为空时才在关系表里插入。这样也会插入
- 2遍,所以需要inverse="true"把一方设置为虚的。即不让插入到关系表中-->
- <join table="stu-com" optional="true" inverse="true">
- <key column="com_id"/>
- <many-to-one name="student" column="stu_id" unique="true"/>
- </join>
- <!--optional="true"的意思是只有当stu_id 和 com_id 都不为空时才在关系表里插入。这样也会插入
- 2遍,所以需要inverse="true"把一方设置为虚的。即不让插入到关系表中-->
- <join table="stu-com" optional="true" inverse="true">
- <key column="com_id"/>
- <many-to-one name="student" column="stu_id" unique="true"/>
- </join>