one-to-many 一对多
package lt.demo6;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
public class Department {
private Integer id;
private String name;
private Set<Employee> employees=new HashSet<Employee>();
@Override
public String toString() {
return "Department [id=" + id + ", name=" + name + ", employees="
+ employees + "]";
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<Employee> getEmployees() {
return employees;
}
public void setEmployees(Set<Employee> employees) {
this.employees = employees;
}
}
package lt.demo6;
public class Employee {
private Integer id;
private String name;
private Department department;
@Override
public String toString() {
return "Employee [id=" + id + ", name=" + name + "]";
}
public Integer getId() {
return id;
}
public void setId(Integer 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;
}
}
javabean toString方法最好只包含基本类型,不包含引用数据类型
department 父表 映射 set集合映射
<?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="lt.demo6">
<class name="Department" table="t_department">
<id name="id">
<generator class="native" />
</id>
<property name="name" type="string" column="name" length="50" />
<!-- column不写默认为name属性 -->
<!-- key 对方表(子表)的外键列 -->
<!-- class 关联的实体类型 -->
<!-- inverse属性(相对于父表) -->
<!-- 默认false 表示维护关联关系 -->
<set name="employees" inverse="true">
<key column="departmentId"></key>
<one-to-many class="Employee"/>
<!-- class(实体类型)=====type(值类型) -->
</set>
</class>
</hibernate-mapping>
employee子表映射 包含外键 name 外键类型 class 外键列
<?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="lt.demo6">
<class name="Employee" table="t_employee">
<id name="id">
<generator class="native" />
</id>
<property name="name" type="string" column="name" length="50" />
<many-to-one name="department" class="Department" column="departmentId"></many-to-one>
</class>
</hibernate-mapping>
测试类
private static SessionFactory sessionFactory=new Configuration()// .configure()// .addClass(Employee.class)// .addClass(Department.class)// .buildSessionFactory();
public void testSave()
{
Session session=sessionFactory.openSession();
Transaction tx=session.beginTransaction();
//保存员工数据
Employee employee1=new Employee();
employee1.setName("张三");
Employee employee2=new Employee();
employee2.setName("lisi");
//保存部门信息
Department department=new Department();
department.setName("科研部门");
//设置联系 以至于两表之间可以互相获取对方
employee1.setDepartment(department);
employee2.setDepartment(department);
// 由于父表默认维护外键关系 所以设置关联只用设置子表的关联
// System.out.println(employee1.getDepartment()+"------");
// department.getEmployees().add(employee1);
// department.getEmployees().add(employee2);
//由上面生成 设置 子表关联后就不用设置父表关联了 两边都维护 面向对象愿意 数据库不愿意
//两全齐美解决办法 让没有外键那一方(主表) inverse=true
//子表中有外键 可以自动维护父表
// Hibernate: update t_employee set departmentId=? where id=?
// Hibernate: update t_employee set departmentId=? where id=?
// System.out.println(department.getEmployees().size()+"------size()");
//保存两表信息
session.save(department); //放在上面 两个update 知道了departmentId
// Hibernate: insert into t_department (name) values (?)
// Hibernate: insert into t_employee (name, departmentId) values (?, ?)
// Hibernate: insert into t_employee (name, departmentId) values (?, ?)
// Hibernate: update t_employee set departmentId=? where id=?
// Hibernate: update t_employee set departmentId=? where id=?
// 如果父表设置了维护
session.save(employee1);
session.save(employee2);
// session.save(department); 放在下面四个update 不知道departmentId 效果一样
// Hibernate: insert into t_employee (name, departmentId) values (?, ?)
// Hibernate: insert into t_employee (name, departmentId) values (?, ?)
// Hibernate: insert into t_department (name) values (?)
// Hibernate: update t_employee set name=?, departmentId=? where id=?
// Hibernate: update t_employee set name=?, departmentId=? where id=?
// Hibernate: update t_employee set departmentId=? where id=?
// Hibernate: update t_employee set departmentId=? where id=?
tx.commit();
session.close();
//注意one-to-many 维护的是外键表
//many-to-many 维护的是中间表
// many-to-many 设置一方inverse=true 就行
//
}
public void testDelete()
{
// 父表 inverse=true 不维护由于外键约束是删不了的
//父表inverse=false 维护关联 会将子表的外键设为null 在删掉外键
//目前知道的唯一作用
//删父表
Session session=sessionFactory.openSession();
Transaction tx=session.beginTransaction();
Department department=(Department) session.get(Department.class, 2);
session.delete(department);
tx.commit();
session.close();
}
many-to-many
<?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="lt.demo7">
<class name="Student" table="student">
<id name="id">
<generator class="native" />
</id>
<property name="name" type="string" column="name" length="50" />
<set name="teachers" table="teacher_student" >
<key column="studentId"></key>
<many-to-many class="Teacher" column="teacherId"></many-to-many>
<!-- 外键 -->
</set>
</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="lt.demo7">
<class name="Teacher" table="teacher">
<id name="id">
<generator class="native" />
</id>
<property name="name" type="string" column="name" length="50" />
<set name="students" table="teacher_student" >
<key column="teacherId"></key>
<many-to-many class="Student" column="studentId"></many-to-many>
<!-- 外键 -->
</set>
</class>
</hibernate-mapping>
Long->Integer long.intValue()
Integer->Long x.Longvalue();
Long x=5L;
一对多 从父表设置关联(自动维护)
@Test
public void testSave()
{
Session session=se
@Test
public void testSave()
{
Session session=sessionFactory.openSession();
Transaction tx=session.beginTransaction();
//保存员工数据
Employee employee1=new Employee();
employee1.setName("张三");
Employee employee2=new Employee();
employee2.setName("lisi");
//保存部门信息
Department department=new Department();
department.setName("科研部门");
//设置联系 以至于两表之间可以互相获取对方
employee1.setDepartment(department);
employee2.setDepartment(department);
// System.out.println(employee1.getDepartment()+"------");
// department.getEmployees().add(employee1);
// department.getEmployees().add(employee2);
//
//由上面生成 设置 子表关联后就不用设置父表关联了 两边都维护 面向对象愿意 数据库不愿意
//两全齐美解决办法 让没有外键那一方(主表) inverse=true
//子表中有外键 可以走哦那个维护父表
// System.out.println(department.getEmployees().size()+"------size()");
//保存两表信息
session.save(department); //放在上面 两个update 知道了departmentId
session.save(employee1);
session.save(employee2);
tx.commit();
session.close();
//注意one-to-many 维护的是外键表
//many-to-many 维护的
// many-to-many 设置一方inverse=true 就行
//
}
Hibernate: insert into t_department (name) values (?) Hibernate: insert into t_employee (name, departmentId) values (?, ?) Hibernate: insert into t_employee (name, departmentId) values (?, ?) Hibernate: update t_employee set departmentId=? where id=? Hibernate: update t_employee set departmentId=? where id=?
为什么还多了两条update语句了?
因为从父表设置与子表(有外键方)的联系时,只有先插入所有数据后,父表才能去设置联系,导致多了两条update语句(没有实体不能设置关联)
从子表设置关联(推荐(规范))
@Test
public void testSave()
{
Session session=sessionFactory.openSession();
Transaction tx=session.beginTransaction();
//保存员工数据
Employee employee1=new Employee();
employee1.setName("张三");
Employee employee2=new Employee();
employee2.setName("lisi");
//保存部门信息
Department department=new Department();
department.setName("科研部门");
//设置联系 以至于两表之间可以互相获取对方
employee1.setDepartment(department);
employee2.setDepartment(department);
//保存两表信息
session.save(department); //放在上面 两个update 知道了departmentId
session.save(employee1);
session.save(employee2);
session.close();
//注意one-to-many 维护的是外键表
//many-to-many 维护的
// many-to-many 设置一方inverse=true 就行
//
}
因为提前保存父表 ,从而子表知道了外键id,就不用更新,效率很高(1对1也是这样设置)
Hibernate: insert into t_department (name) values (?) Hibernate: insert into t_employee (name, departmentId) values (?, ?) Hibernate: insert into t_employee (name, departmentId) values (?, ?)
session.save(employee1);
session.save(employee2);
session.save(department);
Hibernate: insert into t_employee (name, departmentId) values (?, ?)
Hibernate: insert into t_employee (name, departmentId) values (?, ?)
Hibernate: insert into t_department (name) values (?)
Hibernate: update t_employee set name=?, departmentId=? where id=?
Hibernate: update t_employee set name=?, departmentId=? where id=?