hibernate07--关联映射
单向的一对多关联
创建对应的实体类以及映射文件

package cn.bdqn.bean;
/**
*
* @author 小豆腐
*街道对应的实体类
*
*单向的多对一关联
*/
public class Street { private Integer id;
private String name;
//多个街道 属于 一个区县
private District district; //对应的区县 public District getDistrict() {
return district;
}
public void setDistrict(District district) {
this.district = district;
}
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 Street(Integer id, String name) {
super();
this.id = id;
this.name = name;
}
public Street() {
super();
}
@Override
public String toString() {
return "Street [id=" + id + ", name=" + name + "]";
} }


<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="cn.bdqn.bean">
<class name="Street">
<id name="id">
<generator class="assigned"/><!-- 手动给主键赋值 -->
</id>
<property name="name"/>
<!-- 配置多对一关联
name:对应的是 本类中 关联关系的属性名
column:对应数据库中 两个表的 外键!
class:关联的实体类-->
<many-to-one name="district" column="districtId" class="District"/>
</class>
</hibernate-mapping>


package cn.bdqn.bean;
/**
* @author 小豆腐
*
*区县的实体类
*/
public class District { private Integer id;
private String 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 District(Integer id, String name) {
super();
this.id = id;
this.name = name;
}
public District() {
super();
}
@Override
public String toString() {
return "Street [id=" + id + ", name=" + name + "]";
} }


<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="cn.bdqn.bean">
<class name="District">
<id name="id">
<generator class="assigned"/><!-- 手动给主键赋值 -->
</id>
<property name="name"/>
</class>
</hibernate-mapping>

需要在hibernate.cfg.xml文件中 配置映射文件
测试类

Session session=null;
Transaction transaction=null; //获取session 开启事务
@Before
public void before(){
session=HibernateSessionUtil.getCurrentSession();
transaction= session.beginTransaction();
} /**
* 测试单向的多对一的关联
*
* 创建对应的区县 新增几个区县 以备后续使用
*/
@Test
public void testAdd(){
District district=new District(3, "区县3");
session.save(district); //保存
transaction.commit(); //提交事务
} //新增 街道的同时 给街道对应的区县赋值
@Test
public void test01(){
//创建一个街道
Street street=new Street();
street.setId(1);
street.setName("街道1");
//给对应的区县赋值
District district= (District) session.load(District.class, 1);
street.setDistrict(district);
session.save(street); //保存
transaction.commit(); //提交事务 只会产生一条sql insert
} //修改 街道对应的区县
@Test
public void test02(){
//从数据库中获取一个街道
Street street=(Street) session.load(Street.class, 1); // 对应的区县是1
District district=(District) session.load(District.class, 2); // 区县是2
//修改
street.setDistrict(district); // 不需要 update 因为两个对象都是持久化对象
//提交事务
transaction.commit();
} //删除 街道对应的区县
@Test
public void test03(){
//从数据库中获取一个街道
Street street=(Street) session.load(Street.class, 1); // 对应的区县是2
//修改
street.setDistrict(null);
//提交事务
transaction.commit();
}

双向的一对多关联就是在单向多对一的基础上增加一个单向的一对多!
修改District代码 一对多关联

package cn.bdqn.bean; import java.util.ArrayList;
import java.util.List; /**
* @author 小豆腐
*
*区县的实体类
* 一对多的关联关系
*/
public class District { private Integer id;
private String name;
// 一个区县 有 多个街道
private List<Street> streets=new ArrayList<>(); public List<Street> getStreets() {
return streets;
}
public void setStreets(List<Street> streets) {
this.streets = streets;
}
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 District(Integer id, String name) {
super();
this.id = id;
this.name = name;
}
public District() {
super();
}
@Override
public String toString() {
//如果写成streets 会出现 堆栈溢出的异常!
return "District [id=" + id + ", name=" + name + ", streets=" + streets.size()
+ "]";
} }

