关键代码:

1.有外键的一端,使用many-to-one元素进行映射,并且增加unique属性,保证外键的唯一性。

2.没有外键的一端,使用one-to-one元素映射,并且要指定property-ref属性。


场景:

定义两张表:1.Manager管理者表(主键)。2.Department 部门表(外键)。

设计思路:一个部门只有一个最高的管理者。


详细代码:

Manager.java:

package com.shuoeasy.test;

public class Manager {
	private int id;
	private String name;
	
	private Department department;

	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 Department getDepartment() {
		return department;
	}

	public void setDepartment(Department department) {
		this.department = department;
	}

	@Override
	public String toString() {
		return "Manager [id=" + id + ", name=" + name + "]";
	}

}

Department.java:

package com.shuoeasy.test;

public class Department {
	private int id;
	private String Name;
	private Manager manager;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return Name;
	}
	public void setName(String name) {
		Name = name;
	}
	public Manager getManager() {
		return manager;
	}
	public void setManager(Manager manager) {
		this.manager = manager;
	}
	@Override
	public String toString() {
		return "Department [id=" + id + ", Name=" + Name + "]";
	}
	
}

Manager.hbm.xml:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2016-6-25 14:50:51 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
	<class name="com.shuoeasy.test.Manager" table="MANAGER">
		<id name="id" type="int">
			<column name="ID" />
			<generator class="native" />
		</id>
		<property name="name" type="java.lang.String">
			<column name="NAME" />
		</property>
		
		<!-- 
		1.映射1-1的关联关系,在对应数据表中已经有外键了,当前持久化类使用ont-to-ont映射 .
			没有外键的一端使用ont-to-one元素,改元素使用property-ref属性
			指明使用被关联实体主键以外的字段作为关联
		2.
		-->
		<one-to-one name="department"
			class="com.shuoeasy.test.Department"
			property-ref="manager"
		>
		</one-to-one>
		
	</class>
</hibernate-mapping>

Department.hbm.xml:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2016-6-25 14:50:51 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
	<class name="com.shuoeasy.test.Department" table="DEPARTMENT">
		<id name="id" type="int">
			<column name="ID" />
			<generator class="native" />
		</id>
		<property name="name" type="java.lang.String">
			<column name="NAME" />
		</property>
		
		<!-- 使用many-to-one的方式映射1-1的关系 -->
		<many-to-one name="manager" 
			class="com.shuoeasy.test.Manager"
			column="MANAGER_ID" unique="true"
		></many-to-one>
	</class>
</hibernate-mapping>

测试代码 AppTest.java:

package com.shuoeasy.test;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;


/**
 * Unit test for simple App.
 */
public class AppTest {
	Session session;
	SessionFactory sf;

	@Before
	public void init() {

		Configuration conf = new Configuration().configure();

		ServiceRegistry sr = new StandardServiceRegistryBuilder().applySettings(conf.getProperties()).build();

		sf = conf.buildSessionFactory((org.hibernate.service.ServiceRegistry) sr);

		session = sf.openSession();

		session.beginTransaction();
		System.out.println("init");
	}

	@After
	public void destory() {
		session.getTransaction().commit();

		session.close();

		sf.close();
		System.out.println("dectory");
	}

	/**
	 * 插入数据
	 */
	@Test
	public void testInsert(){
		Manager manager = new Manager();
		manager.setName("部门经理1");
		session.save(manager);
		
		Department dept = new Department();
		dept.setName("部门1");
		dept.setManager(manager);
		session.save(dept);
	} 
	
	/**
	 * 读取数据Department
	 * 备注:这里其中生成了多个冗余select,暂时不知道怎么减少多余的查询
	 */
	@Test
	public void testGetDepartment(){
		Department dept = (Department) session.get(Department.class, 1);
		System.out.println(dept.getId());
		System.out.println(dept.getName());
		System.out.println(dept.toString());
		System.out.println(dept.getManager());
	}
	
	/**
	 * 读取数据Manager
	 * 会生成select ... left join ... 的sql
	 */
	@Test
	public void testGetManager(){
		Manager manager = (Manager) session.get(Manager.class, 1);
		System.out.println(manager);
		System.out.println(manager.getDepartment());
	}
	
}

生成的sql:

    select
        manager0_.ID as ID1_1_0_,
        manager0_.NAME as NAME2_1_0_,
        department1_.ID as ID1_0_1_,
        department1_.NAME as NAME2_0_1_,
        department1_.MANAGER_ID as MANAGER_3_0_1_ 
    from
        MANAGER manager0_ 
    left outer join
        DEPARTMENT department1_ 
            on manager0_.ID=department1_.MANAGER_ID 
    where
        manager0_.ID=?

数据库表数据

manager表:

blob.png

department表:

blob.png

你可能感兴趣的文章