一个公司有很多员工,而一个员工只属于一个公司,这就是一个典型的一对多问题。那么hibernate是如何处理上述的关系哪。
Company的属性 company_id , company_level, company_position,company_name
employee的属性 employee_id,employee_name,employee_sex
两个表时通过公司的id进行关联到一起的 但是在实体类中暂时写上面的属性
Company.java 实体类要写映射的关系 set和相应的get方法
package com.sofency.entity;
import java.util.HashSet;
import java.util.Set;
public class Company {
private Integer company_id ;
private Integer company_level;
private String company_position;
private String company_name;
private Set<Employee> setEmployee = new HashSet<Employee>();//
public Set<Employee> getSetEmployee() {
return setEmployee;
}
public void setSetEmployee(Set<Employee> setEmployee) {
this.setEmployee = setEmployee;
}
public Company() {
super();
}
public Company(Integer company_id, Integer company_level, String company_position, String company_name) {
super();
this.company_id = company_id;
this.company_level = company_level;
this.company_position = company_position;
this.company_name = company_name;
}
public Integer getCompany_id() {
return company_id;
}
public void setCompany_id(Integer company_id) {
this.company_id = company_id;
}
public Integer getCompany_level() {
return company_level;
}
public void setCompany_level(Integer company_level) {
this.company_level = company_level;
}
public String getCompany_position() {
return company_position;
}
public void setCompany_position(String company_position) {
this.company_position = company_position;
}
public String getCompany_name() {
return company_name;
}
public void setCompany_name(String company_name) {
this.company_name = company_name;
}
@Override
public String toString() {
return "Company [company_id=" + company_id + ", company_level=" + company_level + ", company_position="
+ company_position + ", company_name=" + company_name + "]";
}
}
Employee.java 将一的实体类写到到多的实体类中
package com.sofency.entity;
public class Employee {
private Integer employee_id;
private String employee_name;
private String employee_sex;
private Employee employee = new Employee();/
public Employee getEmployee() {
return employee;
}
public void setEmployee(Employee employee) {
this.employee = employee;
}
public Employee() {
super();
}
public Employee(Integer employee_id, String employee_name, String employee_sex) {
super();
this.employee_id = employee_id;
this.employee_name = employee_name;
this.employee_sex = employee_sex;
}
public Integer getEmployee_id() {
return employee_id;
}
public void setEmployee_id(Integer employee_id) {
this.employee_id = employee_id;
}
public String getEmployee_name() {
return employee_name;
}
public void setEmployee_name(String employee_name) {
this.employee_name = employee_name;
}
public String getEmployee_sex() {
return employee_sex;
}
public void setEmployee_sex(String employee_sex) {
this.employee_sex = employee_sex;
}
@Override
public String toString() {
return "Employee [employee_id=" + employee_id + ", employee_name=" + employee_name + ", employee_sex="
+ employee_sex + "]";
}
}
Company.hbm.xml的配置
<?xml version="1.0" encoding="UTF-8"?>
<!-- 引入约束 dtd约束 -->
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.sofency.entity.Company" table="Company">
<id name="company_id" column="company_id"><!---引号里面不要有空格 不然会出错-->
<generator class="native"></generator>
</id>
<property name="company_level" column="company_level"></property>
<property name="company_position" column="company_position"></property>
<property name="company_name" column="company_name"></property>
<!-- 在客户映射文件中 表示所有人
使用set标签表示所有人
set标签里面的name属性
属性值写在实体类中表示联系人集合的名字
-->
<set name="setEmployee" cascade="save-update" inverse="true" fetch="select" lazy="true" batch-size=10>
<!-- lazy表示延迟加载
值 false 不延迟加载
true 延迟加载(默认值)
extra 极其延迟 要什么查什么
批量抓取 batch-size=10 越大 处理的数据越多
-->
<!-- inverse true表示放弃更新外键 false 表示不放弃修改-->
<!-- 一对多建表 有外键 hibernate机制 双向维护外键 在一和多那一方都配置外键 column 属性值 外键名称 -->
<key column="company_id"></key><!--cloumn 主键-->
<one-to-many class="com.sofency.entity.Employee"></one-to-many><!--对应多的实体类-->
</set>
</class>
</hibernate-mapping>
Employee.hbm.xml的配置
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.sofency.entity.Employee" table="Employee">
<id name="employee_id" column="employee_id">
<generator class="native"></generator>
</id>
<property name="employee_name" column="employee_name"></property>
<property name="employee_sex" column="employee_sex"></property>
<many-to-one name="Company" class="com.sofency.entity.Company" column="company_id"></many-to-one>
<!--对应1的实体类 cloumn 对应的是Company的主键 Employee的外键-->
</class>
</hibernate-mapping>
hibernate.cfg.xml的配置中需要将上述的两个配置文件引入就可以其它的和之前的没有什么区别
测试hibernateOneToMany.java
级联添加
public void testAdd(){
Configuration cfg = new Configuration();
cfg.configure();
SessionFactory sessionFactory = cfg.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Company company = new Company();
company.setCompany_level(1);
company.setCompany_position("杭州");
company.setCompany_name("阿里巴巴");
Employee employee1 = new Employee();
employee1.setEmployee_name("sofency");
employee1.setEmployee_sex("male");
Employee employee2 = new Employee();
employee2.setEmployee_name("ahoj");
employee2.setEmployee_sex("male");
company.getSetEmployee().add(employee1);
employee1.setCompany(company);
company.getSetEmployee().add(employee2);
employee2.setCompany(company);
session.save(company);
session.save(employee1);
session.save(employee2);//双向维护表
transaction.commit();
session.close();
sessionFactory.close();
}
我们可能会遇到这样的情况,sofenccy从阿里巴巴离职的情况,那么我们如何操作hibernate哪。
单元测试代码
@Test
public void testDelete1() {
Session session = hibernateUtils.openSession();
Transaction transaction = session.beginTransaction();
Company company = session.get(Company.class, 2);
session.delete(company);
transaction.commit();
session.close();
hibernateUtils.closeSessionFactory();
}
我们需要再set部分设置cascade属性值为save-update
不写该属性的话
会导致下面的情况
加上之后就可以级联删除了。清空了该员工的公司id
如果要级联删除的话需要再cascade里面写上delete效果如下把公司相应的员工也删除了。
更新操作 适用场景 当百度的公司级别提高了一个等级,需要修改
测试代码
public void testUpdate1() {
Session session = hibernateUtils.openSession();
Transaction transaction = session.beginTransaction();
Company company = session.get(Company.class, 2);
company.setCompany_level(4);//公司的级别提高了
//不用执行update操作 session.update(company);提交时快照取会和缓存进行比较如果不一样则更新到数据库
transaction.commit();
session.close();
hibernateUtils.closeSessionFactory();
}
原先的公司级别是5 修改为4的结果。