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

  • 相关阅读:
    windows下面安装Python和pip教程
    Python已安装第三方库
    Python安装cx_Oracle第三方库(Mac osx Yosemite Intel i5环境)
    7.Python进阶_函数对象
    6.Python进阶_循环对象
    5.Python进阶_循环设计
    UltraEdit中粘贴问题
    UltraEdit的代码片的编码设置
    使用C#实现SSLSocket加密通讯 Https
    sql while 循环要加begin end
  • 原文地址:https://www.cnblogs.com/lt123/p/7225601.html
Copyright © 2020-2023  润新知