首先,建立两个PO类:User、UserGroup,以及相应的hibernate配置
package com.yyl.po; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import org.hibernate.annotations.GenericGenerator; @Entity public class User { private String id; private String name; private int age; @Id @GenericGenerator(name = "generator", strategy = "uuid") @GeneratedValue(generator = "generator") @Column(nullable = false, unique = true) public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
package com.yyl.po; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Table; import org.hibernate.annotations.GenericGenerator; @Entity @Table(name = "user_group") public class UserGroup { private String id; private String name; @Id @GenericGenerator(name = "generator", strategy = "uuid") @GeneratedValue(generator = "generator") @Column(unique = true, nullable = false) public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
<session-factory> <property name="dialect">org.hibernate.dialect.MySQLDialect</property> <property name="connection.url">jdbc:mysql://localhost:3306/hibernate</property> <property name="connection.username">root</property> <property name="connection.password">123</property> <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="show_sql">true</property> <property name="format_sql">false</property> <!-- 自动建立表或更新表结构 --> <property name="hibernate.hbm2ddl.auto">update</property> <mapping class="com.yyl.po.User"/> <mapping class="com.yyl.po.UserGroup"/> </session-factory>
1、一对一单向、双向关联与下面类似,使用@OneToOne注解
2、多对一单向关联:多个User对应一个UserGroup
在多方User添加一个UserGroup变量以及相应get方法,注解如下
private UserGroup userGroup; //级联删除、更新 @ManyToOne(cascade = CascadeType.ALL) //指定User表中的外键字段名 @JoinColumn(name = "group_id") public UserGroup getUserGroup() { return userGroup; } public void setUserGroup(UserGroup userGroup) { this.userGroup = userGroup; }
3、一对多单向关联:一个UserGroup对应多个User
在一方UserGroup添加一个User集合以及相应get方法,注解如下
private Set<User> users = new HashSet<User>(0); //级联删除、更新 @OneToMany(cascade = CascadeType.ALL) //指定User表中的外键字段名 @JoinColumn(name = "group_id") public Set<User> getUsers() { return users; } public void setUsers(Set<User> users) { this.users = users; }
4、一对多(多对一)双向关联
//多方(User) //级联删除、更新 @ManyToOne(cascade = CascadeType.ALL) //指定User表中的外键字段名 @JoinColumn(name = "group_id") public UserGroup getUserGroup() { return userGroup; } //一方(UserGroup) //级联删除、更新,mappedBy指定User中的userGroup变量 @OneToMany(cascade = CascadeType.ALL, mappedBy = "userGroup") public Set<User> getUsers() { return users; }
注意:以上的2、3、4三种映射均只在多方(User)建立外键(group_id),而一方(UserGroup)数据库中并没有显式外键。
另外,有一个问题,在一对多多对一双向关联中:
若从多的一方保存,即调用User的user.setUserGroup(userGroup)保存一个transient状态的userGroup后,调用session.save(user)即可成功级联保存两表信息
若从一的一方保存,即调用UserGroup的userGroup.getUsers().add(user)保存一个transient的user后,session.save(userGroup)级联保存后,user中的group_id字段为空?不解?
5、多对多单向关联:一个User可以在多个UserGroup中,一个UserGroup可以有多个User
//在User类中 private Set<UserGroup> userGroups = new HashSet<UserGroup>(); //级联删除、更新 @ManyToMany(cascade = CascadeType.ALL) //指定User表中的外键字段名 @JoinTable( name = "user_usergroup", //指定中间表名称 joinColumns = {@JoinColumn(name = "userid")}, //本类主键在中间表中对应的字段名 inverseJoinColumns = {@JoinColumn(name = "groupid")} //对方类主键在中间表中对应的字段名 ) public Set<UserGroup> getUserGroups() { return userGroups; }
6、多对多双向关联:在5的基础上,在UserGroup中加入注解
//在UserGroup类中 private Set<User> users = new HashSet<User>(0); //级联删除、更新,mappedBy指定User中的userGroups变量 @ManyToMany(cascade = CascadeType.ALL, mappedBy = "userGroups") public Set<User> getUsers() { return users; } public void setUsers(Set<User> users) { this.users = users; }