Hibernate 多对一关联查询
2016-06-19 16:25
246 查看
版权声明:本文为博主原创文章,[b]如需转载请标注转载地址。[/b]
博客地址:http://www.cnblogs.com/caoyc/p/5598269.html一、单向多对一和双向多对一的区别
如果只需要从一方获取另一方数据,就用单向多对一;如果需要从双方都获取对方数据,就用双向多对一。如果有两个对象,一个为User对象,一个为Department对象,一个用户只能属于一个部门,而一个部门可以包含多个用户。这样就是多对一关系。如下图
假设:我们需要通过用户找到所对应的部门,不需要通过部门查询该部门有哪些用户,就采用单向多对一关系
如果:我们不仅需要通过用户获取所对应的部门,还需要通过部门对象获取该部门下的用户,那么就采用双向多对一
二、单向多对一关系
Department.javapackage 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”,失败
相关文章推荐
- js实现单例模式
- (三)JavaScript的数组、键值对和原型
- Java注解入门
- Tomcat Unable to open the service 'Tomcat*'
- QT自定义窗口(无边框,自由拖动)
- IDEA使用教程
- iOS开发 - 第02篇 - UI进阶 - 15 - 彩票(第二天)
- Redis服务器管理
- 设计模式-13-门面模式
- CUDA(9)之并行计算之CUDA
- 《剑指offer》:[41-1]和为S的连续整数序列
- Toolbar的介绍与用法
- 通过HtmlEmail 发送邮件
- word frequency counter python 页面词汇频率小代码
- CSS(3) 字体
- 直方图的反向投影
- Javascript面向对象编程(三):非构造函数的继承
- linux中的wheel用户组是什么?
- INNER JOIN——内部链接
- 推荐系统算法(1)<InfoQ系列翻译文章,2016>