7 映射-- 多对一(员工对部门)

多对一的例子 , 多个员工 对 一个部门 (Hibernate3.2)

package dao.po;
/**
* @author zl 员工类
*/
public class Employee
{
private intid;// 员工的ID 
private Stringname;// 员工的名称
private Departmentdepart; //员工所在部门, 是多对一关系
}

package dao.po;
/**

 * 部门类
 * 
 * @author zl
 * 
 */
public class Department
{
	private int		id;	//部门的ID 
	private String	name;	//部门的名称
}

映射文件 :

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping 
	package="dao.po">
	<class name="Employee">	
		<id name="id">
			<generator class="native"/>
		</id>
		<property name="name" not-null="true" length="255" column="`name`"/>
		<!-- 这里做多对一映射    -->
		<!-- name="depart"是Employee类的属性名 -->
		<!-- column="depart_id" 是表中字段名 -->
		<!-- 注意:下面没有非空 约束 , 很多情况,外键是有非空约束的, 一会后面说-->
		<!--column="depart_id" 中的depart_id是Employee对象的depart属性映射为Employee表中的depart_id字段-->
		<many-to-one name="depart" column="depart_id" ></many-to-one>
	</class>
</hibernate-mapping>

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC 
	"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
	"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping 
	package="dao.po">
	<class name="Department">	
		<id name="id">
			<generator class="native"/>
		</id>		
		<property name="name" not-null="true" length="255" column="`name`"/>

</class>
</hibernate-mapping>

hibernate.cfg.xml 文件实在没什么好说的,就不显示了, 想看的下载附件.

我们来保存员工 和 部门:

package dao;
import org.hibernate.Session;
import org.hibernate.Transaction;
import dao.po.Department;
import dao.po.Employee;


/**
 * 多对一的例子 , 多个员工 对 一个部门
 * 
 */

public class Many2One

{
	/**
	 * @param args
	 */
	public static void main(final String[] args)
	{
	add(); //添加两个员工, 一个部门
	}
	/**
	 * 添加两个员工, 一个部门
	 */
	public static void add()
	{
		final Department depart = new Department(); //部门
		depart.setName("技术部");
		final Employee em1 = new Employee(); //员工 一
		em1.setName("赵磊");
		em1.setDepart(depart);

		final Employee em2 = new Employee(); //员工 二
		em2.setName("陈加俊");
	em2.setDepart(depart);
		Session session = null;
		try
		{
			session = HibernateUtil.getSeesion();
			final Transaction tx = session.beginTransaction();
			session.save(depart); //先插入部门
		session.save(em1); //后插入员工, 因为员工的外键是 部门
			session.save(em2);
			tx.commit();
		}
		finally
		{
			if (session != null)
			{
				session.close();

			}
		}
	}
}

注意:保存的顺序:

第一种:

session.save(depart); //先插入部门
session.save(em1); //后插入员工, 因为员工的外键是 部门
session.save(em2);

输出的SQL:

Hibernate: insert into Department (`name`) values (?)
Hibernate: insert into Employee (`name`, depart_id) values (?, ?)
Hibernate: insert into Employee (`name`, depart_id) values (?, ?)

第二种:

session.save(em1); //先插入员工
session.save(em2);
session.save(depart); //后插入部门

输出的SQL:

Hibernate: insert into Employee (`name`, depart_id) values (?, ?)
Hibernate: insert into Employee (`name`, depart_id) values (?, ?)
Hibernate: insert into Department (`name`) values (?)
Hibernate: update Employee set `name`=?, depart_id=? where id=?
Hibernate: update Employee set `name`=?, depart_id=? where id=?

这里多了两句 update,要 注意.

如果Employee.hbm.xml 中外键有非空约束 ,如下:保存时只能用"第一种 "顺序. 用了第二种,先插入员工,但depart_id字段为空,会异常,不能插入.

<many-to-one name="depart" column="depart_id" not-null="true"></many-to-one>

我们来查询一个员工, 注意"部门":

/**
	 * 测试查询
	 * 
	 * @param args
	 */
	public static void main(final String[] args)
	{
		//add(); //添加两个员工, 一个部门
		final Employee em = query(7);
		//员工的部门 , 执行Hibernate.initialize()后, 在session关闭前就取得了部门.
		//若没有执行Hibernate.initialize(), 下面会抛异常.
		System.out.println(em.getDepart().getName());
}

	/**
	 * 查询一个员工出来
           */
	public static Employee query(final int id)
	{
		Session session = null;
		try
		{
			session = HibernateUtil.getSeesion();
			final Transaction tx = session.beginTransaction();
			final Employee em = (Employee) session.get(Employee.class, id); //按ID查
			//因为 员工的 "部门" 属性会懒加载,
			//在session关闭后,调用em.getDepart()无法取到部门信息
			//所以这里用 Hibernate.initialize(em.getDepart()) 提前加载一下.
			//是em.getDepart() 而不是em.
			Hibernate.initialize(em.getDepart());
			tx.commit();
		return em;
		}
	finally
		{	if (session != null)
			{
			session.close();
			}
	}

}

输出的SQL是:

Hibernate: select employee0_.id as id1_0_, employee0_.`name` as name2_1_0_, employee0_.depart_id as depart3_1_0_ from Employee employee0_ where employee0_.id=?

Hibernate: select department0_.id as id0_0_, department0_.`name` as name2_0_0_ from Department department0_ where department0_.id=?

做了两次查询, 没有使用 join on , 想使用join on 还要配置. 默认不用.

关于懒加载, 会在以后的文章中专门讲, 这里先不讲, 只是用了用 Hibernate.initialize(em.getDepart()) 提前加载

你可能感兴趣的:(多对一)