2.1、Hibernate多表操作--一对多、多对一、多对多。

一、什么是一对一、一对多、多对一及多对多关系(以简单的学生和老师的关系为例来说):

  1、一对一:学生具有学号和姓名(假定没有同名的学生)这两个属性,那么我知道了学生的学号也就能找到对应的学生姓名,如果我找到了学生的姓名也就能够找到学生的学号,两者之间是一一对应的,即一对一。

  2、一对多:以一个学生为对象,学生可以选择多门门课程,每门课程对应一个老师,即一个学生对应多个老师为他教学。那么这样就产生了一对多的关系。

  3、多对一:每一个学生都可以选择不同的课程,但是课程的数量是有限的,这样一来就会有多个学生选择选择同一门课,即就是多个学生对应于同一个老师。这样就产生了多对一的关系。

  4、多对多:从学生的角度来说:一个学生可以对应多个老师,从老师的角度来说:一个老师可以同时教多个学生。如果同时考虑学生和老师,那么就产生了多对多的关系。

二、简单的一对多关系(.xml):

  1、创建两张表:

1 create table t_item(
2     id number  primary key,
3     item_name varchar2(30)
4 );
5 create table t_image(
6     item_id number references t_item(id),
7     img_name varchar2(30)
8 );

  2、创建一个web项目,将Hibernate框架所需的jar包拷贝到lib目录下。

  3、粘贴上一篇日志中的HibernateTools工具类。

  4、创建一个ItemBean类

 1 package com.st.bean1;
 2 
 3 import java.util.HashSet;
 4 import java.util.Set;
 5 
 6 public class ItemBean {
 7     
 8     private long id;
 9     private String itemName;
10     
11     private Set<String>  imge =new  HashSet<String>();
12 
13     public long getId() {
14         return id;
15     }
16 
17     public void setId(long id) {
18         this.id = id;
19     }
20 
21     public String getItemName() {
22         return itemName;
23     }
24 
25     public void setItemName(String itemName) {
26         this.itemName = itemName;
27     }
28 
29     public Set<String> getImge() {
30         return imge;
31     }
32 
33     public void setImge(Set<String> imge) {
34         this.imge = imge;
35     }
36 
37     @Override
38     public String toString() {
39         return "ItemBean [id=" + id + ", itemName=" + itemName + ", imge="
40                 + imge + "]";
41     }
42 }

  5、.拷贝一个xxx.hbm.xml文件到com.st.bean目录下,重命名为item.hbm.xml,并修改class标签中的属性:使item表与ItemBean类之间存在映射关系:

 1 <?xml version="1.0"?>
 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 
 6 <hibernate-mapping>
 7     
 8     <class name="com.st.bean1.ItemBean" table="t_item">
 9         <id  name="id" column="ID">
