Hibernate 多对一关联查询
版权声明:本文为博主原创文章,如需转载请标注转载地址。
博客地址:http://www.cnblogs.com/caoyc/p/5598269.html
一、单向多对一和双向多对一的区别
如果只需要从一方获取另一方数据,就用单向多对一;如果需要从双方都获取对方数据,就用双向多对一。
如果有两个对象,一个为User对象,一个为Department对象,一个用户只能属于一个部门,而一个部门可以包含多个用户。这样就是多对一关系。如下图

假设:我们需要通过用户找到所对应的部门,不需要通过部门查询该部门有哪些用户,就采用单向多对一关系
如果:我们不仅需要通过用户获取所对应的部门,还需要通过部门对象获取该部门下的用户,那么就采用双向多对一
二、单向多对一关系
Department.java
package com.proc.pojo;
import java.io.Serializable;
public class Department implements Serializable {
private Integer id;
private String deptname;
//提供构造方法
public Department() {
}
public Department(String deptname) {
this.deptname = deptname;
}
//getter和setter实现
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getDeptname() {
return deptname;
}
public void setDeptname(String deptname) {
this.deptname = deptname;
}
}
User.java
package com.proc.pojo;
import java.io.Serializable;
public class User implements Serializable {
private Integer id;
private String name;
private Department dept;
//提供构造方法
public User() {
}
public User(String name) {
this.name = name;
}
//getter和setter实现
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 getDept() {
return dept;
}
public void setDept(Department dept) {
this.dept = dept;
}
}
Department.hbm.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.proc.pojo">
<class name="Department" table="department">
<id name="id" type="int">
<generator class="native"></generator>
</id>
<property name="deptname" length="20" not-null="true"></property>
</class>
</hibernate-mapping>
User.hbm.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.proc.pojo">
<class name="User">
<id name="id" type="int">
<generator class="native"></generator>
</id>
<property name="name" length="20" not-null="true"></property>
<many-to-one name="dept" column="deptid" class="Department" ></many-to-one>
</class>
</hibernate-mapping>
代码讲解:在配置User(多)->Department(一)时,采用外键映射,其中
name="dept":User对象dept属性
class="Department":表示该dept属性的类型是Department类型,因为User和Department在同一个包中,所以直接使用了类名称
column="deptid":指定在用user表中,对应department表的中主键的列为deptid
这里并没有指出user表中deptid对应的值department表中哪一列,默认为主键,这里也会自动给deptid列添加一个外键约束
foreign-key="none":不创建外键约束,如果将none改成其他的,即为指定外键名称
测试代码:
package com.proc.test; import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test; import com.proc.pojo.Department;
import com.proc.pojo.User; public class TestOneToMany { private static SessionFactory factory=new Configuration()
.configure()
.addClass(User.class)
.addClass(Department.class)
.buildSessionFactory();
@Test
public void set(){ Session session=factory.openSession();
Transaction tran=session.beginTransaction();
Department dept1=new Department("IT部"); User user1=new User("caoyc");
User user2=new User("zhh"); user1.setDept(dept1);
user2.setDept(dept1); session.save(dept1);
session.save(user1);
session.save(user2); tran.commit();
session.close();
}
}
在控制台输出SQL语句:
Hibernate: create table department (id integer not null auto_increment, deptname varchar(20) not null, primary key (id))
Hibernate: create table User (id integer not null auto_increment, name varchar(20) not null, deptid integer, primary key (id))
Hibernate: alter table User add constraint FK66lqw6kl2gcxhs44gamc91fbd foreign key (deptid) references department (id)
Hibernate: insert into department (deptname) values (?)
Hibernate: insert into User (name, deptid) values (?, ?)
Hibernate: insert into User (name, deptid) values (?, ?)
测试:如果将测试代码中32-34行代码改成
session.save(user1);
session.save(user2);
session.save(dept1);
在控制台输出SQL语句:
Hibernate: create table department (id integer not null auto_increment, deptname varchar(20) not null, primary key (id))
Hibernate: create table User (id integer not null auto_increment, name varchar(20) not null, deptid integer, primary key (id))
Hibernate: alter table User add constraint FK66lqw6kl2gcxhs44gamc91fbd foreign key (deptid) references department (id)
Hibernate: insert into User (name, deptid) values (?, ?)
Hibernate: insert into User (name, deptid) values (?, ?)
Hibernate: insert into department (deptname) values (?)
Hibernate: update User set name=?, deptid=? where id=?
Hibernate: update User set name=?, deptid=? where id=?
这里多出了两行update User代码,也就是在我们先添加向user表中插入数据时,而还在department总还没有数据,当插入department数据后,在通过update的方式来修改user表
总结:在我们插入多对一关系时,需要先保存(一)的一方,然后在保存(多)的一方,这样可以减少SQL执行语句,如果是单向多对一关系,在添加多对一关系,只需要在(多)的一方的映射文件(.hbm.xml)中添加many-to-one就可以了
单向多对一删除操作:
a、删除(多)的一方(User),删除成功
b、删除(一)的一方(Department),如果user表中没有该部门的用户,则删除成功
c、删除(一)的一方(Department),如果user表中还有改部门的用户,则删除失败,因为有外键约束
三、双向多对一操作
第一步:在Department.java中添加一个users属性,并提供get和set方法
private Set<User> users;
public Set<User> getUsers() {
return users;
}
public void setUsers(Set<User> users) {
this.users = users;
}
第二步:在Department.hbm.xml中添加关联映射

