HIbernate入门3

HIbernate的一对多操作:

  1. 创建实体类:一个Customer类(客户类)和一个LinkMan类(联系人),两者的关系为:一个客户中可能有多个联系人(关于一对多的实体类之间的关联,不做详细介绍,看下代码)。

  Customer:

package com.geore.pojo.customer;

import java.util.HashSet;
import java.util.Set;

import com.geore.pojo.linkman.LinkMan;

public class Customer {
    private String cid = null;
    private String custLevel = null;
    private String custName = null;
    private String custSource = null;
    private String custMobile = null;
    private Set<LinkMan> mans = new HashSet<LinkMan>();

    @Override
    public String toString() {
        return "Customer [cid=" + cid + ", custLevel=" + custLevel
                + ", custName=" + custName + ", custSource="
                + custSource + ", custMobile=" + custMobile + "]";
    }

    public String getCid() {
        return cid;
    }

    public void setCid(String cid) {
        this.cid = cid;
    }

    public String getCustLevel() {
        return custLevel;
    }

    public void setCustLevel(String custLevel) {
        this.custLevel = custLevel;
    }

    public String getCustName() {
        return custName;
    }

    public void setCustName(String custName) {
        this.custName = custName;
    }

    public String getCustSource() {
        return custSource;
    }

    public void setCustSource(String custSource) {
        this.custSource = custSource;
    }

    public String getCustMobile() {
        return custMobile;
    }

    public void setCustMobile(String custMobile) {
        this.custMobile = custMobile;
    }

    public Set<LinkMan> getMans() {
        return mans;
    }

    public void setMans(Set<LinkMan> mans) {
        this.mans = mans;
    }
}
Customer

  LinkMan:

 1 package com.geore.pojo.linkman;
 2 
 3 import com.geore.pojo.customer.Customer;
 4 
 5 public class LinkMan {
 6     private String lid = null;
 7     private String linkName = null;
 8     private String linkGender = null;
 9     private String linkPhone = null;
10     private Customer customer = null;
11     
12     public LinkMan() {
13         super();
14     }
15     @Override
16     public String toString() {
17         return "LinkMan [lid=" + lid + ", linkName=" + linkName
18                 + ", linkGender=" + linkGender + ", linkPhone=" + linkPhone
19                 + ", customer=" + customer + "]";
20     }
21     public String getLid() {
22         return lid;
23     }
24     public void setLid(String lid) {
25         this.lid = lid;
26     }
27     public String getLinkName() {
28         return linkName;
29     }
30     public void setLinkName(String linkName) {
31         this.linkName = linkName;
32     }
33     public String getLinkGender() {
34         return linkGender;
35     }
36     public void setLinkGender(String linkGender) {
37         this.linkGender = linkGender;
38     }
39     public String getLinkPhone() {
40         return linkPhone;
41     }
42     public void setLinkPhone(String linkPhone) {
43         this.linkPhone = linkPhone;
44     }
45     public Customer getCustomer() {
46         return customer;
47     }
48     public void setCustomer(Customer customer) {
49         this.customer = customer;
50     }
51 }
LinkMan

  2. 配置实体类的Hibernate实体类配置文件

  对于Hibernate实体类的配置:第一,首先将基本的class,id和property等标签的内容配置好之后,因为在Customer中,是一个一对多的关系,因此在Customer实体类中用Set集合表示一个Customer可以拥有多个联系人(Hibernate规定,在表示一对多的时候,使用的集合必须为Set集合),因此在配置文件中,需要对这种关系进行配置,而Hibernate配置文件提供了一个set标签进行配置,具体配置见下代码:

 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>
 6     <class name="com.geore.pojo.customer.Customer" table="t_customer">
 7         <id name="cid" column="cid">
 8             <generator class="uuid"></generator>
 9         </id>
10         <property name="custLevel" column="custLevel"></property>
11         <property name="custName" column="custName"></property>
12         <property name="custSource" column="custSource"></property>
13         <property name="custMobile" column="custMobile"></property>
14         <set name="mans" cascade="save-update,delete">
15             <key column="clid"></key>
16             <one-to-many class="com.geore.pojo.linkman.LinkMan"/>
17         </set>
18     </class>
19 </hibernate-mapping>
Customer.hbm.xml

   同时在LinkMan.hbm.xml文件中,也需要进行配置,因为Hibernate是进行双向关联,因此在LinkMan中也会有一个字段关联到Customer类,一般这个字段我们使用Customer的对象来表示,所以在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>
 6     <class name="com.geore.pojo.linkman.LinkMan" table="t_linkman">
 7         <id name="lid" column="lid">
 8             <generator class="uuid"></generator>
 9         </id>
