02hibernate关联映射

02hibernate关联映射


前言

在关系型数据库中,多表之间存在着三种关联关系,分别为一对一、一对多和多对多。下面将会介绍到三者之间的关系和实践。


一、关联映射的内容和作用

对象间的关联关系的体现:一对一、一对多、多对一、多对多
ORM怎么描述对象之间的关系(重点)
作用:hibernate是一个完整的ORM框架,对象与对象之间是有关系,自动根据关联关系做相应的持久化操作,以面向对象的思想操作关系型数据库。

二、实践 - 一对多

数据库表的联系
在这里插入图片描述
对象的联系:

  • 一方:区域District
  • 多方:街道Street

1、反向工程

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
生成的类中,多方有一个Set集合
在这里插入图片描述
在生成的District.hbm.xml中删除inverse=“true”(后面讲解到)
在这里插入图片描述

在这里插入图片描述

2、 测试

新建测试类
在这里插入图片描述
1、查询指定区域下所有街道的信息

package com.gec.hiber.junit;

import static org.junit.Assert.*;

import java.util.Set;

import org.hibernate.Session;
import org.junit.Test;

import com.gec.hiber.entity.District;
import com.gec.hiber.entity.Street;
import com.gec.hiber.utils.HibernateSessionUtils;

public class TestDistrict {

	//查询指定区域下所有街道的信息
	@Test
	public void test() {
		Session session=HibernateSessionUtils.getSession();	//获取连接
		int id=104;	//要查询的区域id
		District district= (District)session.get(District.class, id);
		System.out.println(district.getName());
		Set<Street> set=district.getStreets();
		for (Street street : set) {
			System.out.println("\t"+street.getName());
		}
		session.close();
	}

}

在这里插入图片描述

2、查询指定街道的信息和街道所属的区域

//查询指定街道的信息和街道所属的区域
	@Test
	public void test2() {
		Session session=HibernateSessionUtils.getSession();	//获取连接
		int id=149;	//要查询的街道id
		Street street= (Street)session.get(Street.class, id);
		System.out.println(street.getName());
		District district=(street.getDistrict());
		System.out.println("\t"+district.getName());
		session.close();
	}

在这里插入图片描述
在这里插入图片描述
3、新增一个区域,同时街道也要分配

//新增一个区域,同时街道也要分配
	@Test
	public void testadd() {
		Session session=HibernateSessionUtils.getSession();	//获取连接
		Transaction tx=session.beginTransaction();	//开启事务
		
		//创建区域对象 临时状态
		District district=new District();
		district.setName("X区");
		
		//创建两条街道
		Street s1=new Street();
		s1.setName("X区-街道1");
		Street s2=new Street();
		s2.setName("X区-街道2");
		
		//设置对象向之间的关联关系
		district.getStreets().add(s1);
		district.getStreets().add(s2);
		s1.setDistrict(district);
		s2.setDistrict(district);
		
		//持久化操作,先加一方,再加多方
		session.save(district);
		session.save(s1);
		session.save(s2);
		
		tx.commit();
		session.close();
	}

在这里插入图片描述
运行结果:出现了多余的update语句,用于修正外键列,影响性能。
在这里插入图片描述
解决办法(优化):指定多方来维护外键列,但是默认是一方来维护的。
在District.hbm.xml中修改

<set name="streets" inverse="true" cascade="all">

inverse=false 默认设置,表示 关联维护方是当前方,就是一方来维护,会出现多余的update语句,用于修改多方表的外键列
inverse=true 反转的意思,由当前方的对方(多方)来维护外键列,减少update语句,改善性能。

级联操作:
在这里插入图片描述

三、实践 - 多对多

在这里插入图片描述

1、反向工程

在这里插入图片描述
在这里插入图片描述

  • employ和project添加对应的类名和自增长
  • r_emp_proj不需要添加
    在这里插入图片描述
    更新了两个实体文件和两个orm映射文件
    在这里插入图片描述
    Employ和Project都各自带有Set集合

2、测试

在这里插入图片描述
新增项目,分配现在的两名员工负责

package com.gec.hiber.junit;

import static org.junit.Assert.*;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import com.gec.hiber.entity.Employ;
import com.gec.hiber.entity.Project;
import com.gec.hiber.utils.HibernateSessionUtils;

public class TestProjectEmp {

	//新增项目,分配现在的两名员工负责
	@Test
	public void testManyToMany() {
		Session session = HibernateSessionUtils.getSession();
		Transaction tx = session.beginTransaction();
		
		Project project = new Project();
		project.setProjectname("学习管理系统");
		project.setProjectdesc("very good");
		
		//查找两名现有的员工
		Employ emp1 = (Employ) session.get(Employ.class, 7);
		Employ emp2 = (Employ) session.get(Employ.class, 9);
		
		//设置关联关系
		project.getEmploies().add(emp1);
		project.getEmploies().add(emp2);
		emp1.getProjects().add(project);
		emp2.getProjects().add(project);
		
		//持久化的操作
		session.save(project);
		
		tx.commit();
		
		HibernateSessionUtils.closeSession();
	}

}

测试成功
在这里插入图片描述
在这里插入图片描述

四、实践 - 一对一

car汽车表,carport车位表。其中car表的主键,同时又是carport表的外键列在这里插入图片描述

1、反向工程

修改为one-to-one
在这里插入图片描述
在这里插入图片描述
在生成的car.hbm.xml中添加上carport的外键
在这里插入图片描述

2、测试

package com.gec.hiber.junit;

import static org.junit.Assert.*;

import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

import com.gec.hiber.entity.Car;
import com.gec.hiber.entity.Carport;
import com.gec.hiber.utils.HibernateSessionUtils;

public class TestCar {

	//新增车位和汽车
	@Test
	public void testOneToOne() {
		Session session=HibernateSessionUtils.getSession();	//获取连接
		Transaction tx = session.beginTransaction();	//开启事务
			
		Carport carport = new Carport();
		carport.setLocation("X区101");
		carport.setCpsize("1000");
			
		Car car = new Car();
		car.setNum("粤AE88888");
		car.setBrand("五菱宏光");
			
		//设置关联关系
		carport.setCar(car);
		car.setCarport(carport);
			
		//先保存车位
		session.save(carport);
		session.save(car);
			
		tx.commit();
		session.close();
	}

}

运行结果
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值