修改District.hbm.xml文件代码

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="cn.bdqn.bean">
<class name="District">
<id name="id">
<generator class="assigned"/><!-- 手动给主键赋值 -->
</id>
<property name="name"/>
<!-- 设置一对多
name:本类中的关联属性名 集合的名称
column: 就是数据库表中的外键
order-by="id desc" 按照 街道的id 进行 降序排列
inverse:是由谁来维护表与表之间的关系! 默认是false!(维护) true(不维护)
-->
<bag name="streets" cascade="all" inverse="true">
<key column="districtId"/>
<one-to-many class="Street"/>
</bag>
</class>
</hibernate-mapping>

在测试类中增加代码

/**
* 创建几个街道 测试 双向的一对多关联
*/
@Test
public void test04(){
Street street=new Street();
street.setId(4);
street.setName("街道4");
//给对应的区县赋值
District district= (District) session.load(District.class, 1);
street.setDistrict(district);
session.save(street); //保存
//提交事务
transaction.commit();
} //根据区县 获取所管辖的街道
@Test
public void test05(){
District district=(District) session.load(District.class, 1);
List<Street> streets = district.getStreets();
for (Street street : streets) {
System.out.println(street);
}
}
/**
* 根据区县 获取所管辖的街道 根据街道的编号 降序排列
* 01.只需要在 bag节点中 增加 order-by属性 = id desc
*/
@Test
public void test06(){
District district=(District) session.load(District.class, 1);
List<Street> streets = district.getStreets();
for (Street street : streets) {
System.out.println(street);
}
}
/**
* 02.使用hql语句
*/
@Test
public void test07(){
String hql="from Street s where districtId=:id order by s.id desc";
//创建query对象
Query query = session.createQuery(hql);
//给参数赋值
query.setParameter("id", 1); //区县编号是1
//遍历结果集
List<Street> list = query.list();
for (Street street : list) {
System.out.println(street);
}
} /**
* cascade属性:定义的是关系两端 对象到对象的级联关系!
* 必须是 双向的一对多关联!
*
* 常用的属性值:
* 01.none:默认值!当session操作当前对象的时候,忽略关联的属性!
* 02.save-update:当session调用save,saveorUpdate以及update()的时候!
* 会级联的保存和修改当前对象以及对象关联的属性!
* 001.去区县的xml文件中 的 bag节点 增加 cascade属性!
* 002.直接运行以下代码
* 03.delete: 当session调用 delete()的时候,会级联删除所关联的对象 !
* 04.all: 包括了save-update和delete!
*
* 添加区县的同时 添加街道
*/
@Test
public void test08(){
//创建区县
District district=new District(4, "区县4");
//创建街道
Street street1=new Street(5, "街道5");
Street street2=new Street(6, "街道6");
Street street3=new Street(7, "街道7");
//给区县的街道赋值
district.getStreets().add(street1);
district.getStreets().add(street2);
district.getStreets().add(street3);
//保存区县
session.save(district); //发现 保存了 区县 但是 没有保存对应的街道!
transaction.commit();
/**
* 程序执行之后的结果:
* Hibernate: insert into District (name, id) values (?, ?)
Hibernate: update Street set districtId=? where id=?
Hibernate: update Street set districtId=? where id=?
Hibernate: update Street set districtId=? where id=?
*/ /**
* 在xml文件中设置了 cascade="save-update" 之后的结果
*
* 问题:虽然级联保存成功了!
* 但是有多余update语句!
* 为什么会出现多余的? 两个对象都在维护彼此之间的关系!
*
* Hibernate: select street_.id, street_.name as name1_, street_.districtId as districtId1_ from Street street_ where street_.id=?
Hibernate: select street_.id, street_.name as name1_, street_.districtId as districtId1_ from Street street_ where street_.id=?
Hibernate: select street_.id, street_.name as name1_, street_.districtId as districtId1_ from Street street_ where street_.id=?
Hibernate: insert into District (name, id) values (?, ?)
Hibernate: insert into Street (name, districtId, id) values (?, ?, ?)
Hibernate: insert into Street (name, districtId, id) values (?, ?, ?)
Hibernate: insert into Street (name, districtId, id) values (?, ?, ?)
Hibernate: update Street set districtId=? where id=?
Hibernate: update Street set districtId=? where id=?
Hibernate: update Street set districtId=? where id=?
*/
} /**
* cascade="delete" xml中的配置
* 删除 区县 的同时 删除 街道!
*/
@Test
public void test09(){
District district= (District) session.load(District.class, 1);
//获取三个街道
Street street1= (Street) session.load(Street.class, 2);
Street street2= (Street) session.load(Street.class, 3);
Street street3= (Street) session.load(Street.class, 4);
session.delete(district);
transaction.commit();
/**
* Hibernate: update Street set districtId=null where districtId=?
Hibernate: delete from Street where id=?
Hibernate: delete from Street where id=?
Hibernate: delete from Street where id=?
Hibernate: delete from District where id=?
*/
} /**
* 针对于 多余的sql语句 解决办法!
*
* 只需要一方来维护表之间的关系!
* inverse属性:
* 01.默认是false(由我维护!)
* 02.inverse=true:这一方不维护关系!(不与数据库交互)
*
*
* 不能都维护,也不能都 不维护! 这个时候关键是谁来维护这个关系?
* 双向的一对多!
* hibernate:规定多的一端来维护关系,那么必须在一的一方设置 inverse=true:
*/
@Test
public void test10(){
//创建区县
District district=new District(4, "区县4");
//创建街道
Street street1=new Street(5, "街道5");
Street street2=new Street(6, "街道6");
Street street3=new Street(7, "街道7");
//给区县的街道赋值
district.getStreets().add(street1);
district.getStreets().add(street2);
district.getStreets().add(street3);
//保存区县
session.save(district); //发现 保存了 区县 但是 没有保存对应的街道!
transaction.commit();
/**
*
* 发现 没有了 update语句!
* Hibernate: select street_.id, street_.name as name1_, street_.districtId as districtId1_ from Street street_ where street_.id=?
Hibernate: select street_.id, street_.name as name1_, street_.districtId as districtId1_ from Street street_ where street_.id=?
Hibernate: select street_.id, street_.name as name1_, street_.districtId as districtId1_ from Street street_ where street_.id=?
Hibernate: insert into District (name, id) values (?, ?)
Hibernate: insert into Street (name, districtId, id) values (?, ?, ?)
Hibernate: insert into Street (name, districtId, id) values (?, ?, ?)
Hibernate: insert into Street (name, districtId, id) values (?, ?, ?)
*/
}
hibernate07--关联映射的更多相关文章
- Hibernatel框架关联映射
Hibernatel框架关联映射 Hibernate程序执行流程: 1.集合映射 需求:网络购物时,用户购买商品,填写地址 每个用户会有不确定的地址数目,或者只有一个或者有很多.这个时候不能把每条地址 ...
- hibernate多对多关联映射
关联是类(类的实例)之间的关系,表示有意义和值得关注的连接. 本系列将介绍Hibernate中主要的几种关联映射 Hibernate一对一主键单向关联Hibernate一对一主键双向关联Hiberna ...
- Hibernate一对多单向(双向)关联映射
(1).编写配置文件 Hibernate通过读写默认的XML配置文件hibernate.cfg.xml加载数据库配置信息.代码如下: <hibernate-configuration> & ...
- Java三大框架之——Hibernate关联映射与级联操作
什么是Hibernate中的关联映射? 简单来说Hibernate是ORM映射的持久层框架,全称是(Object Relational Mapping),即对象关系映射. 它将数据库中的表映射成对应的 ...
- Hibernate关联映射 映射文件的配置
一:多对一单向关联 首先我们必须创建两个实体类 例如:Dept类 public class Dept { private Integer deptNo; private String dName; p ...
- Hibernate组件和关联映射
一.基本定义 组件:建立一个类,为了方便代码复用和建立模型,但类在数据库中并没有对应的表,此类可以作为一个组件插入到其他类中(有数据表的类) 组件和关联映射的关系是组件是没有对应的类;组件是值类型的, ...
- 【Hibernate框架】关联映射(多对多关联映射)
按着我们的总结行进计划,接下来,就是有关于多对多映射的总结了. 我们来举个例子啊,很长时间以来,房价暴涨不落,但是还有很多人拥有很多套房产,假如说,一个富豪拥有九套房产,家里人么准去住哪一套,我们就以 ...
- 【Hibernate框架】关联映射(一对多,多对一)
根据我们的总结计划,上篇文章我们总结了有关于一对一映射相关知识,接下来,我们进行下一个阶段,一对多.多对一映射相关知识. 场景设定: 国家规定,一个人只能在一个公司上班,一个公司可以拥有很多员工.我们 ...
- 【Hibernate框架】关联映射(一对一关联映射)
一.整理思路: 之前,小编总结过Mybatis的关联映射,接下来,再来总结一下hibernate的相关的关联映射,直接上图: 这张图,就是小编整理总结整个Hibernate的关联映射的一个大致思路. ...
- Hibernate注解----关联映射注解以及课程总结详解----图片版本
上一篇,记录了Hibernate注解----类级别注解以及属性注解详解 ,我们这一节主要讲解的是Hibernate注解----关联映射注解以及课程总结详解. 本节的主要内容: 第3章 关联映射注解 3 ...
随机推荐
- 本机ip、127.0.0.1和0.0.0.0区别及内环流量
本机ip.127.0.0.1和0.0.0.0区别及内环流量 所谓内环流量 简单的说是指 计算机内部,程序间通讯产生的流量,或者叫 本地流量,对应的是来自网络的流量. 比如,你安装了卡巴斯基,avast ...
- .Net转Java.03.受查异常和非受查异常
转到Java以后发现一个很妖的事情,为啥有些方法后边有个 throws XXXXException 比如下面的代码 @Override public <T> ResponseEntity& ...
- Python学习笔记:Flask-Migrate基于model做upgrade的基本原理
1)flask-migrate的官网:https://flask-migrate.readthedocs.io/en/latest/ 2)获取帮助,在pycharm的控制台中输入 flask d ...
- 【原】Linux环境下Shell调用MySQL并实现定时任务
对于一些周期性事务,我们可以在Linux下,使用shell脚本调用mysql数据库存储过程,并设置定时任务. 本来是要mysql数据库中创建事件任务来,定时执行存储过程,做数据传输的...使用cron ...
- golang 使用pprof和go-torch做性能分析
软件开发过程中,项目上线并不是终点.上线后,还要对程序的取样分析运行情况,并重构现有的功能,让程序执行更高效更稳写. golang的工具包内自带pprof功能,使找出程序中占内存和CPU较多的部分功能 ...
- .NET 同步与异步 之 线程安全的集合 (十一)
本随笔续接:.NET 同步与异步 之 警惕闭包(十) 无论之前说的锁.原子操作 还是 警惕闭包,都是为安全保驾护航,本篇随笔继续安全方面的主题:线程安全的集合. 先看一下命名空间:System.Col ...
- SQL DDL 数据定义语句
前言 DDL(Data Definition Language)语句:数据定义语句,这些语句定义了不同的数据段.数据库.表.列.索引等数据库对象.常用的语句关键字主要包括 create.drop.al ...
- Effective Java 第三版——76. 争取保持失败原子性
Tips 书中的源代码地址:https://github.com/jbloch/effective-java-3e-source-code 注意,书中的有些代码里方法是基于Java 9 API中的,所 ...
- 17.翻译系列:将Fluent API的配置迁移到单独的类中【EF 6 Code-First系列】
原文链接:https://www.entityframeworktutorial.net/code-first/move-configurations-to-seperate-class-in-cod ...
- 使用 fail2ban 防御 SSH 服务器的暴力破解攻击
对于SSH服务的常见的攻击就是暴力破解攻击——远程攻击者通过不同的密码来无限次地进行登录尝试.当然SSH可以设置使用非密码验证验证方式来对抗这种攻击,例如公钥验证或者双重验证.将不同的验证方法的优劣处 ...