10         <property name="linkName" column="linkName"></property>
11         <property name="linkGender" column="linkGender"></property>
12         <property name="linkPhone" column="linkPhone"></property>
13         <many-to-one name="customer" class="com.geore.pojo.customer.Customer" not-found="ignore">
14             <column name="clid"></column>
15         </many-to-one>
16     </class>
17 </hibernate-mapping>
LinkMan.hbm.xml

  3. 一对多的级联操作:

  (1)、保存操作

  代码片段:

 1 @Test
 2     public void fun1() {
 3         Transaction ts = null;
 4         Session session = null;
 5         SessionFactory factory = null;
 6         try {
 7             factory = Tools.getSessionFactory();
 8             session = factory.openSession();
 9             ts = session.beginTransaction();
10             // 一对多的操作
11             Customer customer = new Customer();
12             customer.setCustLevel("vip");
13             customer.setCustMobile("1378*******");
14             customer.setCustName("Geore");
15             customer.setCustSource("Baidu");
16             LinkMan linkman = new LinkMan();
17             linkman.setLinkGender("M");
18             linkman.setLinkName("Mr.Li");
19             linkman.setLinkPhone("****-*******");
20             // 添加兩個對象的之间的一对多关系
21             customer.getMans().add(linkman);
22             linkman.setCustomer(customer);
23             // 添加到数据库
24             session.save(customer);
25             session.save(linkman);
26 
27             ts.commit();
28         } catch (Exception e) {
29             ts.rollback();
30             e.printStackTrace();
31         } finally {
32             session.close();
33         }
34     }
35 
36     @Test
37     // 级联保存的简化写法
38     public void fun2() {
39         Transaction ts = null;
40         Session session = null;
41         SessionFactory factory = null;
42         try {
43             factory = Tools.getSessionFactory();
44             session = factory.openSession();
45             ts = session.beginTransaction();
46             // 一对多的操作
47             Customer customer = new Customer();
48             customer.setCustLevel("svip");
49             customer.setCustMobile("1378*******");
50             customer.setCustName("Alley");
51             customer.setCustSource("Google");
52             LinkMan linkman = new LinkMan();
53             linkman.setLinkGender("F");
54             linkman.setLinkName("Mr.Wang");
55             linkman.setLinkPhone("****-*******");
56             // 添加兩個對象的之间的一对多关系
57             customer.getMans().add(linkman);
58             // 添加到数据库
59             session.save(customer);
60             ts.commit();
61         } catch (Exception e) {
62             ts.rollback();
63             e.printStackTrace();
64         } finally {
65             session.close();
66         }
67     }
View Code

  运行截图:

 

对于上面的简单方法的插入,需要在Hibernate实体类的配置文件中进行配置,配置代码如下:

<set name="mans" cascade="save-update">
需要配置的就是cascade="save-update",这个save-update表示的就是自动的会对一对多的关系在HIbernate底层进行处理,配置了这个,就不需要在代码中双向关联对应的实体类对象了

  (2)、删除操作

  代码片段:

 1 @Test
 2     // 级联删除操作,在set标签中进行配置
 3     public void fun3() {
 4         Transaction ts = null;
 5         Session session = null;
 6         SessionFactory factory = null;
 7         try {
 8             factory = Tools.getSessionFactory();
 9             session = factory.openSession();
10             ts = session.beginTransaction();
11 
12             // 通过id找到对应的数据记录
13             Customer customer = session.get(Customer.class,
14                     "4028d4015e6dedd5015e6deddbeb0000");
15             session.delete(customer);
16 
17             ts.commit();
18         } catch (Exception e) {
19             ts.rollback();
20             e.printStackTrace();
21         } finally {
22             session.close();
23         }
24     }
View Code

  运行截图:

同样的,对于删除操作,因为是1对多,删除一个Customer,那么对应的Customer下的LinkMan也要删除,那么这样删除的话,同样要配置Hibernate的配置文件,来实现级联删除。代码如下:

1 <set name="mans" cascade="save-update,delete">
2     <key column="clid"></key>
3     <one-to-many class="com.geore.pojo.linkman.LinkMan"/>
4 </set>
5 同样的也是在cascade中进行配置,在这个属性中给个只delete,至于之前保存操作的save-update不用删除,只需要在后面加上一个,号,在写上delete表示进行级联删除操作即可

  

  (3)、一对多表的维护操作

  代码片段:

 1 @Test
 2     // 将Mr.wang公司修改带Baidu,加上not-found="ignore",否则报错,原因不明
 3     public void fun4() {
 4         Transaction ts = null;
 5         Session session = null;
 6         SessionFactory factory = null;
 7         try {
 8             factory = Tools.getSessionFactory();
 9             session = factory.openSession();
10             ts = session.beginTransaction();
11 
12             // 通过id找到baidu公司客户记录
13             Customer customer = session.get(Customer.class,
14                     "4028d4015e6f04a6015e6f04ad120000");
15             System.out.println(customer);
16             // 通过id找到联系人Mr.wang的记录
17             LinkMan Mr_wang = session.get(LinkMan.class,
18                     "4028d4015e6f04d3015e6f04da2c0001");
19             System.out.println(Mr_wang);
20             customer.getMans().add(Mr_wang);
21             Mr_wang.setCustomer(customer);
22 
23             ts.commit();
24         } catch (Exception e) {
25             ts.rollback();
26             e.printStackTrace();
27         } finally {
28             session.close();
29         }
30     }
View Code

  运行截图:

  注意:使用这个修改的时候,须在一对多的多方的实体类配置文件中,配置如下属性值:

