Hibernate 一对一关联查询
版权声明:本文为博主原创文章,如需转载请标注转载地址。
博客地址:http://www.cnblogs.com/caoyc/p/5602418.html
一对一关联,可以分为两种。一种是基于外键的关联,另一种是基于主键的关联。如图
一、基于外键的方式
User.java
1 package com.proc.one2one; 2 3 public class User { 4 5 private Integer id; 6 private String name; 7 private IdCard card; 8 public User() { 9 } 10 public User(String name) { 11 this.name = name; 12 } 13 public Integer getId() { 14 return id; 15 } 16 public void setId(Integer id) { 17 this.id = id; 18 } 19 public String getName() { 20 return name; 21 } 22 public void setName(String name) { 23 this.name = name; 24 } 25 public IdCard getCard() { 26 return card; 27 } 28 public void setCard(IdCard card) { 29 this.card = card; 30 } 31 @Override 32 public String toString() { 33 return "User [id=" + id + ", name=" + name + "]"; 34 } 35 }
IdCard.java
1 package com.proc.one2one; 2 3 public class IdCard { 4 5 private Integer id; 6 private String cardNo; 7 private User user; 8 public IdCard(String cardNo) { 9 this.cardNo = cardNo; 10 } 11 public IdCard() { 12 } 13 public Integer getId() { 14 return id; 15 } 16 public void setId(Integer id) { 17 this.id = id; 18 } 19 public String getCardNo() { 20 return cardNo; 21 } 22 public void setCardNo(String cardNo) { 23 this.cardNo = cardNo; 24 } 25 public User getUser() { 26 return user; 27 } 28 public void setUser(User user) { 29 this.user = user; 30 } 31 @Override 32 public String toString() { 33 return "IdCard [id=" + id + ", cardNo=" + cardNo + "]"; 34 } 35 36 }
User.hbm.xml
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE hibernate-mapping PUBLIC 3 "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 4 "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> 5 <hibernate-mapping package="com.proc.one2one"> 6 <class name="User" table="t_user"> 7 <id name="id" type="int" column="id" > 8 <generator class="native"></generator> 9 </id> 10 <property name="name" length="20" not-null="true"></property> 11 <one-to-one name="card" class="IdCard"></one-to-one> 12 </class> 13 </hibernate-mapping>
IdCard.hbm.xml
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE hibernate-mapping PUBLIC 3 "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 4 "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> 5 <hibernate-mapping package="com.proc.one2one"> 6 <class name="IdCard" table="t_idcard"> 7 <id name="id" type="int" column="id" > 8 <generator class="native"></generator> 9 </id> 10 <property name="cardNo" type="string" column="cardNo" length="20" not-null="true"></property> 11 <many-to-one name="user" column="userid" class="User" unique="true"></many-to-one> 12 </class> 13 </hibernate-mapping>
我们可以看到一个是one-to-one一个是many-to-one的unique。
分清楚这两个很重要,many-to-one用在保存外键的表,也就是说t_idcard表,one-to-one用在没有保存外键的表,也就是user表.
测试代码:
1、添加关联关系
测试:1:
1 public class App { 2 3 private static SessionFactory factory=new Configuration() 4 .configure() 5 .addClass(User.class) 6 .addClass(IdCard.class) 7 .buildSessionFactory(); 8 9 @Test 10 public void test(){ 11 12 Session session=factory.openSession(); 13 Transaction tx=session.beginTransaction(); 14 15 User user=new User("caoyc"); 16 IdCard card=new IdCard("510123588413x"); 17 18 card.setUser(user); 19 session.save(user); 20 session.save(card); 21 tx.commit(); 22 session.close(); 23 24 } 25 }
上面我们通过IdCard来维护关联关系,结果正确
测试2:
下面我们来试一试通过User来维护关联关系,看结果会怎么样?
1 @Test 2 public void test(){ 3 4 Session session=factory.openSession(); 5 Transaction tx=session.beginTransaction(); 6 7 User user=new User("caoyc"); 8 IdCard card=new IdCard("510123588413x"); 9 10 user.setCard(card); 11 12 session.save(user); 13 session.save(card); 14 tx.commit(); 15 session.close(); 16 17 }
在数据库中我们可以看到,数据库中表的结构完全一致,而且在t_user中也插入了数据,在t_idcard表中也同样有数据,只不过,t_idcard表中的userid列为null,也就是说,通过user无法维护关联关系
【总结】:在有外键的一方,可以维护关联关系,而在没有外键的一方无法维护关联关系
测试3:
我们交换user对象和card对象的保存顺序
1 session.save(card); 2 session.save(user);
结果数据也能够正常插入到数据库中,结果和测试1相同。那么交换保存顺序是否有其他影响呢?答案是肯定的,虽然数据同样插入进去了,但是在具体插入过程却有不同。
在测试1中:我们先保存的user,通过insert into语句我们将数据正确插入,然后我们在保存card,而此时的user对象由于已经在数据库中存在,那么必然有主键ID存在,我们在插入到IdCard表中,数据全部完全插入。具体sql语句
1 Hibernate: insert into t_user (name) values (?) 2 Hibernate: insert into t_idcard (cardNo, userid) values (?, ?)
在测试3中:我们先将card的数据保存到idcard表中,而此时的user的id值为null,所有在插入到idcard中是,userid会是nul
l
然后在插入user到t_user表中,那么此时user的主键值已经生成。为了维护关联关系
系统会有执行一条语句
update t_idcard set cardNo=?, userid=? where id=?
所有在测试3中,我们会看到
1 Hibernate: insert into t_idcard (cardNo, userid) values (?, ?) 2 Hibernate: insert into t_user (name) values (?) 3 Hibernate: update t_idcard set cardNo=?, userid=? where id=?
【总结】:在保存数据时,我们先保存没有外键的一方,然后在保存有外键的一方,这样执行效率更高
2、解除关联关系
测试1:通过User来解除关联关系
1 @Test 2 public void test(){ 3 4 Session session=factory.openSession(); 5 Transaction tx=session.beginTransaction(); 6 7 User user=session.get(User.class, 1); 8 user.setCard(null); 9 10 tx.commit(); 11 session.close(); 12 13 }
执行的SQL语句
Hibernate: select user0_.id as id1_1_0_, user0_.name as name2_1_0_, idcard1_.id as id1_0_1_, idcard1_.cardNo as cardNo2_0_1_, idcard1_.userid as userid3_0_1_ from t_user user0_ left outer join t_idcard idcard1_ on user0_.id=idcard1_.id where user0_.id=?
可以看到,此时通过user无法来解除关联关系
测试2:通过idcard来解除关联关系
1 @Test 2 public void test(){ 3 4 Session session=factory.openSession(); 5 Transaction tx=session.beginTransaction(); 6 7 IdCard card=session.get(IdCard.class, 1); 8 card.setUser(null); 9 10 tx.commit(); 11 session.close(); 12 13 }
执行的SQL语句
1 Hibernate: select idcard0_.id as id1_0_0_, idcard0_.cardNo as cardNo2_0_0_, idcard0_.userid as userid3_0_0_ from t_idcard idcard0_ where idcard0_.id=? 2 Hibernate: update t_idcard set cardNo=?, userid=? where id=?
在数据库中也可看到通过idcard的确能够解除关联关系
3、删除操作
测试1:删除user
1 @Test 2 public void test(){ 3 4 Session session=factory.openSession(); 5 Transaction tx=session.beginTransaction(); 6 7 User user=session.get(User.class, 1); 8 session.delete(user); 9 10 tx.commit(); 11 session.close(); 12 13 }
如果此时将要删除的user数据在t_idcard表中没有对应相应的数据,那么可以删除成功,否则将会抛出异常,意思说有外键约束,该数据无法删除
测试2:删除idcard
1 public void test(){ 2 3 Session session=factory.openSession(); 4 Transaction tx=session.beginTransaction(); 5 IdCard card=session.get(IdCard.class, 1); 6 session.delete(card); 7 tx.commit(); 8 session.close(); 9 }
结果:删除成功
Question:在上面测试2中,我们删除了t_idcard中的数据,如果我需要当删除了t_idcard中的数据后,同样删除t_user中对应的属性,我们该怎么办呢?
Answer: 那么我们需要设置cascade属性为delete,我们在IdCard.hbm.xml
<many-to-one name="user" column="userid" class="User" unique="true" cascade="delete"></many-to-one>
也就是说,我们在删除对象idCard是,同样对其属性user也做删除动作
外键方式总结:
1、在有外键的一方,可以维护关联关系,可以建立关联关系,同样也可以解除关联关系,可以任意删除本对象,如果在hbm.xml中设置了cascade="delete",也可以删除关联对象
2、在没有外键的一方,不可以维护关联关系,所有无法建立关联关系,也无法解除关联关系。在删除过程中,如有没有外键值对应本条数据,可以成功删除,否则会抛出异常
二、基于主键的关联方式
基于外键方式:一个many-to-one(有外键方)和一个one-to-one(无外键方法)
基于主键方式:两个都是one-to-one
还是上面的例子,其它我们都不需要改变,我们只需要改变IdCard.hbm.xml就可以,具体代码如下
1 <?xml version="1.0" encoding="UTF-8" ?> 2 <!DOCTYPE hibernate-mapping PUBLIC 3 "-//Hibernate/Hibernate Mapping DTD 3.0//EN" 4 "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> 5 <hibernate-mapping package="com.proc.one2one"> 6 <class name="IdCard" table="t_idcard"> 7 <id name="id" type="int" column="id" > 8 <generator class="foreign"> 9 <param name="property">user</param> 10 </generator> 11 </id> 12 <property name="cardNo" type="string" column="cardNo" length="20" not-null="true"></property> 13 <one-to-one name="user" class="User" constrained="true"></one-to-one> 14 </class> 15 </hibernate-mapping>
代码说明:
1、由于是基于主键方式,所有对应t_idcard表的主键id也是来自于t_user表,所有对应IdCard主键生成策略我们选用foregin,其中还必须指定一个从参数property,表示该主键生成策略基于对象的那个属性,我们这里的属性是user
2、constrained="true":表示给t_idcard添加一个外键约束,默认为false,不添加外键约束
转载于:https://www.cnblogs.com/caoyc/p/5602418.html
Hibernate 一对一关联查询相关推荐
- hibernate hql 关联查询_Hibernate【关联查询篇】
1. Hibernate 关联查询 1.1. 说明 Hibernate框架支持通过配置映射关系实现多表关联查询. 1.2. 类型 关联查询分为:一对一(one-to-one).一对多(one-to-m ...
- 一对一关联查询注解@OneToOne的实例详解(一)
转载自: https://www.cnblogs.com/boywwj/p/8092915.html 一对一关联查询注解@OneToOne的实例详解 表的关联查询比较复杂,应用的场景很多,本文根据自己 ...
- 【mybatis】一对一关联查询
mybatis: 一对一关联查询 注意 代码部分 实体类(extity) mybatis mapper service controller 注意 在.xml文件编写中有报错,The content ...
- 【Hadoop基础教程】7、Hadoop之一对一关联查询
我们都知道一个产品唯一对应一个单价,本案例将通过两种类型输入文件:product类(产品)和price类(价格)进行一对一的关联查询,得到产品名(例如:手表)与产品价格(例如:$100)的关联信息. ...
- hibernate mysql 关联查询_Hibernate关联映射及高级查询
一.Hibernate中的关联关系 1.1.单向一对多关联关系 按照以下步骤配置hibernate中持久化类的一对多对象关联: (1).持久化类添加关联类的相关属性及getter/setter方法. ...
- 一对一关联查询注解@OneToOne的实例详解
表的关联查询比较复杂,应用的场景很多,本文根据自己的经验解释@OneToOne注解中的属性在项目中的应用.本打算一篇博客把增删改查写在一起,但是在改的时候遇到了一些问题,感觉挺有意思,所以写下第二篇专 ...
- Hibernate一对一关联映射配置
一对一关联 Hibernate提供了两种映射一对一关联关系的方式:按照外键映射和按照主键映射.下面以员工账号和员工档案表为例,介绍这两种映射方式,并使用这两种映射方式分别完成以下持久化操作: (1)保 ...
- MyBatis框架学习 DAY_03:如何解决无法封装问题 / 一对一关联查询 / 一对多关联查询
1. 通过查询时自定义别名的方式解决名称不一致而导致的无法封装数据的问题 假设,向用户组数据表(t_group)表中插入一些测试数据: INSERT INTO t_group (name) VALUE ...
- mysql 一对一关联查询_学习ThinkPHP的第20天--MySQL事务操作、查询事件、一对一关联...
之所以从20天才开始写随笔记是因为之前没搞自己的博客 从20天开始记录我在ThinkPHP中的点点滴滴 1.MySQL事务操作 /**事务操作*/ //startTrans启动事务.rollback回 ...
最新文章
- 科普篇:贝叶斯网络中的置信度传播
- adc如何获取周期_ADI小课堂丨今天咱们实例分析一款精密型ADC
- Training—Managing Audio Playback
- 收录网zblog主题导航模板
- 泛型系列3:获取泛型的类型
- Python可视化库Matplotlib的使用
- rowStyle设置Bootstrap Table行样式
- 数学分析原理 定理 6.8
- 评:网瘾不是问题 两代人文化冲突是根本
- 什么是php递归算法_PHP递归算法(三)
- 网线水晶头接法图解8根顺序
- 计算机键盘上每一个键的作用,电脑键盘上各种键的作用是什么 电脑键盘上每个键的作用说明【图文】...
- PPPOE拨号之一:Cisco 路由器adsl拨号配置
- 关于作虚拟软盘启动(转)
- pyecharts绘制日历图、漏斗图、仪表盘、水滴图
- 灵狐插件与IDEA的集成
- python取矩阵的某一行_Pythonnumpy提取矩阵的某一行或某一列的实例
- 详解百度指数搜索指数js逆向
- 阿里云国际站:实名认证上传材料填写样例(域名持有者为个人)
- 【Spring Cloud Alibaba】Spring Cloud Alibaba 分布式配置Nacos实践
热门文章
- oracle视图总结(创建、查询、改动、删除等)
- 如何实现红帽企业虚拟化管理平台Host主机所在数据中心的切换
- spring 启动完成后事件监听器处理
- install pymssql on centos
- SQL Server 2005中专用管理员连接 (DAC) 使用技巧修改系统表的方法
- php按城市显示搜索结果,在php错误中突出显示搜索结果
- sas一元回归分析_商业分析的应用
- Java NIO学习篇之缓冲区ByteBuffer详解
- Python机器学习:逻辑回归002逻辑回归的损失函数
- lsqnonneg函数_matlab中线性最小二乘问题求解