Hibernate关联映射之_多对一
多对一 Employee-Department
对于 员工 和 部门 两个对象,从员工的角度来看,就是多对一的一个关系--->多个员工对应一个部门
表设计:
部门表:department,id主键
员工表:employee,id主键,depart_id作为外键,与部门表的主键对应
对象模型设计:
部门:
package org.zln.hibernate.domain; /**
* 部门Domain对象
* Created by sherry on 000018/6/18 21:38.
*/
public class Department {
private int id;
private String name; @Override
public String toString() {
return "Department{" +
"id=" + id +
", name='" + name + '\'' +
'}';
} 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;
} }
员工:
package org.zln.hibernate.domain; /**
* 员工Domain对象
* Created by sherry on 000018/6/18 21:39.
*/
public class Employee {
private int id;
private String name;
/*employee隶属于一个department*/
private Department department; @Override
public String toString() {
return "Employee{" +
"id=" + id +
", name='" + name + '\'' +
", 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;
}
}
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">
<hibernate-mapping package="org.zln.hibernate.domain"> <class name="Employee" table="employee">
<!--单字段主键-->
<id name="id" column="id">
<generator class="native"/>
</id>
<!--普通字段-->
<property name="name" column="name"/>
<!--多对一字段--><!--默认查找员工表中的department_id==部门表中的主键id的部门信息,也可以手动指定 property-ref-->
<many-to-one name="department" column="department_id"/>
</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="org.zln.hibernate.domain"> <class name="Department" table="department">
<id name="id" column="id">
<generator class="native"/>
</id>
<property name="name" column="name"/> </class> </hibernate-mapping>
说明:部门的映射文件没有什么不同,但是在员工的映射文件中,映射domain对象中的department对象的,是department_id字段,Hibernate会查询employee表中的department_id,以此为条件,
再去查询department表中的记录,department_id对应department表中的id(默认情况外键对应主键嘛)。然后将从department表中的记录填充到employee对象中的department成员变量。
Dao:
/**
* 添加员工及其部门
* @param department
* @param employee
*/
public void addEmployee(Department department,Employee employee){
Session session = null;
Transaction transaction = null;
try {
session = HibernateUtils.getSession();
transaction = session.beginTransaction(); employee.setDepartment(department);
session.save(department);
session.save(employee); transaction.commit(); }finally {
if (session != null){
session.close();
}
}
}
上段代码,往数据库的员工表与部门表同时插入了一条记录,通过 employee.setDepartment(department); 将部门记录管理到了员工记录中
先插部门,会生成一个id作为员工表的外键,在插员工,此时员工信息+外键,都会插入到员工表中。如果先插入员工,那么此时员工表的外键是空的,当插入部门后,部门主键生成,员工的外键才有值,此时Hibernate在提交前还会执行一条update语句。从结果上看是一样的,但是多执行了一条。所以最好还是先执行部门的插入操作。
public void addEmployee(Employee employee){
Session session = null;
Transaction transaction = null;
try {
session = HibernateUtils.getSession();
transaction = session.beginTransaction(); /*通过department_id查询department,将部门与员工关联起来*/
employee.setDepartment(departmentDao.getDepartment(employee.getDepartment()));
session.save(employee); transaction.commit();
}finally {
if (session != null){
session.close();
}
}
}
上段代码,员工想要关联的部门信息已经在数据库中了,不需要重新插入,那么怎么关联呢?答案就是在插入员工信息前,先通过部门的查询条件从数据库中查询到部门信息,将部门信息设置给员工,然后再保存员工。此时数据库中的员工记录也和部门信息有了关联。
public Employee getEmployee(Employee employee){
Session session = null;
Employee employee1 = null;
try {
session = HibernateUtils.getSession();
employee1 = (Employee) session.get(Employee.class,employee.getId());
System.out.println(employee1);//不知道为什么,不先使用对象的话,session关闭后在方法体外就无法使用了。这里的懒加载干嘛了?
}finally {
if (session != null){
session.close();
}
}
return employee1; }
上段代码,查询条件就只有员工的id,但是通过映射文件,其对应的部门信息也会被填充到员工信息中
最新文章
- 特殊文件: /dev/null和/dev/tty
- Apache ab参数--压力测试
- Python闭包实现的计数器
- PHP实现下载功能之流程分析
- 启动报错:java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderListener
- 【设计模式 - 23】之模版方法模式(Template)
- git 免密码提交代码
- JavaWeb从0开始学(一)-----搭建第一个Web应用程序与JSP工作原理
- 什么是Web Worker?
- Android开发_TextView跑马灯
- python之@property
- Python通过分页对数据进行展示
- js----常用功能
- Cmake编译SDL2
- 【转】linux下解压.bz2压缩文件
- redis-trib.rb报错:/usr/lib/ruby/1.9.1/rubygems/custom_require.rb:36:in `require&#39;: cannot load such file -- redis (LoadError)
- 浅谈 PHP 中的多种加密技术及代码示例
- ChemOffice Professional 16.0新增了哪些功能
- 从svn检出项目的注意事项
- 【bzoj1086】[SCOI2005]王室联邦 树分块