<many-to-one name="customer" class="com.geore.pojo.customer.Customer" not-found="ignore">
就是not-found="ignore",现在还没有发现具体造成原因,不加上此句将报异常

Hibernate 多对多的操作

 1. 创建多对多的实体类,并且在实体类中建立起表的多对多关系(用户表和角色表,一个用户可以有多个角色,一个角色也可以属于多个用户),实体类如下:

  Role:

 1 package com.geore.pojo.role;
 2 
 3 import java.util.HashSet;
 4 import java.util.Set;
 5 
 6 import com.geore.pojo.users.Users;
 7 
 8 public class Role {
 9     private String rid = null;
10     private String roleName = null;
11     private String roleMemo = null;
12     private Set<Users> users = new HashSet<Users>();
13     
14     public Set<Users> getUsers() {
15         return users;
16     }
17     public void setUsers(Set<Users> users) {
18         this.users = users;
19     }
20     @Override
21     public String toString() {
22         return "Role [rid=" + rid + ", roleName=" + roleName + ", roleMemo="
23                 + roleMemo + "]";
24     }
25     public String getRid() {
26         return rid;
27     }
28     public void setRid(String rid) {
29         this.rid = rid;
30     }
31     public String getRoleName() {
32         return roleName;
33     }
34     public void setRoleName(String roleName) {
35         this.roleName = roleName;
36     }
37     public String getRoleMemo() {
38         return roleMemo;
39     }
40     public void setRoleMemo(String roleMemo) {
41         this.roleMemo = roleMemo;
42     }
43 }
Role

  Users:

 1 package com.geore.pojo.users;
 2 
 3 import java.util.HashSet;
 4 import java.util.Set;
 5 
 6 import com.geore.pojo.role.Role;
 7 
 8 public class Users {
 9     private String uid = null;
10     private String username = null;
11     private String password = null;
12     private Set<Role> roles = new HashSet<Role>();
13     
14     public Set<Role> getRoles() {
15         return roles;
16     }
17     public void setRoles(Set<Role> roles) {
18         this.roles = roles;
19     }
20     @Override
21     public String toString() {
22         return "Users [uid=" + uid + ", username=" + username + ", password="
23                 + password + "]";
24     }
25     public String getUid() {
26         return uid;
27     }
28     public void setUid(String uid) {
29         this.uid = uid;
30     }
31     public String getUsername() {
32         return username;
33     }
34     public void setUsername(String username) {
35         this.username = username;
36     }
37     public String getPassword() {
38         return password;
39     }
40     public void setPassword(String password) {
41         this.password = password;
42     }
43 }
Users

2. 多对多关系的配置文件,Hibernate的多对多也是进行双向关联,因此对于多对多关系的两表均需要进行配置

 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>
 6     <class name="com.geore.pojo.users.Users" table="t_users">
 7         <id name="uid" column="uid">
 8             <generator class="uuid"></generator>
 9         </id>
10         <property name="username" column="username"></property>
11         <property name="password" column="password"></property>
12         <set name="roles" table="t_roleuser" cascade="save-update,delete">
13             <key column="userId"></key>
14             <many-to-many class="com.geore.pojo.role.Role" column="roleId"></many-to-many>
15         </set>
16     </class>
17 </hibernate-mapping>
Users.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>
 6     <class name="com.geore.pojo.role.Role" table="t_role">
 7         <id name="rid" column="rid">
 8             <generator class="uuid"></generator>
 9         </id>
10         <property name="roleName" column="roleName"></property>
11         <property name="roleMemo" column="roleMemo"></property>
12         <set name="users" table="t_roleuser" cascade="save-update,delete">
13             <!-- 第三张表中Users表的外键id -->
14             <key column="roleId"></key>
15             <!-- class:表示的是set集合关联的对象的全路径;column:表示关联表在第三张表中的外键 -->
16             <many-to-many class="com.geore.pojo.users.Users" column="userId"></many-to-many>
17         </set>
18     </class>
19 </hibernate-mapping>
Role.hbm.xml

  对于这两个配置文件而言,因为是多对多的关系,因此在实体类中均需要集合进行保存,因此在配置文件中使用set标签来配置多对多的关系,又因为对于多对多的关系,一般使用的是第三张表来维护多对多的欢喜,因此在set标签中有一个属性table,表示的就是第三张表的名字.

