首页 > 代码库 > Hibernate(八):基于外键映射的1-1关联关系

Hibernate(八):基于外键映射的1-1关联关系

  • 背景:

一个部门只有一个一把手,这在程序开发中就会设计数据映射应该设置为一对一关联。

在hibernate代码开发中,实现这个业务有两种方案:

1)基于外键映射的1-1关联;

2)基于主键映射的1-1关联。

本篇文章主要是用来学习如何使用外键实现1-1关联关系。

  • 新建项目hibernate05

新建java project,引入依赖包,在src下添加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://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> 5 <hibernate-configuration> 6     <session-factory> 7         <property name="hibernate.connection.username">root</property> 8         <property name="hibernate.connection.password">123456</property> 9         <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>10         <property name="hibernate.connection.url">jdbc:mysql://localhost/hibernate_01</property>11 12         <!-- <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> 13             <property name="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</property> -->14         <property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>15 16         <property name="hibernate.show_sql">true</property>17 18         <property name="hibernate.format_sql">true</property>19 20         <property name="hibernate.hbm2ddl.auto">update</property>21 22         <property name="hibernate.current_session_context_class">thread</property>23 24         <property name="hibernate.c3p0.max_size">500</property>25         <property name="hibernate.c3p0.min_size">20</property>26         <property name="hibernate.c3p0.max_statements">10</property>27         <property name="hibernate.c3p0.timeout">2000</property>28         <property name="hibernate.c3p0.idle_test_period">2000</property>29         <property name="hibernate.c3p0.acquire_increment">10</property>30 31         <mapping resource="com/dx/hibernate005/onetoonebyforigenkey/Deparment.hbm.xml" />32         <mapping class="com.dx.hibernate005.onetoonebyforigenkey.Deparment" />33         <mapping resource="com/dx/hibernate005/onetoonebyforigenkey/Manager.hbm.xml" />34         <mapping class="com.dx.hibernate005.onetoonebyforigenkey.Manager" />35     </session-factory>36 </hibernate-configuration>
View Code

在src下新建包com.dx.hibernate005.onetoonebyforigenkey

在com.dx.hibernate005.onetoonebyforigenkey包下创建

Deparment.java

技术分享
 1 package com.dx.hibernate005.onetoonebyforigenkey; 2  3 public class Deparment { 4     private Integer departId; 5     private String departName; 6     private Manager manager; 7  8     public Deparment() { 9         super();10     }11 12     public Deparment(Integer departId, String departName) {13         super();14         this.departId = departId;15         this.departName = departName;16     }17 18     public Integer getDepartId() {19         return departId;20     }21 22     public void setDepartId(Integer departId) {23         this.departId = departId;24     }25 26     public String getDepartName() {27         return departName;28     }29 30     public void setDepartName(String departName) {31         this.departName = departName;32     }33 34     public Manager getManager() {35         return manager;36     }37 38     public void setManager(Manager manager) {39         this.manager = manager;40     }41 42 }
View Code

Deparment.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 2017-6-2 10:54:26 by Hibernate Tools 3.5.0.Final --> 5 <hibernate-mapping> 6     <class name="com.dx.hibernate005.onetoonebyforigenkey.Deparment" table="DEPARMENTS"> 7         <id name="departId" type="java.lang.Integer"> 8             <column name="DEPART_ID" /> 9             <generator class="native" />10         </id>11         <property name="departName" type="java.lang.String">12             <column name="DEPART_NAME" />13         </property>14         15         <!-- 在Deparment中定义一个Many-to-one就可以实现在Deparments表中多一个外键列 -->16         <many-to-one name="manager" class="com.dx.hibernate005.onetoonebyforigenkey.Manager" column="MANAGER_ID" unique="true"></many-to-one>17     </class>18 </hibernate-mapping>

Manager.java

技术分享
 1 package com.dx.hibernate005.onetoonebyforigenkey; 2  3 public class Manager { 4     private Integer managerId; 5     private String managerName; 6     private Deparment deparment; 7  8     public Manager() { 9         super();10     }11 12     public Manager(Integer managerId, String managerName) {13         super();14         this.managerId = managerId;15         this.managerName = managerName;16     }17 18     public Integer getManagerId() {19         return managerId;20     }21 22     public void setManagerId(Integer managerId) {23         this.managerId = managerId;24     }25 26     public String getManagerName() {27         return managerName;28     }29 30     public void setManagerName(String managerName) {31         this.managerName = managerName;32     }33 34     public Deparment getDeparment() {35         return deparment;36     }37 38     public void setDeparment(Deparment deparment) {39         this.deparment = deparment;40     }41 42 }
View Code

Deparment.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 2017-6-2 10:54:26 by Hibernate Tools 3.5.0.Final --> 5 <hibernate-mapping> 6     <class name="com.dx.hibernate005.onetoonebyforigenkey.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进行映射 -->16         <one-to-one name="deparment" class="com.dx.hibernate005.onetoonebyforigenkey.Deparment" property-ref="manager"></one-to-one>17     </class>18 </hibernate-mapping>

TestMain.java测试类,并引入JUnit4所需的依赖包。

