hibernate关系映射小结

首先,建立两个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;
    }
原文地址:https://www.cnblogs.com/honghuzidelaoren/p/3596777.html