4.Hibernate关系映射

Hibernate实体关联关系映射

双向一对一关联
@Entity(name = "address")
@Table(name = "t_address")
public class Address implements Serializable {

    private static final long serialVersionUID = 2390103918524410815L;

    @Id
    @Column(length = 36)
    @GeneratedValue(generator = "addressID")
    @GenericGenerator(name = "addressID", strategy = "guid")
    private String addressID;

    private String addressName;

    private String content;

    @OneToOne(fetch = FetchType.LAZY, mappedBy = "address", cascade = CascadeType.ALL)
    private Subscriber subscriber;
}
@Entity(name = "user")
@Table(name = "t_user")
public class Subscriber implements Serializable {

    private static final long serialVersionUID = 9181139977020744196L;

    @Id
    @Column(length = 36)
    @GeneratedValue(generator = "user_id")
    @GenericGenerator(name = "user_id", strategy = "guid")
    private String userID;

    private String username;

    private LocalDate lastUpdate;

    @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinColumn(name = "addressID")
    private Address address;
}
2017-01-07 15:12:53 DEBUG create table t_address (addressID varchar(36) not null, addressName varchar(255), content varchar(255), primary key (addressID))
2017-01-07 15:12:53 DEBUG create table t_user (userID varchar(36) not null, lastUpdate date, username varchar(255), addressID varchar(36), primary key (userID))
2017-01-07 15:12:53 DEBUG alter table t_user add constraint FKs3m591aubwmq2gs9pa690nu89 foreign key (addressID) references t_address (addressID)

上面两个实体类分别为用户表和用户地址表之间的双向一对一关联。
在用户表一侧设置外键,关联地址表主键,代码中需要在Address类中的@OneToOne注解中添加mappedBy表示由用户表一侧维护关联关系(即在用户表一侧添加外键关联)。

单向一对一关联

在双向一对一关联的基础上,只要在需要添加外键表的实体类上增加一对一关联即可,Subscriber 类不做变化,修改Address类:

public class Address implements Serializable {

    private static final long serialVersionUID = 2390103918524410815L;

    @Id
    @Column(length = 36)
    @GeneratedValue(generator = "addressID")
    @GenericGenerator(name = "addressID", strategy = "guid")
    private String addressID;

    private String addressName;

    private String content;

}
双向一对多关联(双向多对一关联)
@Entity(name = "user")
@Table(name = "t_user")
public class Subscriber implements Serializable {

    private static final long serialVersionUID = 9181139977020744196L;

    @Id
    @Column(length = 36)
    @GeneratedValue(generator = "user_id")
    @GenericGenerator(name = "user_id", strategy = "guid")
    private String userID;

    private String username;

    private LocalDate lastUpdate;

    @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinColumn(name = "roleID")
    private Role role;
}
@Entity(name = "role")
@Table(name = "t_role")
public class Role implements Serializable {

    private static final long serialVersionUID = -7982000043216756088L;

    @Id
    @Column(length = 36)
    @GeneratedValue(generator = "roleID")
    @GenericGenerator(name = "roleID", strategy = "guid")
    private String roleID;

    private String roleName;

    private LocalDateTime lastUpdate;

    @OneToMany(fetch = FetchType.LAZY, mappedBy = "role", cascade = CascadeType.ALL)
    private Set<Subscriber> subscribers;
2017-01-07 15:22:31 DEBUG create table t_role (roleID varchar(36) not null, lastUpdate datetime, roleName varchar(255), primary key (roleID))
2017-01-07 15:22:31 DEBUG create table t_user (userID varchar(36) not null, lastUpdate date, username varchar(255), roleID varchar(36), primary key (userID))
2017-01-07 15:22:31 DEBUG alter table t_user add constraint FKc28rhpmp7an5dx89avr1y1m2q foreign key (roleID) references t_role (roleID)
多对一单项关联

在多对一双向关联的基础上修改Role类,去除subscribers:

public class Role implements Serializable {

    private static final long serialVersionUID = -7982000043216756088L;

    @Id
    @Column(length = 36)
    @GeneratedValue(generator = "roleID")
    @GenericGenerator(name = "roleID", strategy = "guid")
    private String roleID;

    private String roleName;

    private LocalDateTime lastUpdate;
}
一对多单项关联
public class Role implements Serializable {

    private static final long serialVersionUID = -7982000043216756088L;

    @Id
    @Column(length = 36)
    @GeneratedValue(generator = "roleID")
    @GenericGenerator(name = "roleID", strategy = "guid")
    private String roleID;

    private String roleName;

    private LocalDateTime lastUpdate;

    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    private Set<Subscriber> subscribers;
}
public class Subscriber implements Serializable {

    private static final long serialVersionUID = 9181139977020744196L;

    @Id
    @Column(length = 36)
    @GeneratedValue(generator = "user_id")
    @GenericGenerator(name = "user_id", strategy = "guid")
    private String userID;

    private String username;

    private LocalDate lastUpdate;
}
2017-01-07 15:31:29 DEBUG create table t_role (roleID varchar(36) not null, lastUpdate datetime, roleName varchar(255), primary key (roleID))
2017-01-07 15:31:29 DEBUG create table t_role_t_user (role_roleID varchar(36) not null, subscribers_userID varchar(36) not null, primary key (role_roleID, subscribers_userID))
2017-01-07 15:31:29 DEBUG create table t_user (userID varchar(36) not null, lastUpdate date, username varchar(255), addressID varchar(36), primary key (userID))
2017-01-07 15:31:29 DEBUG alter table t_role_t_user add constraint UK_3trydf2lqhdnq52vixb2ahoe0 unique (subscribers_userID)
2017-01-07 15:31:29 DEBUG alter table t_role_t_user add constraint FKrc5t9x0w3bhithg26cvbio0ar foreign key (subscribers_userID) references t_user (userID)
2017-01-07 15:31:29 DEBUG alter table t_role_t_user add constraint FKpxyafwfxy75buuokrq08fl4ob foreign key (role_roleID) references t_role (roleID)

最后会生成3张表,这里显而易见,当做多对多来处理

双向多对多关联
public class Subscriber implements Serializable {