既可以通过User的到Department,也可以通过Department得到Set<User>
双向多对一删除:
a、删除(多)的一方,总是成功
b、删除(少)的一方,如果inverse=“false”,成功
c、删除(少)的一方,如果inverse=“true”,失败
Hibernate 多对一关联查询的更多相关文章
- Hibernate 多对多关联查询条件使用
from Brand as b inner join fetch b.styles as s where s.styleId=?
- hibernate多对多关联映射
关联是类(类的实例)之间的关系,表示有意义和值得关注的连接. 本系列将介绍Hibernate中主要的几种关联映射 Hibernate一对一主键单向关联Hibernate一对一主键双向关联Hiberna ...
- Hibernate-ORM:11.Hibernate中的关联查询
------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥------------- 本篇博客将讲述Hibernate中的关联查询,及其级联(cascade)操作,以及指定哪一方维护关联关系的(i ...
- atitit.atitit.hb many2one relate hibernate 多对一关联配置..
atitit.atitit.hb many2one relate hibernate 多对一关联配置.. 1. 多对一单向 @ManyToOne 1 1. 其中@JoinColumn 注解 2 2. ...
- NHibernate教程(11)--多对多关联查询
本节内容 多对多关系引入 多对多映射关系 多对多关联查询 1.原生SQL关联查询 2.HQL关联查询 3.Criteria API关联查询 结语 多对多关系引入 让我们再次回顾在第二篇中建立的数据模型 ...
- mybatis实战教程二:多对一关联查询(一对多)
多对一关联查询 一.数据库关系.article表和user表示多对一的关系 CREATE TABLE `article` ( `id` ) NOT NULL AUTO_INCREMENT, `user ...
- Python--day64--找到作者关联的所有书籍对象、ORM多对多关联查询的原理
找到当前作者关联的所有书籍对象: ORM多对多关联查询的原理: 编辑作者:
- mybatis 14: 多对一关联查询
业务背景 根据订单id查询订单的信息,以及该订单所属的客户的基本信息(不包括该客户自己的订单信息) 两张数据表 客户表 订单表 实体类 客户实体类:Customer private Integer i ...
- 05.Hibernate多对多关联
前言:本文讲解使用Hibernate映射多对多关联关系,并使用多种方式映射多对多关联. 1.数据库表的多对多关系 本文根据学生信息表(tb_student)和教师信息表(tb_teac ...
随机推荐
- oracle中 char,varchar,varchar2的区别
区别: 1. CHAR的长度是固定的,而VARCHAR2的长度是可以变化的, 比如,存储字符串“abc",对于CHAR (20),表示你存储的字符将占20个字节(包括17个空字符) ...
- Linux运维 -- 文件备份同步系列
[1.]文件备份与恢复 #()整盘数据备份-->另一个盘/一个image文件 dd if=/dev/sdb of=/dev/sde #备份到指定的image文件中 dd if=/dev/sdb ...
- Friends number NBUT - 1223 (暴力打表)
Paula and Tai are couple. There are many stories between them. The day Paula left by airplane, Tai s ...
- [Contest20170910]string
给定一个由且仅由字符$'H','T'$构成的字符串$S$ 给定一个最初为空的字符串$T$,每次随机地在$T$的末尾添加$'H'$或者$'T'$ 问当$S$为$T$的后缀时,在末尾添加字符的期望次数 妙 ...
- 【强联通分量缩点】【Tarjan】bzoj1051 [HAOI2006]受欢迎的牛
就是看是否有一些点,从其他任何点出发都可到达 定理:有向无环图中唯一出度为0的点,一定可以由任何点出发均可达. 所以缩点,若出度为零的点(强联通分量)唯一,则答案为该强联通分量中点的度数. 若不唯一, ...
- 【费用流】BZOJ1877[SDOI2009]-晨跑
[题目大意] Elaxia每天从寝室出发跑到学校,保证寝室编号为1,学校编号为N. Elaxia的晨跑计划是按周期(包含若干天)进行的,由于他不喜欢走重复的路线,所以在一个周期内,每天的晨跑路线都不会 ...
- Ubuntu 16.04安装KVM
说明:其实之前我有安装过KVM,只是但是不知道这个就是KVM,而当时只知道叫做QEMU虚拟机. 安装: http://www.cnblogs.com/EasonJim/p/7215836.html h ...
- Ubuntu下查看APT安装的软件安装路径和版本
1.查询安装路径 dpkg -L 软件名 例如:dpkg -L gedit dpkg -L gedit /. /usr /usr/bin /usr/bin/gedit /usr/share /usr/ ...
- ms_sql_server_architecture
We have classified the architecture of SQL Server into the following parts for easy understanding − ...
- [Android实例] 推荐给你们一个好用的ListView、RecyclerView适配器
https://github.com/vihuela/RecyclerViewHelpper 如果用过RecyclerView的人都知道,高度不会包裹,然后写法好像也不是很简洁,甚至点击事件不好设 置 ...