4.Hibernate关系映射

来源:互联网 发布:linux 新建用户组 编辑:程序博客网 时间:2024/06/08 03:06

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-9e22cd9fb5ab2017-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;

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

0 0