3. 多对多的级练操作

  (1)、保存操作:

代码片段:

 1 @Test
 2     public void fun1() {
 3         // 多对多级练操作
 4         Transaction ts = null;
 5         Session session = null;
 6         SessionFactory factory = null;
 7         try {
 8             factory = Tools.getSessionFactory();
 9             session = factory.openSession();
10             ts = session.beginTransaction();
11 
12             // 往用户中添加角色
13             Users u1 = new Users();
14             u1.setUsername("Alley");
15             u1.setPassword("123456");
16 
17             Users u2 = new Users();
18             u2.setUsername("Mary");
19             u2.setPassword("456789");
20             // 设置角色
21             Role r1 = new Role();
22             r1.setRoleName("HR");
23             r1.setRoleMemo("HR");
24 
25             Role r2 = new Role();
26             r2.setRoleName("Teacher");
27             r2.setRoleMemo("Teacher");
28 
29             Role r3 = new Role();
30             r3.setRoleName("CEO");
31             r3.setRoleMemo("CEO");
32             // 用户1添加角色r1,r2
33             u1.getRoles().add(r1);
34             u1.getRoles().add(r2);
35             // 用户2添加角色r13,r2
36             u2.getRoles().add(r3);
37 
38             session.save(u2);
39             session.save(u1);
40 
41             ts.commit();
42         } catch (Exception e) {
43             ts.rollback();
44             e.printStackTrace();
45         } finally {
46             session.close();
47         }
48     }
View Code

  对于多对多的级联保存操作,也需要对实体类的配置文件的set标签的cascade属性进行配置,如下:

1 <set name="users" table="t_roleuser" cascade="save-update">

运行截图:

 (2)、级联删除操作

代码片段:

 1 // 级联删除
 2     @Test
 3     public void fun2() {
 4         // 多对多级练操作
 5         Transaction ts = null;
 6         Session session = null;
 7         SessionFactory factory = null;
 8         try {
 9             factory = Tools.getSessionFactory();
10             session = factory.openSession();
11             ts = session.beginTransaction();
12 
13             // 第一步:查找用戶
14             Users user = session.get(Users.class,
15                     "4028d4015e6f140b015e6f1411490000");
16             session.delete(user);
17 
18             ts.commit();
19         } catch (Exception e) {
20             ts.rollback();
21             e.printStackTrace();
22         } finally {
23             session.close();
24         }
25     }
View Code

同样的级联删除也需要配置实体类的HIbernate配置文件,如下:

1 <set name="users" table="t_roleuser" cascade="save-update,delete">

运行截图:

 (3)、维护第三种表

  >>>.维护第三张表---为用户添加新的角色(给Mary添加Teacher职责)

代码片段:

 1 // 维护第三张表---为用户添加新的角色
 2     @Test
 3     public void fun3() {
 4         // 多对多级练操作
 5         Transaction ts = null;
 6         Session session = null;
 7         SessionFactory factory = null;
 8         try {
 9             factory = Tools.getSessionFactory();
10             session = factory.openSession();
11             ts = session.beginTransaction();
12 
13             // 第一步:查找用戶,
14             Users user = session.get(Users.class,
15                     "4028d4015e6f1fe3015e6f1fe99a0000");
16             // 查找角色
17             Role role = session.get(Role.class,
18                     "4028d4015e6f1fe3015e6f1fe9da0004");
19             // 添加角色到用户
20             user.getRoles().add(role);
21 
22             ts.commit();
23         } catch (Exception e) {
24             ts.rollback();
25             e.printStackTrace();
26         } finally {
27             session.close();
28         }
29     }
View Code

运行截图:

  >>>.维护第三张表---删除为用户的角色(删除Mary添加Teacher职责)

代码片段:

 1 // 维护第三张表---一处用户的某个角色
 2     @Test
 3     public void fun4() {
 4         // 多对多级练操作
 5         Transaction ts = null;
 6         Session session = null;
 7         SessionFactory factory = null;
 8         try {
 9             factory = Tools.getSessionFactory();
10             session = factory.openSession();
11             ts = session.beginTransaction();
12 
13             // 第一步:查找用戶,
14             Users user = session.get(Users.class,
15                     "4028d4015e6f1fe3015e6f1fe99a0000");
16             // 查找角色
17             Role role = session.get(Role.class,
18                     "4028d4015e6f1fe3015e6f1fe9da0004");
19             // 添加角色到用户
20             user.getRoles().remove(role);
21 
22             ts.commit();
23         } catch (Exception e) {
24             ts.rollback();
25             e.printStackTrace();
26         } finally {
27             session.close();
28         }
29     }
View Code

运行截图:

原文地址:https://www.cnblogs.com/geore/p/7502328.html