10         <!-- class用于设置主键生成方式increment-自增长; assigned-指定的 -->
11             <generator class="increment"></generator>
12         </id>
13         <!-- 普通节点配置 -->
14         <property name="itemName" column="ITEM_NAME" type="java.lang.String" ></property>
15         
16         <!-- 基本的一对多配置
17            name:javaBean 里面的集合名
18            table:映射外键对应的表
19            key:映射的外表的外键
20            elememt:元素值对应的列
21         -->
22         <set name="imge" table="t_image">
23             <!-- 指定外键 -->
24             <key column="item_id"></key>
25             <element column="IMG_NAME" type="java.lang.String"></element>
26         </set>
27     </class>
28 </hibernate-mapping>

  6、拷贝一个hibernate.cfg.xml文件到src文件下,删除hibernate.xml文件中无用的映射文件后,添加映射文件-item.hbm.xml。

  7、6、在新建一个BeanTest类,在里面即可编写相应的增删改查的代码:

 1 @Test
 2     public void bean1test1(){
 3         // 获取一个会话
 4         Session session = HibernateTools.openSession();
 5         //开启一次事物
 6         Transaction tran = session.beginTransaction();
 7         ItemBean item = new ItemBean ();    
 8         item.setItemName("第四个项目");
 9         item.getImge().add("a4.jpg");
10         item.getImge().add("b4.jpg");
11         session.save(item);
12         //确认提交事物
13         tran.commit();
14     }
15     @Test
16     public void bean1test2(){
17         Session session = HibernateTools.openSession();
18         List<ItemBean> list= session.createCriteria(ItemBean.class).list();
19         for(ItemBean a : list)
20             System.out.println(a);
21     }
22     @Test
23     public void bean1test3(){
24         Session session = HibernateTools.openSession();
25         ItemBean item = (ItemBean)session.get(ItemBean.class,1L); //1L代表主键
26         Transaction tran = session.beginTransaction();
27         session.delete(item);
28         tran.commit();
29     }

 

 三、复杂的一对多关系:

  1、创建两张表:

 1 /*部门表*/
 2 create table dept(
 3     id number primary key,
 4     name varchar2(30)  /*部门名称*/
 5 );
 6 /*员工表*/
 7 create table employee(
 8     id number primary key,
 9     name varchar2(30),
10     sex  varchar2(2),
11     job varchar2(20),
12     dept_id number references dept(id)   /*所在部门*/
13 );

  2、创建一个DeptBean类

 1 package com.st.bean2;
 2 
 3 import java.util.HashSet;
 4 import java.util.Set;
 5 
 6 public class DeptBean {
 7     private long id;
 8     private String name;
 9     
10     private Set<EmployeeBean> emp = new HashSet<EmployeeBean>();
11 
12     @Override
13     public String toString() {
14         return "DeptBean [id=" + id + ", name=" + name +"]";
15     }
16 
17     public long getId() {
18         return id;
19     }
20 
21     public void setId(long id) {
22         this.id = id;
23     }
24 
25     public String getName() {
26         return name;
27     }
28 
29     public void setName(String name) {
30         this.name = name;
31     }
32 
33     public Set<EmployeeBean> getEmp() {
34         return emp;
35     }
36 
37     public void setEmp(Set<EmployeeBean> emp) {
38         this.emp = emp;
39     }
40 
41     
42 }

  3、创建一个EmployeeBean类

 1 package com.st.bean2;
 2 
 3 public class EmployeeBean {
 4     private long id;
 5     private String name;
 6     private String sex;
 7     private String job;
 8     private long deptId;
 9     //一个员工对应于一个部门号,所以这里不用集合
10     private DeptBean dept ;  //注意这个地方不要new对象,否则会无法运行 
11 
12     public long getId() {
13         return id;
14     }
15 
16     public void setId(long id) {
17         this.id = id;
18     }
19 
20     public String getName() {
21         return name;
22     }
23 
24     public void setName(String name) {
25         this.name = name;
26     }
27 
28     public String getSex() {
29         return sex;
30     }
31 
32     public void setSex(String sex) {
33         this.sex = sex;
34     }
35 
36     public String getJob() {
37         return job;
38     }
39 
40     public void setJob(String job) {
41         this.job = job;
42     }
43 
44     public long getDeptId() {
45         return deptId;
46     }
47 
48     public void setDeptId(long deptId) {
49         this.deptId = deptId;
50     }
51 
52     public DeptBean getDept() {
53         return dept;
54     }
55 
56     public void setDept(DeptBean dept) {
57         this.dept = dept;
58     }
59 
60     @Override
61     public String toString() {
62         return "EmployeeBean [id=" + id + ", name=" + name + ", sex=" + sex
63                 + ", job=" + job + ", deptId=" + deptId + ", dept=" + dept
64                 + "]";
65     }
66 }

  4、配置DeptBean这个类的xml文件

 1 <hibernate-mapping>
 2     
 3     <class name="com.st.bean2.DeptBean" table="DEPT">
 4         <id  name="id" column="ID">
 5         <!-- class用于设置主键生成方式increment-自增长; assigned-指定的 -->
 6             <generator class="increment"></generator>
 7         </id>
 8         <!-- 普通节点配置 -->
 9         <property name="name" column="NAME" type="java.lang.String" ></property>
10         
11         <!-- 一对多配置一的一方
12            name:javaBean 里面的集合名
13            cascade:级联关系(增加、删除、修改)
14            inverse:表示是否维护关系
15            key:映射的外表的外键
16            class:对应外表的JavaBean
17         -->
18         <set name="emp" cascade="all" inverse="false">
19             <!-- 指定外键 -->
20             <key column="dept_id"></key>
21             <one-to-many class="com.st.bean2.EmployeeBean"/>  <!-- 外表对应的JavaBean -->
22         </set>
23     </class>
24 </hibernate-mapping>

  5、配置EmployeeBean这个类的xml文件

 1 <hibernate-mapping>
 2     
 3     <class name="com.st.bean2.EmployeeBean" table="employee">
 4         <id  name="id" column="ID">
 5         <!-- class用于设置主键生成方式increment-自增长; assigned-指定的 -->
 6             <generator class="increment"></generator>
 7         </id>
 8         <!-- 普通节点配置 -->
 9         <property name="name" column="NAME" type="java.lang.String" ></property>
