ManyToMany(多对多数据映射的insert、update及delete)

对hibernete只知道皮毛的偶,一直觉得在多表联合查询时配置hibernate数据表的映射文件很是麻烦的问题,最近难得有时间学习java annotation所以顺便更进一步的去学习一下hibernate,虽然我现在写这些东西在有好多人觉得是否开始有些过时,但是作为小鸟的我希望能将我的学习到的知识和经验与更多像我一样的小鸟们分享一下。那就废话少说了,这里我通过一个人员与角色的多对多实例,来与大家分享一下我的理解。

1.首先是一个User.java和Role.java的POJO类,代码如下:

(1) User.java

  1. package com.candy.hibernate.bean;  
  2. import java.io.Serializable;  
  3. import java.util.LinkedHashSet;  
  4. import java.util.Set;  
  5. import javax.persistence.Column;  
  6. import javax.persistence.Entity;  
  7. import javax.persistence.FetchType;  
  8. import javax.persistence.Id;  
  9. import javax.persistence.ManyToMany;  
  10. import javax.persistence.Table;  
  11. @Entity  
  12. @Table(name="user")  
  13. public class User implements Serializable {  
  14.     /** 
  15.      *  
  16.      */  
  17.     private static final long serialVersionUID = 1L;  
  18.     @Id  
  19.     @Column(name="user_id", length=7, nullable=false)  
  20.     private String id;  
  21.       
  22.     @Column(name="user_name", length=20,nullable=false)  
  23.     private String name;  
  24.       
  25.     @Column(name="user_pwd",length=20,nullable=false)  
  26.     private String password;  
  27.       
  28.     @Column(name="user_addr",length=50)  
  29.     private String address;  
  30.       
  31.     @Column(name="user_mail" ,length=20)  
  32.     private String email;  
  33.     @Column(name="head_img" ,length=50)  
  34.     private String headImage;  
  35.       
  36.     @ManyToMany(mappedBy="users", fetch=FetchType.LAZY)  
  37.     private Set<Role> roles = new LinkedHashSet<Role>();  
  38.       
  39.     public String getId() {  
  40.         return id;  
  41.     }  
  42.     public void setId(String id) {  
  43.         this.id = id;  
  44.     }  
  45.     public String getName() {  
  46.         return name;  
  47.     }  
  48.     public void setName(String name) {  
  49.         this.name = name;  
  50.     }  
  51.     public String getPassword() {  
  52.         return password;  
  53.     }  
  54.     public void setPassword(String password) {  
  55.         this.password = password;  
  56.     }  
  57.     public String getAddress() {  
  58.         return address;  
  59.     }  
  60.     public void setAddress(String address) {  
  61.         this.address = address;  
  62.     }  
  63.     public String getEmail() {  
  64.         return email;  
  65.     }  
  66.     public void setEmail(String email) {  
  67.         this.email = email;  
  68.     }  
  69.     public String getHeadImage() {  
  70.         return headImage;  
  71.     }  
  72.     public void setHeadImage(String headImage) {  
  73.         this.headImage = headImage;  
  74.     }  
  75.       
  76.       
  77.     public Set<Role> getRoles() {  
  78.         return roles;  
  79.     }  
  80.     public void setRoles(Set<Role> roles) {  
  81.         this.roles = roles;  
  82.     }  
  83.     @Override  
  84.     public String toString() {  
  85.         StringBuilder stb = new StringBuilder();  
  86.         stb.append("User[");  
  87.         stb.append("id:" + getId());  
  88.         stb.append(";name:" + getName());  
  89.         stb.append(";password:" + getPassword());  
  90.         stb.append(";email:" + getEmail());  
  91.         stb.append(";address:" + getAddress());  
  92.         stb.append("headImage:" + getHeadImage());  
  93.         stb.append("]");  
  94.         return stb.toString();  
  95.     }  
  96. }  

Role.java

  1. package com.candy.hibernate.bean;  
  2. import java.io.Serializable;  
  3. import java.util.LinkedHashSet;  
  4. import java.util.Set;  
  5. import javax.persistence.CascadeType;  
  6. import javax.persistence.Column;  
  7. import javax.persistence.Entity;  
  8. import javax.persistence.FetchType;  
  9. import javax.persistence.Id;  
  10. import javax.persistence.JoinColumn;  
  11. import javax.persistence.JoinTable;  
  12. import javax.persistence.ManyToMany;  
  13. import javax.persistence.Table;  
  14. @Entity  
  15. @Table(name="role")  
  16. public class Role implements Serializable {  
  17.     /** 
  18.      *  
  19.      */  
  20.     private static final long serialVersionUID = 1597271124780386657L;  
  21.     @Id  
  22.     @Column(name="role_id",length=7,nullable=false)  
  23.     private int id;  
  24.       
  25.     @Column(name="role_name",length=10, nullable=false)  
  26.     private String role;  
  27.       
  28.     @ManyToMany(cascade = CascadeType.PERSIST, fetch = FetchType.LAZY)  
  29.     @JoinTable(name="user_role",joinColumns={@JoinColumn(name="role_id")},inverseJoinColumns={@JoinColumn(name="user_id")})  
  30.     private Set<User> users = new LinkedHashSet<User>();  
  31.       
  32.     @ManyToMany(mappedBy="roles")  
  33.     private Set<Priority> prioritys = new LinkedHashSet<Priority>();  
  34.       
  35.     public int getId() {  
  36.         return id;  
  37.     }  
  38.     public void setId(int id) {  
  39.         this.id = id;  
  40.     }  
  41.     public String getRole() {  
  42.         return role;  
  43.     }  
  44.     public void setRole(String role) {  
  45.         this.role = role;  
  46.     }  
  47.       
  48.       
  49.     public Set<User> getUsers() {  
  50.         return users;  
  51.     }  
  52.     public void setUsers(Set<User> users) {  
  53.         this.users = users;  
  54.     }  
  55.     @Override  
  56.     public String toString() {  
  57.         StringBuilder stb = new StringBuilder();  
  58.         stb.append("Role[");  
  59.         stb.append("id:" + getId());  
  60.         stb.append(";role:" + getRole());  
  61.         stb.append("]");  
  62.         return stb.toString();  
  63.     }  
  64. }   

