java hibernate 一对多和多对多映射关系总结

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=?

原文地址:https://www.cnblogs.com/lt123/p/7225601.html