Hibernate one-to-one一对一映射

本文介绍Hibernate中一对一关系映射的三种实现方式:通过外键、主键和关系表实现。详细展示了每种方式的数据库表结构、Java实体类定义及配置文件。

hibernate 关系映射 one-to-one主要有三种实现方式
1.通过外键方式实现
以学生和电脑为例(Student-Computer)
建表sql语句:
Java代码 复制代码
  1. CREATEDATABASE`onetoone`
  2. CHARACTERSET'utf8';
  3. USE`onetoone`;
  4. DROPTABLEIFEXISTS`student`;
  5. CREATETABLE`student`(
  6. `id`int(11)NOTNULLauto_increment,
  7. `name`varchar(255)NOTNULL,
  8. PRIMARYKEY(`id`)
  9. )ENGINE=InnoDBDEFAULTCHARSET=utf8;
  10. DROPTABLEIFEXISTS`computer`;
  11. CREATETABLE`computer`(
  12. `id`int(11)NOTNULLauto_increment,
  13. `name`varchar(255)NOTNULL,
  14. `student_id`int(11),
  15. foreignkey(`student_id`)referencesstudent(`id`),
  16. PRIMARYKEY(`id`)
  17. )ENGINE=InnoDBDEFAULTCHARSET=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:
Java代码 复制代码
  1. packagecom.domain;
  2. publicclassStudentimplementsjava.io.Serializable{
  3. privateIntegerid;
  4. privateStringname;
  5. privateComputercomputer;
  6. publicStudent(){
  7. }
  8. publicStudent(Stringname){
  9. this.name=name;
  10. }
  11. publicIntegergetId(){
  12. returnthis.id;
  13. }
  14. publicvoidsetId(Integerid){
  15. this.id=id;
  16. }
  17. publicStringgetName(){
  18. returnthis.name;
  19. }
  20. publicvoidsetName(Stringname){
  21. this.name=name;
  22. }
  23. publicComputergetComputer(){
  24. returncomputer;
  25. }
  26. publicvoidsetComputer(Computercomputer){
  27. this.computer=computer;
  28. }
  29. }
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:
Java代码 复制代码
  1. packagecom.domain;
  2. publicclassComputerimplementsjava.io.Serializable{
  3. privateIntegerid;
  4. privateStudentstudent;
  5. privateStringname;
  6. publicComputer(){
  7. }
  8. publicComputer(Stringname){
  9. this.name=name;
  10. }
  11. publicComputer(Studentstudent,Stringname){
  12. this.student=student;
  13. this.name=name;
  14. }
  15. publicIntegergetId(){
  16. returnthis.id;
  17. }
  18. publicvoidsetId(Integerid){
  19. this.id=id;
  20. }
  21. publicStudentgetStudent(){
  22. returnthis.student;
  23. }
  24. publicvoidsetStudent(Studentstudent){
  25. this.student=student;
  26. }
  27. publicStringgetName(){
  28. returnthis.name;
  29. }
  30. publicvoidsetName(Stringname){
  31. this.name=name;
  32. }
  33. }
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:
Java代码 复制代码
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <!DOCTYPEhibernate-mappingPUBLIC"-//Hibernate/HibernateMappingDTD3.0//EN"
  3. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
  4. <hibernate-mapping>
  5. <classname="com.domain.Student"table="student"catalog="onetoone">
  6. <idname="id"type="java.lang.Integer">
  7. <columnname="id"/>
  8. <generatorclass="native"/>
  9. </id>
  10. <propertyname="name"type="java.lang.String">
  11. <columnname="name"not-null="true"/>
  12. </property>
  13. <!--class可以不写,因为根据name的值computer(属性),会通过反射自动找到属于哪个类的-->
  14. <one-to-onecascade="delete,save-update"name="computer"class="com.domain.Computer"property-ref="student"></one-to-one>
  15. </class>
  16. </hibernate-mapping>
<?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>


Computer.hbm.xml:
Java代码 复制代码
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <!DOCTYPEhibernate-mappingPUBLIC"-//Hibernate/HibernateMappingDTD3.0//EN"
  3. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
  4. <hibernate-mapping>
  5. <classname="com.domain.Computer"table="computer"catalog="onetoone">
  6. <idname="id"type="java.lang.Integer">
  7. <columnname="id"/>
  8. <generatorclass="native"/>
  9. </id>
  10. <propertyname="name"type="java.lang.String">
  11. <columnname="name"not-null="true"/>
  12. </property>
  13. <!--many开头的是代表该表持有外键-->
  14. <many-to-onename="student"class="com.domain.Student"unique="true">
  15. <columnname="student_id"/>
  16. </many-to-one>
  17. </class>
  18. </hibernate-mapping>
<?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>