    private static final long serialVersionUID = 9181139977020744196L;

    @Id
    @Column(length = 36)
    @GeneratedValue(generator = "user_id")
    @GenericGenerator(name = "user_id", strategy = "guid")
    private String userID;

    private String username;

    private LocalDate lastUpdate;

    @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinTable(name = "t_user_group", joinColumns = {@JoinColumn(name = "userID")},
            inverseJoinColumns = {@JoinColumn(name = "groupID")})
    private Set<Group> groups;
}
public class Group implements Serializable {

    private static final long serialVersionUID = -1086629855135859375L;

    @Id
    @Column(length = 36)
    @GeneratedValue(generator = "groupID")
    @GenericGenerator(name = "groupID", strategy = "guid")
    private String groupID;

    private String groupName;

    @ManyToMany(mappedBy = "groups")
    private Set<Subscriber> subscribers;
}
2017-01-07 15:47:57 DEBUG create table t_group (groupID varchar(36) not null, groupName varchar(255), primary key (groupID))
2017-01-07 15:47:58 DEBUG create table t_user (userID varchar(36) not null, lastUpdate date, username varchar(255), addressID varchar(36), roleID varchar(36), primary key (userID))
2017-01-07 15:47:58 DEBUG create table t_user_group (userID varchar(36) not null, groupID varchar(36) not null, primary key (userID, groupID))
2017-01-07 15:47:58 DEBUG alter table t_user_group add constraint FKfgcvmarajos52c6isr5jbmtcx foreign key (groupID) references t_group (groupID)
2017-01-07 15:47:58 DEBUG alter table t_user_group add constraint FKbovsdkvtssoue3hacl3ss4pb foreign key (userID) references t_user (userID)
单项多对多关联

在多项多对多关联上的某一方去除@ManyToMany即可。例如在Group一方:

public class Group implements Serializable {

    private static final long serialVersionUID = -1086629855135859375L;

    @Id
    @Column(length = 36)
    @GeneratedValue(generator = "groupID")
    @GenericGenerator(name = "groupID", strategy = "guid")
    private String groupID;

    private String groupName;
}
单向一对一主键关联(共享主键)
public class Address implements Serializable {

    private static final long serialVersionUID = 2390103918524410815L;

    @Id
    @Column(length = 36)
    @GeneratedValue(generator = "addressID")
    @GenericGenerator(name = "addressID", strategy = "foreign", parameters = @Parameter(name = "property", value = "subscriber"))
    private String addressID;

    private String addressName;

    private String content;

    @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @PrimaryKeyJoinColumn(name = "addressID", referencedColumnName = "userID")
    private Subscriber subscriber;
}
public class Subscriber implements Serializable {

    private static final long serialVersionUID = 9181139977020744196L;

    @Id
    @Column(length = 36)
    @GeneratedValue(generator = "user_id")
    @GenericGenerator(name = "user_id", strategy = "guid")
    private String userID;

    private String username;

    private LocalDate lastUpdate;
}
Session session = this.sessionFactory.getCurrentSession();
session.getTransaction().begin();

Subscriber subscriber = new Subscriber("username");
Address address = new Address("addressName", "content");
address.setSubscriber(subscriber);
session.persist(address);

session.getTransaction().commit();
session.close();
2017-01-08 16:26:25 DEBUG create table t_address (addressID varchar(36) not null, addressName varchar(255), content varchar(255), primary key (addressID))
2017-01-08 16:26:25 DEBUG create table t_user (userID varchar(36) not null, lastUpdate date, username varchar(255), primary key (userID))
2017-01-08 16:26:25 DEBUG select uuid()
2017-01-08 16:26:25 WARN  HHH000113: GUID identifier generated: 53c6e9ec-26cc-1035-ad8a-9e22cd9fb5ab
2017-01-08 16:26:25 DEBUG insert into t_user (lastUpdate, username, userID) values (?, ?, ?)
2017-01-08 16:26:25 TRACE binding parameter [1] as [DATE] - [2017-01-08]
2017-01-08 16:26:25 TRACE binding parameter [2] as [VARCHAR] - [username]
2017-01-08 16:26:25 TRACE binding parameter [3] as [VARCHAR] - [53c6e9ec-26cc-1035-ad8a-9e22cd9fb5ab]
2017-01-08 16:26:25 DEBUG insert into t_address (addressName, content, addressID) values (?, ?, ?)
2017-01-08 16:26:25 TRACE binding parameter [1] as [VARCHAR] - [addressName]
2017-01-08 16:26:25 TRACE binding parameter [2] as [VARCHAR] - [content]
2017-01-08 16:26:25 TRACE binding parameter [3] as [VARCHAR] - [53c6e9ec-26cc-1035-ad8a-9e22cd9fb5ab]

运行测试代码后,发出的建表语句中没有添加外键关联。在插入数据时,只会生成一个主键,Subscriber和Address两个实体共用一个主键

双向一对一主键关联(共享主键)

在Subscriber中添加如下代码即可

@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "subscriber")
@PrimaryKeyJoinColumn(name = "userID", referencedColumnName = "addressID")
private Address address;

运行测试代码效果和单项一对一主键关联一致

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值