10         <property name="sex" column="SEX" ></property>
11         <property name="job" column="JOB" ></property>
12         
13         <!-- 多的一方的属性名 -->
14         <many-to-one name="dept" column="DEPT_ID"></many-to-one>
15     </class>
16 </hibernate-mapping>

  6、将上面两个类的配置文件映射到hibernate.cfg.xml文件中去。

  7、在BeanTest类下面编写测试代码:

 1 @Test
 2     public void bean2test1(){
 3         // 获取一个会话
 4         Session session = HibernateTools.openSession();
 5         //开启一次事物
 6         Transaction tran = session.beginTransaction();
 7 
 8         //首先在dept中新增一条数据,再在关联的employee中新增一条数据
 9         DeptBean dept = new DeptBean();
10         //先读去dept中的数据,再在读取的基础上关联的在employee中新增一条数据
11 //        DeptBean dept = (DeptBean) session.get(DeptBean.class,1L); //1L代表主键
12         EmployeeBean emp = new EmployeeBean();
13         dept.setName("技术部");
14         emp.setName("陈泽俊");
15         emp.setSex("男");
16         emp.setJob("STM32");
17         emp.setDeptId(1);
18         dept.getEmp().add(emp);
19         session.save(dept);
20         //确认提交事物
21         tran.commit();
22     }
23     @Test
24     public void bean2test2(){
25         Session session = HibernateTools.openSession();
26                 List<DeptBean> list= session.createCriteria(DeptBean.class).list();
27         for(DeptBean a : list)
28             System.out.println(a.getEmp());
29         System.out.println("/************************************************************************/");
30         List<EmployeeBean> list1= session.createCriteria(EmployeeBean.class).list();
31         for(EmployeeBean a : list1)
32             System.out.println(a);
33     }
34     @Test
35     //注意以下三种删除方法的不同之处,更新和删除一样
36     public void bean2test3(){
37         Session session = HibernateTools.openSession();
38         Transaction tran = session.beginTransaction();
39         //先将employee的dept_id更新为null,再讲dept删除
40 /*        DeptBean dept = new DeptBean();
41         dept.setId(1L);
42         session.delete(dept);*/
43         //直接将employee中的类容删除,dept中的类容不删除
44 /*        EmployeeBean employee = new EmployeeBean();
45         employee.setId(1L);
46         session.delete(employee);*/
47         //将employee中的关联外键dept_id更新为null,再删除employee中的数据再删除dept中的数据
48         DeptBean dept = (DeptBean) session.get(DeptBean.class, 1L);
49         session.delete(dept);
50         tran.commit();
51     }

 

四、多对多关系

  1、新建三张表t_user、t_role及第三张关联表user_role

 1 create table t_user(
 2     id number primary key,  
 3     name varchar2(30),
 4     sex varchar2(10)
 5 );
 6 create table t_role(
 7     id number primary key,
 8     post varchar2(30),--职位
 9     pay number --薪资
10 );
11 create table user_role(
12     user_id number references t_user(id) ,
13     role_id number references t_role(id)
14 );
15 
16 
17 select *from t_role;
18 select *from t_user;
19 select *from user_role;
20 
21 drop table user_role;
22 drop table t_role;
23 drop table t_user;

  2、上述已有的目下新建一个bean3包,再在包下面新建两个类:UserBean和RoleBean

    a)userBean

 1 package com.st.bean3;
 2 import java.util.HashSet;
 3 import java.util.Set;
 4 public class UserBean {
 5     private long id;
 6     private String name;
 7     private String sex;
 8     
 9     private Set<RoleBean> role = new HashSet<RoleBean>();
10     
11     public long getId() {
12         return id;
13     }
14     public void setId(long id) {
15         this.id = id;
16     }
17     public String getName() {
18         return name;
19     }
20     public void setName(String name) {
21         this.name = name;
22     }
23     public String getSex() {
24         return sex;
25     }
26     public void setSex(String sex) {
27         this.sex = sex;
28     }
29     public Set<RoleBean> getRole() {
30         return role;
31     }
32     public void setRole(Set<RoleBean> role) {
33         this.role = role;
34     }
35     @Override
36     public String toString() {
37         return "UserBean [id=" + id + ", name=" + name + ", sex=" + sex
38                 + ", role=" + role + "]";
39     }
40 }

    b)RoleBean

 1 package com.st.bean3;
 2 import java.util.HashSet;
 3 import java.util.Set;
 4 public class RoleBean {
 5     private long id;
 6     private String post;//职位
 7     private int pay;    //薪资
 8     
 9     private Set<UserBean>  user = new HashSet<UserBean>();
10 
11     public long getId() {
12         return id;
13     }
14     public void setId(long id) {
15         this.id = id;
16     }
17     public String getPost() {
18         return post;
19     }
20     public void setPost(String post) {
21         this.post = post;
22     }
23     public int getPay() {
24         return pay;
25     }
26     public void setPay(int pay) {
27         this.pay = pay;
28     }
29     public Set<UserBean> getUser() {
30         return user;
31     }
32     public void setUser(Set<UserBean> user) {
33         this.user = user;
34     }
35     @Override
36     public String toString() {
37         return "RoleBean [id=" + id + ", post=" + post + ", pay=" + pay + "]";
38     }
39 }

  3、在bean包下面添加两个Bean类的.xml配置文件

    a)user.hbm.xml

 1 <hibernate-mapping>
 2     
 3     <class name="com.st.bean3.UserBean" table="T_USER">
 4         <id  name="id" column="ID">
 5         <!-- class用于设置主键生成方式increment-自增长; assigned-指定的 -->
 6             <generator class="increment"></generator>
 7         </id>
 8         <!-- 普通节点配置 -->
 9         <property name="name" column="NAME" type="java.lang.String" ></property>