测试类:
Java代码 复制代码
  1. packagecom.domain;
  2. importorg.hibernate.Query;
  3. importorg.hibernate.Session;
  4. importcom.util.HibernateSessionFactory;
  5. publicclassTest{
  6. publicstaticvoidmain(String[]args){
  7. Sessionsession=HibernateSessionFactory.getSession();
  8. //save
  9. Studentstudent=newStudent();
  10. student.setName("student9");
  11. Computercomputer=newComputer();
  12. computer.setName("Intel9");
  13. //computer.setStudent(student)和student.setComputer(computer);都必须要
  14. computer.setStudent(student);
  15. student.setComputer(computer);
  16. session.save(student);
  17. /**
  18. 执行的sql:
  19. Hibernate:insertintoonetoone.student(name)values(?)
  20. Hibernate:insertintoonetoone.computer(name,student_id)values(?,?)
  21. */
  22. //
  23. session.beginTransaction().commit();
  24. //query
  25. //Stringhql="fromStudentwherename=?";
  26. //Queryquery=session.createQuery(hql);
  27. //query.setString(0,"student3");
  28. //
  29. //Studentstudent=(Student)query.uniqueResult();
  30. //System.out.println(student.getId()+":"+student.getComputer().getName());
  31. //delete
  32. //Studentstudent=(Student)session.load(Student.class,newInteger(1));
  33. //session.delete(student);
  34. //session.beginTransaction().commit();
  35. /**
  36. 执行的sql为:
  37. Hibernate:selectstudent0_.idasid0_1_,student0_.nameasname0_1_,computer1_.idasid1_0_,computer1_.nameasname1_0_,computer1_.student_idasstudent3_1_0_fromonetoone.studentstudent0_leftouterjoinonetoone.computercomputer1_onstudent0_.id=computer1_.student_idwherestudent0_.id=?
  38. Hibernate:deletefromonetoone.computerwhereid=?
  39. Hibernate:deletefromonetoone.studentwhereid=?
  40. */
  41. session.close();
  42. }
  43. }
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();
	}

}


2.通过主键方式实现(一个表的主键由另一个表的主键决定),在这里Computer的主键由Student的主键决定。
Student.hbm.xml:
Java代码 复制代码
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <!DOCTYPEhibernate-mappingPUBLIC"-//Hibernate/HibernateMappingDTD3.0//EN"
  3. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
  4. <hibernate-mapping>
  5. <classname="com.domain.Student"table="student"catalog="onetoone">
  6. <idname="id"type="java.lang.Integer">
  7. <columnname="id"/>
  8. <generatorclass="native"/>
  9. </id>
  10. <propertyname="name"type="java.lang.String">
  11. <columnname="name"not-null="true"/>
  12. </property>
  13. <!--class可以不写,因为根据name的值computer(属性),会通过反射自动找到属于哪个类的
  14. <one-to-onecascade="delete,save-update"name="computer"class="com.domain.Computer"property-ref="student"></one-to-one>
  15. -->
  16. <one-to-onename="computer"/>
  17. </class>
  18. </hibernate-mapping>
<?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>


Comuter.hbm.xml:
Java代码 复制代码
  1. <?xmlversion="1.0"encoding="utf-8"?>
  2. <!DOCTYPEhibernate-mappingPUBLIC"-//Hibernate/HibernateMappingDTD3.0//EN"
  3. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
  4. <hibernate-mapping>
  5. <classname="com.domain.Computer"table="computer"catalog="onetoone">
  6. <idname="id"type="java.lang.Integer">
  7. <columnname="id"/>
  8. <!--generatorclass="native"/-->
  9. <!--Computer的主键由Student的主键决定,可以看成是外键-->
  10. <generatorclass="foreign">
  11. <paramname="property">student</param>
  12. </generator>
  13. </id>
  14. <propertyname="name"type="java.lang.String">
  15. <columnname="name"not-null="true"/>
  16. </property>
  17. <!--many开头的是代表该表持有外键
  18. <many-to-onename="student"class="com.domain.Student"unique="true">
  19. <columnname="student_id"/>
  20. </many-to-one>-->
  21. <one-to-onename="student"/>
  22. </class>
  23. </hibernate-mapping>
<?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>


TestMainKey.java:

Java代码 复制代码
  1. packagecom.domain;
  2. importorg.hibernate.Session;
  3. importcom.util.HibernateSessionFactory;
  4. publicclassTestMainKey{
  5. publicstaticvoidmain(String[]args){
  6. Sessionsession=HibernateSessionFactory.getSession();
  7. //save
  8. Studentstudent=newStudent();
  9. student.setName("student15");
  10. Computercomputer=newComputer();
  11. computer.setName("Intel15");
  12. computer.setStudent(student);
  13. //student.setComputer(computer);
  14. //因为save2个表,所以不需要双向赋值
  15. session.save(student);
  16. session.save(computer);
  17. session.beginTransaction().commit();
  18. session.close();
  19. }
  20. }
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();
	}
}





3.通过关系表实现:
Java代码 复制代码
  1. DROPTABLEIFEXISTS`st`;
  2. createtablestu_com(
  3. stu_idintnotnull,
  4. com_idintnotnull
  5. )ENGINE=InnoDBDEFAULTCHARSET=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;

Java代码 复制代码
  1. <!--optional="true"的意思是只有当stu_id和com_id都不为空时才在关系表里插入。这样也会插入
  2. 2遍,所以需要inverse="true"把一方设置为虚的。即不让插入到关系表中-->
  3. <jointable="stu-com"optional="true"inverse="true">
  4. <keycolumn="com_id"/>
  5. <many-to-onename="student"column="stu_id"unique="true"/>
  6. </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>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值