Hibernate的一对一映射
一、创建Java工程,新建Lib文件夹,加入Hibernate和数据库(如MySql、Oracle、SqlServer等)的Jar包,创建 hibernate.cfg.xml 文件,并配置,配置项如下:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <!DOCTYPE hibernate-configuration PUBLIC 3 "-//Hibernate/Hibernate Configuration DTD 3.0//EN" 4 "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> 5 <hibernate-configuration> 6 <session-factory> 7 8 <!-- 配置连接数据库的基本信息 --> 9 <property name="connection.username">root</property> 10 <property name="connection.password"></property> 11 <property name="connection.driver_class">com.mysql.jdbc.Driver</property> 12 <!-- <property name="connection.url">jdbc:mysql:///mis</property> --> 13 <property name="connection.url"> 14 <!-- 解决Mysql插入中文乱码的问题 --> 15 <![CDATA[jdbc:mysql://localhost:3306/mis?useUnicode=true&characterEncoding=utf8]]> 16 </property> 17 18 19 <!-- 配置 hibernate 的基本信息 --> 20 <!-- hibernate 所使用的数据库方言 --> 21 <property name="dialect">org.hibernate.dialect.MySQL5Dialect</property> 22 23 <!-- 执行操作时是否在控制台打印 SQL --> 24 <property name="show_sql">true</property> 25 26 <!-- 是否对 SQL 进行格式化 --> 27 <property name="format_sql">true</property> 28 29 <!-- 指定自动生成数据表的策略 --> 30 <property name="hbm2ddl.auto">update</property> 31 32 <!-- 设置 Hibernate 的事务隔离级别 2:读已提交的记录--> 33 <property name="connection.isolation">2</property> 34 35 <!-- 删除对象后, 使其 OID 置为 null --> 36 <property name="use_identifier_rollback">true</property> 37 38 <!-- 配置 C3P0 数据源 --> 39 <property name="hibernate.c3p0.max_size">10</property> 40 <property name="hibernate.c3p0.min_size">5</property> 41 <property name="c3p0.acquire_increment">2</property> 42 43 <property name="c3p0.idle_test_period">2000</property> 44 <property name="c3p0.timeout">2000</property> 45 46 <property name="c3p0.max_statements">10</property> 47 48 <!-- 设定 JDBC 的 Statement 读取数据的时候每次从数据库中取出的记录条数 --> 49 <property name="hibernate.jdbc.fetch_size">100</property> 50 51 <!-- 设定对数据库进行批量删除,批量更新和批量插入的时候的批次大小 --> 52 <property name="jdbc.batch_size">30</property> 53 54 <!-- 指定关联的 .hbm.xml 文件 --> 55 <!-- 56 <mapping resource="com/mcs/hibernate/entities/News.hbm.xml" /> 57 <mapping resource="com/mcs/hibernate/entities/Worker.hbm.xml" /> 58 59 <mapping resource="com/mcs/hibernate/entities/n21/Customer.hbm.xml" /> 60 <mapping resource="com/mcs/hibernate/entities/n21/Order.hbm.xml" /> 61 --> 62 63 <mapping resource="com/mcs/hibernate/entities/n21/both/Customer.hbm.xml" /> 64 <mapping resource="com/mcs/hibernate/entities/n21/both/Order.hbm.xml" /> 65 66 </session-factory> 67 68 </hibernate-configuration>
二、基于外键的一对一映射
1、创建Java实体类
1 package com.mcs.hibernate.entities.onetoone.foreign; 2 3 public class Department { 4 5 private Integer departmentId; 6 private String departmentName; 7 8 private Manager manager; 9 10 public Integer getDepartmentId() { 11 return departmentId; 12 } 13 14 public void setDepartmentId(Integer departmentId) { 15 this.departmentId = departmentId; 16 } 17 18 public String getDepartmentName() { 19 return departmentName; 20 } 21 22 public void setDepartmentName(String departmentName) { 23 this.departmentName = departmentName; 24 } 25 26 public Manager getManager() { 27 return manager; 28 } 29 30 public void setManager(Manager manager) { 31 this.manager = manager; 32 } 33 34 35 36 }
1 package com.mcs.hibernate.entities.onetoone.foreign; 2 3 public class Manager { 4 5 private Integer managerId; 6 private String managerName; 7 8 private Department department; 9 10 public Integer getManagerId() { 11 return managerId; 12 } 13 14 public void setManagerId(Integer managerId) { 15 this.managerId = managerId; 16 } 17 18 public String getManagerName() { 19 return managerName; 20 } 21 22 public void setManagerName(String managerName) { 23 this.managerName = managerName; 24 } 25 26 public Department getDepartment() { 27 return department; 28 } 29 30 public void setDepartment(Department department) { 31 this.department = department; 32 } 33 34 35 36 }
2、根据实体类创建对应的 hbm.xml文件
1 <?xml version="1.0"?> 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 4 <!-- Generated 2015-10-28 13:38:17 by Hibernate Tools 3.5.0.Final --> 5 <hibernate-mapping> 6 <class name="com.mcs.hibernate.entities.onetoone.foreign.Department" table="DEPARTMENTS"> 7 <id name="departmentId" type="java.lang.Integer"> 8 <column name="DEPARTMENT_ID" /> 9 <generator class="native" /> 10 </id> 11 <property name="departmentName" type="java.lang.String"> 12 <column name="DEPARTMENT_NAME" /> 13 </property> 14 15 <!-- 使用 many-to-one 的方式来映射 1-1 关联关系 --> 16 <many-to-one name="manager" 17 class="com.mcs.hibernate.entities.onetoone.foreign.Manager" 18 column="MANAGER_ID" 19 unique="true"></many-to-one> 20 </class> 21 </hibernate-mapping>
1 <?xml version="1.0"?> 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 4 <!-- Generated 2015-10-28 13:38:17 by Hibernate Tools 3.5.0.Final --> 5 <hibernate-mapping> 6 <class name="com.mcs.hibernate.entities.onetoone.foreign.Manager" table="MANAGERS"> 7 <id name="managerId" type="java.lang.Integer"> 8 <column name="MANAGER_ID" /> 9 <generator class="native" /> 10 </id> 11 <property name="managerName" type="java.lang.String"> 12 <column name="MANAGER_NAME" /> 13 </property> 14 15 <!-- 映射 1-1 的关联关系: 在对应的数据表中已经有外键了, 当前持久化类使用 one-to-one 进行映射 --> 16 <!-- 17 没有外键的一端需要使用one-to-one元素,该元素使用 property-ref 属性指定使用被关联实体主键以外的字段作为关联字段 18 --> 19 <one-to-one name="department" 20 class="com.mcs.hibernate.entities.onetoone.foreign.Department" 21 property-ref="manager"> 22 </one-to-one> 23 </class> 24 </hibernate-mapping>
注:
1、在有外键的一端需要使用many-to-one元素,该元素使用 unique="true" 属性来约束唯一值,并指定外键栏 column="MANAGER_ID"
2、没有外键的一端需要使用one-to-one元素,该元素使用 property-ref 属性指定使用被关联实体主键以外的字段作为关联字段
3、在保存操作中,建议先保存没有外键列的那个对象. 这样会减少 UPDATE 语句
4、默认情况下对关联属性使用懒加载,注意可能会出现懒加载异常的问题。
5、在查询没有外键的实体对象时, 使用的左外连接查询, 一并查询出其关联的对象,并已经进行初始化。
三、基于主键的一对一映射
1、创建Java实体类
1 package com.mcs.hibernate.entities.onetoone.primary; 2 3 public class Department { 4 5 private Integer departmentId; 6 private String departmentName; 7 8 private Manager manager; 9 10 public Integer getDepartmentId() { 11 return departmentId; 12 } 13 14 public void setDepartmentId(Integer departmentId) { 15 this.departmentId = departmentId; 16 } 17 18 public String getDepartmentName() { 19 return departmentName; 20 } 21 22 public void setDepartmentName(String departmentName) { 23 this.departmentName = departmentName; 24 } 25 26 public Manager getManager() { 27 return manager; 28 } 29 30 public void setManager(Manager manager) { 31 this.manager = manager; 32 } 33 34 35 36 }
1 package com.mcs.hibernate.entities.onetoone.primary; 2 3 public class Manager { 4 5 private Integer managerId; 6 private String managerName; 7 8 private Department department; 9 10 public Integer getManagerId() { 11 return managerId; 12 } 13 14 public void setManagerId(Integer managerId) { 15 this.managerId = managerId; 16 } 17 18 public String getManagerName() { 19 return managerName; 20 } 21 22 public void setManagerName(String managerName) { 23 this.managerName = managerName; 24 } 25 26 public Department getDepartment() { 27 return department; 28 } 29 30 public void setDepartment(Department department) { 31 this.department = department; 32 } 33 34 35 36 }
2、根据实体类创建对应的 hbm.xml文件
1 <?xml version="1.0"?> 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 4 <!-- Generated 2015-10-28 13:38:17 by Hibernate Tools 3.5.0.Final --> 5 <hibernate-mapping> 6 <class name="com.mcs.hibernate.entities.onetoone.primary.Department" table="DEPARTMENTS"> 7 <id name="departmentId" type="java.lang.Integer"> 8 <column name="DEPARTMENT_ID" /> 9 <!-- 使用外键的方式来生成当前的主键 --> 10 <generator class="foreign" > 11 <!-- property 属性指定使用当前持久化类的哪一个属性的主键作为外键 --> 12 <param name="property">manager</param> 13 </generator> 14 </id> 15 <property name="departmentName" type="java.lang.String"> 16 <column name="DEPARTMENT_NAME" /> 17 </property> 18 19 <!-- 20 采用 foreign 主键生成器策略的一端增加 one-to-one 元素映射关联属性, 21 其 one-to-one 节点还应增加 constrained=true 属性, 以使当前的主键上添加外键约束 22 --> 23 <one-to-one name="manager" 24 class="com.mcs.hibernate.entities.onetoone.primary.Manager" 25 constrained="true"> 26 </one-to-one> 27 </class> 28 </hibernate-mapping>
1 <?xml version="1.0"?> 2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> 4 <!-- Generated 2015-10-28 13:38:17 by Hibernate Tools 3.5.0.Final --> 5 <hibernate-mapping> 6 <class name="com.mcs.hibernate.entities.onetoone.primary.Manager" table="MANAGERS"> 7 <id name="managerId" type="java.lang.Integer"> 8 <column name="MANAGER_ID" /> 9 <generator class="native" /> 10 </id> 11 <property name="managerName" type="java.lang.String"> 12 <column name="MANAGER_NAME" /> 13 </property> 14 15 <one-to-one name="department" 16 class="com.mcs.hibernate.entities.onetoone.primary.Department"> 17 </one-to-one> 18 </class> 19 </hibernate-mapping>
注:
1、其中一端会使用另外一端的主键做为主键,另外一端代码采用 foreign 主键生成器策略的一端增加 one-to-one 元素映射关联属性,其 one-to-one 节点还应增加 constrained=true 属性, 以使当前的主键上添加外键约束。
2、在保存操作中,建议先保存没有外键列的那个对象. 这样会减少 UPDATE 语句
3、默认情况下对关联属性使用懒加载,注意可能会出现懒加载异常的问题。