10         <property name="sex" column="SEX" type="java.lang.String" ></property>
11         
12         <!-- 多对多关系映射
13             name:javaBean对应的属性名
14             table:中间表
15             key中的column:与本类主键对应的中间表的外键
16             many-to-many中的column:class里设置的类的主键对应的中间表的外键
17          -->
18         <set name="role" table = "user_role"  cascade="save-update" inverse="false">
19             <key column="USER_ID"></key>
20             <many-to-many class="com.st.bean3.RoleBean" column="ROLE_ID"></many-to-many>
21         </set>
22     </class>
23 </hibernate-mapping>

    b)role.hbm.xml

 1 <hibernate-mapping>
 2     
 3     <class name="com.st.bean3.RoleBean" table="T_ROLE">
 4         <id  name="id" column="ID">
 5         <!-- class用于设置主键生成方式increment-自增长; assigned-指定的 -->
 6             <generator class="increment"></generator>
 7         </id>
 8         <!-- 普通节点配置 -->
 9         <property name="post" column="POST" type="java.lang.String" ></property>
10         <property name="pay" column="PAY"  ></property>
11         
12         <set name="user" table="user_role" cascade="save-update" inverse="false">
13            <key column="ROLE_ID"></key>
14            <many-to-many class="com.st.bean3.UserBean" column="USER_ID"/>
15         </set>
16     </class>
17 </hibernate-mapping>

  4、早hibernate.cfg.xml文件中引入步骤三种的两个配置文件:

1          <mapping resource="com/st/bean3/role.hbm.xml"/>
2          <mapping resource="com/st/bean3/user.hbm.xml"/> 

  5、在BeanTest类中编写测试代码

 1     @Test
 2     public void bean3test1(){
 3         // 获取一个会话
 4         Session session = HibernateTools.openSession();
 5         //开启一次事物
 6         Transaction tran = session.beginTransaction();
 7         UserBean user = new UserBean();
 8         RoleBean role = (RoleBean) session.get(RoleBean.class,3L);
 9 //        RoleBean role = new RoleBean();
10         user.setName("陈泽俊");
11         user.setSex("男");
12 //        role.setPost("单片机开发工程师");
13 //        role.setPay(9000);
14         role.getUser().add(user);
15         session.save(role);
16         //确认提交事物
17         tran.commit();
18     }
19     @Test
20     public void bean3test2(){
21         // 获取一个会话
22         Session session = HibernateTools.openSession();
23 /*        List<UserBean> list = session.createCriteria(UserBean.class).list();
24         for(UserBean user : list)
25             System.out.println(user);*/
26         String hql = "select new Map(u.name as name,u.sex as sex,r.post as post,r.pay as pay) from UserBean u join u.role r";
27         List<Map<String,Object>> list = session.createQuery(hql).list();
28         for(Map<String,Object> data : list)
29             System.out.println(data);
30     }

 

19:41:06

posted @ 2016-09-12 14:36  陈泽俊  阅读(441)  评论(0编辑  收藏  举报