单向关联(Unidirectional associations)
双向关联(Bidirectional associations)
hibernate的单向与双向,体现在Java持久化类(代码)上面就是关联的一端是否拥有另一端的属性引用,体现在数据库里面就是持久化类对应的表里是否拥有另一个表的外键(先不讨论连接表join table)。但是持久化类中的属性引用的体现才是根本,hibernate封装处理时是要分析持久化类的属性及get set方法的。
hibernate的一对多,多对多等关联关系,体现在Java持久化类上面是关联实体的属性引用,体现在数据库中就是如何设置主键(primary key),应为主键是unique的,其他的不是unique的,这样就确定了一对多,多对多等关联关系。
举例如下(用Annotation管理映射关系):
一、基于外键(foreign key)的一对一单向关联:
Husband.java
package hibernate;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
@Entity
public class Husband {
private int id;
private String name;
private Wife wife;
@Id
@GeneratedValue
public int getId() {
return id;
}
public String getName() {
return name;
}
@OneToOne
@JoinColumn(name="wifeId")
public Wife getWife() {
return wife;
}
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setWife(Wife wife) {
this.wife = wife;
}
}
Wife.java
package hibernate;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class Wife {
private int id;
private String name;
@Id
@GeneratedValue
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost/hibernate</property>
<property name="connection.username">root</property>
<property name="connection.password">123456</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</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.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<mapping class="hibernate.Husband"/>
<mapping class="hibernate.Wife"/>
</session-factory>
</hibernate-configuration>
测试类(junit测试):
HibernateORMappingTest.java
package test;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.junit.Test;
public class HibernateORMappingTest {
@Test
public void testSchemaExport() {
// new SchemaExport(new AnnotationConfiguration().configure()).create(false, true);
new SchemaExport(new AnnotationConfiguration().configure()).create(true, true);
}
}
结果:
/*Table: husband*/
------------------
/*Column Information*/
----------------------
FIELD TYPE COLLATION NULL KEY DEFAULT Extra PRIVILEGES COMMENT
------ ------------ --------------- ------ ------ ------- -------------- ------------------------------- -------
id INT(11) (NULL) NO PRI (NULL) AUTO_INCREMENT SELECT,INSERT,UPDATE,REFERENCES
NAME VARCHAR(255) utf8_general_ci YES (NULL) SELECT,INSERT,UPDATE,REFERENCES
wifeId INT(11) (NULL) YES MUL (NULL) SELECT,INSERT,UPDATE,REFERENCES
/*Index Information*/
---------------------
TABLE Non_unique Key_name Seq_in_index Column_name COLLATION Cardinality Sub_part Packed NULL Index_type COMMENT
------- ---------- ------------------ ------------ ----------- --------- ----------- -------- ------ ------ ---------- -------
husband 0 PRIMARY 1 id A 0 (NULL) (NULL) BTREE
husband 1 FKAEEA401B109E78ED 1 wifeId A 0 (NULL) (NULL) YES BTREE
/*DDL Information*/
-------------------
CREATE TABLE `husband` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) DEFAULT NULL,
`wifeId` INT(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `FKAEEA401B109E78ED` (`wifeId`),
CONSTRAINT `FKAEEA401B109E78ED` FOREIGN KEY (`wifeId`) REFERENCES `wife` (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8
/*Table: wife*/
---------------
/*Column Information*/
----------------------
FIELD TYPE COLLATION NULL KEY DEFAULT Extra PRIVILEGES COMMENT
------ ------------ --------------- ------ ------ ------- -------------- ------------------------------- -------
id INT(11) (NULL) NO PRI (NULL) AUTO_INCREMENT SELECT,INSERT,UPDATE,REFERENCES
NAME VARCHAR(255) utf8_general_ci YES (NULL) SELECT,INSERT,UPDATE,REFERENCES
/*Index Information*/
---------------------
TABLE Non_unique Key_name Seq_in_index Column_name COLLATION Cardinality Sub_part Packed NULL Index_type COMMENT
------ ---------- -------- ------------ ----------- --------- ----------- -------- ------ ------ ---------- -------
wife 0 PRIMARY 1 id A 0 (NULL) (NULL) BTREE
/*DDL Information*/
-------------------
CREATE TABLE `wife` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8
二、基于外键(foreign key)的一对一双向关联:
Husband.java
package hibernate2;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
@Entity
public class Husband {
private int id;
private String name;
private Wife wife;
@Id
@GeneratedValue
public int getId() {
return id;
}
public String getName() {
return name;
}
@OneToOne
@JoinColumn(name="wifeId")
public Wife getWife() {
return wife;
}
public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setWife(Wife wife) {
this.wife = wife;
}
}
Wife.java
package hibernate2;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
@Entity
public class Wife {
private int id;
private String name;
private Husband husband;
@OneToOne(mappedBy="wife")
public Husband getHusband() {
return husband;
}
public void setHusband(Husband husband) {
this.husband = husband;
}
@Id
@GeneratedValue
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost/hibernate</property>
<property name="connection.username">root</property>
<property name="connection.password">123456</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</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.NoCacheProvider</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<!-- Drop and re-create the database schema on startup
<property name="hbm2ddl.auto">update</property>
-->
<mapping class="hibernate2.Husband"/>
<mapping class="hibernate2.Wife"/>
</session-factory>
</hibernate-configuration>
测试类 (junit测试):
同上
结果:
/*Table: husband*/
------------------
/*Column Information*/
----------------------
FIELD TYPE COLLATION NULL KEY DEFAULT Extra PRIVILEGES COMMENT
------ ------------ --------------- ------ ------ ------- -------------- ------------------------------- -------
id INT(11) (NULL) NO PRI (NULL) AUTO_INCREMENT SELECT,INSERT,UPDATE,REFERENCES
NAME VARCHAR(255) utf8_general_ci YES (NULL) SELECT,INSERT,UPDATE,REFERENCES
wifeId INT(11) (NULL) YES MUL (NULL) SELECT,INSERT,UPDATE,REFERENCES
/*Index Information*/
---------------------
TABLE Non_unique Key_name Seq_in_index Column_name COLLATION Cardinality Sub_part Packed NULL Index_type COMMENT
------- ---------- ------------------ ------------ ----------- --------- ----------- -------- ------ ------ ---------- -------
husband 0 PRIMARY 1 id A 0 (NULL) (NULL) BTREE
husband 1 FKAEEA401B109E78ED 1 wifeId A 0 (NULL) (NULL) YES BTREE
/*DDL Information*/
-------------------
CREATE TABLE `husband` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) DEFAULT NULL,
`wifeId` INT(11) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `FKAEEA401B109E78ED` (`wifeId`),
CONSTRAINT `FKAEEA401B109E78ED` FOREIGN KEY (`wifeId`) REFERENCES `wife` (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8
/*Table: wife*/
---------------
/*Column Information*/
----------------------
FIELD TYPE COLLATION NULL KEY DEFAULT Extra PRIVILEGES COMMENT
------ ------------ --------------- ------ ------ ------- -------------- ------------------------------- -------
id INT(11) (NULL) NO PRI (NULL) AUTO_INCREMENT SELECT,INSERT,UPDATE,REFERENCES
NAME VARCHAR(255) utf8_general_ci YES (NULL) SELECT,INSERT,UPDATE,REFERENCES
/*Index Information*/
---------------------
TABLE Non_unique Key_name Seq_in_index Column_name COLLATION Cardinality Sub_part Packed NULL Index_type COMMENT
------ ---------- -------- ------------ ----------- --------- ----------- -------- ------ ------ ---------- -------
wife 0 PRIMARY 1 id A 0 (NULL) (NULL) BTREE
/*DDL Information*/
-------------------
CREATE TABLE `wife` (
`id` INT(11) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8