package com.dx.hibernate005.onetoonebyforigenkey;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.Transaction;import org.hibernate.boot.Metadata;import org.hibernate.boot.MetadataSources;import org.hibernate.boot.model.naming.ImplicitNamingStrategyComponentPathImpl;import org.hibernate.boot.registry.StandardServiceRegistry;import org.hibernate.boot.registry.StandardServiceRegistryBuilder;import org.junit.After;import org.junit.Before;import org.junit.Test;public class TestMain {    private SessionFactory sessionFactory = null;    private Session session = null;    private Transaction transaction = null;    @Before    public void init() {        StandardServiceRegistry standardRegistry = new StandardServiceRegistryBuilder().configure().build();        Metadata metadata = new MetadataSources(standardRegistry).getMetadataBuilder().applyImplicitNamingStrategy(ImplicitNamingStrategyComponentPathImpl.INSTANCE).build();        sessionFactory = metadata.getSessionFactoryBuilder().build();        session = sessionFactory.getCurrentSession();        transaction = session.beginTransaction();    }        @After    public void destory() {        transaction.commit();        session.close();        sessionFactory.close();    }}

运行空测试类,初始化sql:

技术分享
 1 Hibernate:  2      3     create table DEPARMENTS ( 4        DEPART_ID integer not null auto_increment, 5         DEPART_NAME varchar(255), 6         MANAGER_ID integer, 7         primary key (DEPART_ID) 8     ) engine=InnoDB 9 Hibernate: 10     11     create table MANAGERS (12        MANAGER_ID integer not null auto_increment,13         MANAGER_NAME varchar(255),14         primary key (MANAGER_ID)15     ) engine=InnoDB16 Hibernate: 17     18     alter table DEPARMENTS 19        drop index UK_j9bdvgylyeboig73ntlfcuyf620 Hibernate: 21     22     alter table DEPARMENTS 23        add constraint UK_j9bdvgylyeboig73ntlfcuyf6 unique (MANAGER_ID)24 Hibernate: 25     26     alter table DEPARMENTS 27        add constraint FKnlmf88ii3maigw7hgc182cqi4 28        foreign key (MANAGER_ID) 29        references MANAGERS (MANAGER_ID)
View Code
  • 测试:

1)测试insert:

 1     @Test 2     public void testInsert(){ 3         Deparment deparment=new Deparment(); 4         deparment.setDepartName("Depart1"); 5          6         Manager manager=new Manager(); 7         manager.setManagerName("manager1"); 8          9         deparment.setManager(manager);10         manager.setDeparment(deparment);11         12         session.save(manager);13         session.save(deparment);14     }15     

测试通过,测试打印sql

技术分享
 1 Hibernate:  2     insert  3     into 4         MANAGERS 5         (MANAGER_NAME)  6     values 7         (?) 8 Hibernate:  9     insert 10     into11         DEPARMENTS12         (DEPART_NAME, MANAGER_ID) 13     values14         (?, ?)
View Code

2)测试select

 1     @Test 2     public void testSelect() { 3         // 1.查询时,采用懒加载。 4         Deparment deparment = (Deparment) session.get(Deparment.class, 1); 5         System.out.println(deparment.getDepartName()); 6  7         // // 2.会出现懒加载异常问题 8         // session.close(); 9         // Manager manager = deparment.getManager();10         // System.out.println(manager.getClass());11         // System.out.println(manager.getManagerName());    12     }

3)测试Select Manager

 1     @Test 2     public void testSelectManager() { 3         // 1.查询时,没采用懒加载。 4         Manager manager = session.get(Manager.class, 1); 5         System.out.println(manager.getManagerName()); 6          7         // 2.不会出现懒加载异常问题 8         session.close(); 9         System.out.println(manager.getDeparment().getDepartName());10     }

4)测试修改

 1     @Test 2     public void testUpdate() { 3         // // 1) session关闭时,修改执行 4         // Manager manager = session.get(Manager.class, 1); 5         // manager.setManagerName("Mgr11111"); 6         // // session.save(manager); 7         // 8         // Deparment deparment = session.get(Deparment.class, 1); 9         // deparment.setDepartName("Depart111111");10         // // session.save(deparment);11 12         // // 2)通过manager 关联修改deparment13         // Manager manager = session.get(Manager.class, 1);14         // manager.setManagerName("Mgr222");15         // manager.getDeparment().setDepartName("DEPT22");16 17         // 3)通过department关联修改manager18         Deparment deparment = session.get(Deparment.class, 1);19         deparment.setDepartName("DPT333");20         deparment.getManager().setManagerName("Mgr333");21     }

5)测试删除

 1     @Test 2     public void testDelete() { 3         // 1)在department表中有记录与之关联时,删除失败 4         // Manager manager = session.get(Manager.class, 1); 5         // session.delete(manager); 6  7         // 2)删除成功,只删除了deparment表中的记录,manger表中的记录并没有删除,之后再删除manager就不会出现错误。 8         Deparment deparment = session.get(Deparment.class, 1); 9         session.delete(deparment);10     }

 

Hibernate(八):基于外键映射的1-1关联关系