通过上面的java annotation,可以映射到三个表,分别为:

(1) @Table(name="user") :得到表名为user的数据表。

(2) @Table(name="role")  :得到表名为role的数据表。

(3) @JoinTable(name="user_role",...)得到表名为user_role的多对多关系维护数据表。

同时,通过User.java的@ManyToMany(mappedBy="users",...)我们知道,主控方在Role.java,也就是说,当我们的Role发生delete这样的操作时,hibernate会自动的帮我们把user_role表中与该Role有关的所有数据给delete掉。总之,当对主控方进行操作时,对于中间表的维护要相对容易,所以在这我就不多说了。而对于被控方的操作,在对中间表的维护时,很多时候我们也需要维护中间关系表,下面就是我在对被控方操作时维护中间表的实例:

A. 添加一个拥有指定角色的用户。对于给一个用户添加角色,我们大脑首先会想到的是将该用户添加到指定角色的群组中,没错,就是这个思路,代码如下:

  1. public void addUser(User user) {  
  2.         try {  
  3.             for (Role role : user.getRoles()) {  
  4.                 role.getUsers().add(user);  
  5.             }  
  6.             this.getHibernateTemplate().save(user);  
  7.         } catch (Exception e) {  
  8.             e.printStackTrace();  
  9.             logger.error("error occured at : ", e);  
  10.         }  
  11.     }  

B.更新用户。

对于更新一个用户,对中间表的维护的思路跟上面的添加差不多,我的思路是先去掉该用户未被更新前的所有角色,再为该用户添加现有的角色,所以代码大致如下(下面的代码总感觉不太好,谁有好的写法,希望留言。我在这就先抛砖引玉了):

  1. public void updateUser(User user) {  
  2.         try {  
  3.             // update user's role   
  4.             User oldUser = (User) this.getHibernateTemplate().get(User.class,  
  5.                     user.getId());  
  6.             if (oldUser != null) {  
  7.                 for (Role role : oldUser.getRoles()) {  
  8.                     role.getUsers().remove(oldUser);  
  9.                 }  
  10.                 for (Role role : user.getRoles()) {  
  11.                     role.getUsers().add(oldUser);  
  12.                 }  
  13.                 this.getHibernateTemplate().save(oldUser);  
  14.                 // update inverse table, the middle table has not been updated   
  15.                 this.getHibernateTemplate().merge(user);  
  16.             }  
  17.         } catch (Exception e) {  
  18.             e.printStackTrace();  
  19.             logger.error("error occured at : ", e);  
  20.         }  
  21.     }   

C.删除操作的思路也差不多,这里我就不多说了,代码如下:

  1. public void deleteUser(String primaryKey) {  
  2.         try {  
  3.             User user = (User) this.getHibernateTemplate().get(User.class,  
  4.                     primaryKey);  
  5.             if (user != null) {  
  6.                 // remove the relationship   
  7.                 for (Role role : user.getRoles()) {  
  8.                     role.getUsers().remove(user);  
  9.                 }  
  10.                 this.getHibernateTemplate().delete(user);  
  11.             }  
  12.         } catch (Exception e) {  
  13.             e.printStackTrace();  
  14.             logger.error("error occured at : ", e);  
  15.         }  
  16.     }  

下面是hibernate生成的表对应的sql:


CREATE TABLE `user` (
  `user_id` varchar(7) NOT NULL,
  `user_addr` varchar(50) default NULL,
  `user_mail` varchar(20) default NULL,
  `head_img` varchar(50) default NULL,
  `user_name` varchar(20) NOT NULL,
  `user_pwd` varchar(20) NOT NULL,
  PRIMARY KEY  (`user_id`)
) ENG

CREATE TABLE `role` (
  `role_id` int(11) NOT NULL,
  `role_name` varchar(10) NOT NULL,
  PRIMARY KEY  (`role_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `user_role` (
  `role_id` int(11) NOT NULL,
  `user_id` varchar(7) NOT NULL,
  PRIMARY KEY  (`role_id`,`user_id`),
  KEY `FK143BF46AD86B0194` (`role_id`),
  KEY `FK143BF46A7D95C574` (`user_id`),
  CONSTRAINT `FK143BF46A7D95C574` FOREIGN KEY (`user_id`) REFERENCES `user` (`user_id`),
  CONSTRAINT `FK143BF46AD86B0194` FOREIGN KEY (`role_id`) REFERENCES `role` (`role_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

好了,偶就能分享这么多了,希望对大家有用,有理解得不对的地方,欢迎大家批评指正。

Link:http://blog.csdn.net/shadow55/article/details/4428059 

猜你喜欢

转载自oywl2008.iteye.com/blog/1312020