<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <!-- Database connection settings --> <property name="connection.driver_class">com.ibm.db2.jcc.DB2Driver</property> <property name="connection.url">jdbc:db2://127.0.0.1:60003/HIBER</property> <property name="connection.username">*****</property> <property name="connection.password">******</property> <!-- JDBC connection pool (use the built-in) --> <property name="connection.pool_size">3</property> <!-- SQL dialect --> <property name="dialect">org.hibernate.dialect.DB2Dialect</property> <!-- Enable Hibernate's automatic session context management --> <property name="current_session_context_class">thread</property> <!-- Disable the second-level cache --> <property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property> <!-- Echo all executed SQL to stdout --> <property name="show_sql">true</property> <!-- Drop and re-create the database schema on startup --> <property name="hbm2ddl.auto">update</property> <!-- <mapping resource="org/hibernate/tutorial/domain/Event.hbm.xml" /> --> <mapping class="azure.hibernate4.associations.unidi.many2one.Person" /> <mapping class="azure.hibernate4.associations.unidi.many2one.Address" /> </session-factory> </hibernate-configuration>
public SessionFactory sessionFactory; public Session getCurrentSession() { String filePath = this.getClass().getPackage().getName() .replaceAll("\\.", "/"); if (sessionFactory == null) { Configuration cfg = new Configuration().configure(Thread .currentThread().getContextClassLoader() .getResource(filePath + "/hibernate.cfg.xml")); ServiceRegistry serviceRegistry = new ServiceRegistryBuilder() .applySettings(cfg.getProperties()).buildServiceRegistry(); sessionFactory = cfg.buildSessionFactory(serviceRegistry); } return sessionFactory.getCurrentSession(); }
下面我们一一测试每一种关联映射。
//Person.java package azure.hibernate4.associations.unidimany2one; import java.io.Serializable; import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; @Entity @Table(name = "PERSON") public class Person implements Serializable { private static final long serialVersionUID = -1097173835933422124L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int personId; @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) @JoinColumn(name = "ADDRESS_ID") private Address address; public int getPersonId() { return personId; } public void setPersonId(int personId) { this.personId = personId; } public Address getAddress() { return address; } public void setAddress(Address address) { this.address = address; } }
//Address.java package azure.hibernate4.associations.unidimany2one; import java.io.Serializable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name = "ADDRESS") public class Address implements Serializable { private static final long serialVersionUID = 3794514024483047170L; @Id @Column(name = "ADDRESS_ID") private int addressId; @Column(name = "ADDRESS_NAME") private String name; public int getAddressId() { return addressId; } public void setAddressId(int addressId) { this.addressId = addressId; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
由Hibernate生成的表物理视图如下, 在ManyToOne关系中是在主表中生成一个外键.
映射部分代码Person.java
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int personId; @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) @JoinColumn(name = "ADDRESS_ID") private Address address;
Address.java
@Id @Column(name = "ADDRESS_ID") private int addressId; @Column(name = "ADDRESS_NAME") private String name;
生成的建表SQL语句如下:
Hibernate: create table ADDRESS (ADDRESS_ID integer not null, ADDRESS_NAME varchar(255), primary key (ADDRESS_ID)) Hibernate: create table PERSON (personId integer generated by default as identity, ADDRESS_ID integer, primary key (personId)) Hibernate: alter table PERSON add constraint FK8C768F5591A4FE5E foreign key (ADDRESS_ID) references ADDRESS
生成的表的物理视图如下:
关联部分代码Person.java
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int personId; @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY) private Set<Address> address;
Address.java
@Id @Column(name = "ADDRESS_ID") private int addressId; @Column(name = "ADDRESS_NAME") private String name;
生成的建表SQL语句如下:
Hibernate: create table ADDRESS (ADDRESS_ID integer not null, ADDRESS_NAME varchar(255), primary key (ADDRESS_ID)) Hibernate: create table PERSON (personId integer generated by default as identity, primary key (personId)) Hibernate: create table PERSON_ADDRESS (PERSON_personId integer not null, address_ADDRESS_ID integer not null, primary key (PERSON_personId, address_ADDRESS_ID)) Hibernate: alter table PERSON_ADDRESS add constraint UK_9E2338EA65485A71 unique (address_ADDRESS_ID) Hibernate: alter table PERSON_ADDRESS add constraint FK9E2338EAD006FE6A foreign key (address_ADDRESS_ID) references ADDRESS Hibernate: alter table PERSON_ADDRESS add constraint FK9E2338EA495AB8A foreign key (PERSON_personId) references PERSON
物理表视图如下, 看到Hibernate使用连接表来实现单向OneToMany, 根据Hibernate文档的说明:
Person.java
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int personId; @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY) private Set<Address> address;Address.java
@Id @Column(name = "ADDRESS_ID") private int addressId; @Column(name = "ADDRESS_NAME") private String name;
建表SQL
Hibernate: create table ADDRESS (ADDRESS_ID integer not null, ADDRESS_NAME varchar(255), primary key (ADDRESS_ID)) Hibernate: create table PERSON (personId integer generated by default as identity, primary key (personId)) Hibernate: create table PERSON_ADDRESS (PERSON_personId integer not null, address_ADDRESS_ID integer not null, primary key (PERSON_personId, address_ADDRESS_ID)) Hibernate: alter table PERSON_ADDRESS add constraint FK9E2338EADD54AFC1 foreign key (address_ADDRESS_ID) references ADDRESS Hibernate: alter table PERSON_ADDRESS add constraint FK9E2338EABAB0F353 foreign key (PERSON_personId) references PERSON物理表
Person.java
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int personId; @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY) private Set<Address> address;Address.java
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int personId; @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY) private Set<Address> address;建表SQL
Hibernate: create table ADDRESS (ADDRESS_ID integer not null, ADDRESS_NAME varchar(255), primary key (ADDRESS_ID)) Hibernate: create table ADDRESS_PERSON (ADDRESS_ADDRESS_ID integer not null, person_personId integer not null, primary key (ADDRESS_ADDRESS_ID, person_personId)) Hibernate: create table PERSON (personId integer generated by default as identity, primary key (personId)) Hibernate: create table PERSON_ADDRESS (PERSON_personId integer not null, address_ADDRESS_ID integer not null, primary key (PERSON_personId, address_ADDRESS_ID)) Hibernate: alter table ADDRESS_PERSON add constraint FK3672AE20593E71E foreign key (person_personId) references PERSON Hibernate: alter table ADDRESS_PERSON add constraint FK3672AE20EED03556 foreign key (ADDRESS_ADDRESS_ID) references ADDRESS Hibernate: alter table PERSON_ADDRESS add constraint FK9E2338EAEED03556 foreign key (address_ADDRESS_ID) references ADDRESS Hibernate: alter table PERSON_ADDRESS add constraint FK9E2338EA593E71E foreign key (PERSON_personId) references PERSON物理表视图如下
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int personId; @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY) @JoinTable(name = "PERSON_ADDRESS", joinColumns = { @JoinColumn(name = "ADDRESS_ID") }, inverseJoinColumns = { @JoinColumn(name = "PERSON_ID") }) private Set<Address> address;Address.java
@Id @Column(name = "ADDRESS_ID") private int addressId; @Column(name = "ADDRESS_NAME") private String name; @ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) @JoinTable(name = "PERSON_ADDRESS", joinColumns = { @JoinColumn(name = "PERSON_ID") }, inverseJoinColumns = { @JoinColumn(name = "ADDRESS_ID") }) private Set<Person> person;这时的建表SQL语句如下:
Hibernate: create table ADDRESS (ADDRESS_ID integer not null, ADDRESS_NAME varchar(255), primary key (ADDRESS_ID)) Hibernate: create table PERSON (personId integer generated by default as identity, primary key (personId)) Hibernate: create table PERSON_ADDRESS (PERSON_ID integer not null, ADDRESS_ID integer not null, primary key (ADDRESS_ID, PERSON_ID)) Hibernate: alter table PERSON_ADDRESS add constraint FK9E2338EA97561B8A foreign key (ADDRESS_ID) references PERSON Hibernate: alter table PERSON_ADDRESS add constraint FK9E2338EABC62752A foreign key (PERSON_ID) references ADDRESS
双向ManyToOne关联, 在1的一端需要有到N的一段的集合字段, 在N的一端需要到1的一端的字段. 在双向一对多关联中建议不用连接表, 而直接在多的一端加外键.
Person.java
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int personId; @ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) @JoinColumn(name = "ADDRESS_ID") private Address address;
Address.java
@Id @Column(name = "ADDRESS_ID") private int addressId; @Column(name = "ADDRESS_NAME") private String name; @OneToMany(mappedBy = "address", cascade = CascadeType.ALL, fetch = FetchType.LAZY) private Set<Person> persons;
建表SQL如下:
Hibernate: create table ADDRESS (ADDRESS_ID integer not null, ADDRESS_NAME varchar(255), primary key (ADDRESS_ID)) 2013-5-22 16:42:45 org.hibernate.tool.hbm2ddl.SchemaExport perform Hibernate: create table PERSON (personId integer generated by default as identity, ADDRESS_ID integer, primary key (personId)) Hibernate: alter table PERSON add constraint FK8C768F5592A339F2 foreign key (ADDRESS_ID) references ADDRESS
通过双向OneToOne关联可以从任意一端导航到另一端, 在两个实体类里面需要同时定义到另一端的属性. 物理表结构方面, 在任意一端建立一个外键.
Person.java
@Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int personId; @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) private Address address;
Address.java
@Id @Column(name = "ADDRESS_ID") private int addressId; @Column(name = "ADDRESS_NAME") private String name; @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER) private Person person;
建表语句如下:
Hibernate: create table ADDRESS (ADDRESS_ID integer not null, ADDRESS_NAME varchar(255), person_personId integer, primary key (ADDRESS_ID)) Hibernate: create table PERSON (personId integer generated by default as identity, address_ADDRESS_ID integer, primary key (personId)) Hibernate: alter table ADDRESS add constraint FKE66327D4A65E7D16 foreign key (person_personId) references PERSON Hibernate: alter table PERSON add constraint FK8C768F5567585E5E foreign key (address_ADDRESS_ID) references ADDRESS
物理表结构如下: