1.单向 N:1
例如:一个地方有多个人住.
(在1 的一端进行配置,每个同学记住老师,比老师记住每个同学简单.效率高)
2.单向 1:1
基于外键的单向1:1
基于主键的单向 1:1
3.单向 1:N
例如:一个人有多个住的地址(土豪啦)
4.单向 N:N
单向N:N的关联,必须使用中间表
5.双向 1:N
6.双向 N:N
双向N:N的关联,必须使用中间表
6.双向 1:1
//基于外键的双向1:1
//基于主键的双向1:1
7.组建属性包含关联实体
8.复合主键的关联关系
9.复合主键的成员属性为关联实体
10.采用subclass 进行继承映射
11.采用joined-subclass 进行继承映射
21.采用union-subclass 进行继承映射
例如:一个地方有多个人住.
(在1 的一端进行配置,每个同学记住老师,比老师记住每个同学简单.效率高)
public class Address {
private Integer addressid;
private String addressDetail;
//set get ...
}
public class Person {
private Integer id;
private String name;
private int age;
private Address address; //单向(N:1) 反过来(1:1)
//set get...
}
#主表
DROP TABLE IF EXISTS mytest.address;
CREATE TABLE mytest.address
(
aid INTEGER NOT NULL,
addressdesc VARCHAR (400),
PRIMARY KEY (aid)
);
#子表
DROP TABLE IF EXISTS mytest.person;
CREATE TABLE mytest.person
(
pid INTEGER NOT NULL,
name VARCHAR (50) NOT NULL,
age TINYINT NOT NULL DEFAULT 0,
address_id INTEGER,
PRIMARY KEY (pid),
KEY address_id (address_id),
CONSTRAINT person_ibfk_1 FOREIGN KEY (address_id) REFERENCES address (aid)
);
<!--方式1.没有中间关联表(没有中间表)--> <!--在Person.hbm.xml的配置文件中加入 many:Person one:Address --> <many-to-one name="address" cascade="all" class="Address" column="address_id"/> <!--方式2.有中间关联表(有中间表:person_address(person_id,address_id))--> <!--在Person.hbm.xml的配置文件中加入 many:Person one:Address --> <join table="person_address"> <key column="person_id"/> <many-to-one name="address" cascade="all" class="Address" column="address_id"/> </join>
2.单向 1:1
public class Address {
private Integer addressid;
private String addressDetail;
//set get ...
}
public class Person {
private Integer id;
private String name;
private int age;
private Address address; //单向(N:1) 反过来(1:1)
//set get...
}
基于外键的单向1:1
<!--方式1.没有中间关联表(没有中间表)--> <!--在Person.hbm.xml的配置文件中加入 many:Person one:Address --> <many-to-one name="address" unique="true" cascade="all" class="Address" column="address_id"/> <!--方式2.有中间关联表(有中间表:person_address(person_id,address_id))--> <!--在Person.hbm.xml的配置文件中加入 many:Person one:Address --> <join table="person_address"> <key column="person_id"/> <many-to-one name="address" unique="true" cascade="all" class="Address" column="address_id"/> </join>
基于主键的单向 1:1
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Generated 2013-12-2 22:01:23 by Hibernate Tools 3.4.0.CR1 --> <hibernate-mapping> <class name="com.crazyit.app.domain.mapping.Person" table="PERSON"> <id name="id" type="java.lang.Integer"> <column name="ID" /> <!-- <generator class="native" /> --> <generator class="foreign"> <!--通过property 指定 映射的主键为 自己的属性 address这个对象 --> <param name="property">address</param> </generator> </id> <property name="name" type="java.lang.String"> <column name="NAME" /> </property> <property name="age" type="int"> <column name="AGE" /> </property> <!--单向 主键关联(即,该表不能自己生成主键 ,只能引用其他表的主键 比如下面,是引用 Address表 主键 --> <one-to-one name="address"/> </class> </hibernate-mapping>
3.单向 1:N
例如:一个人有多个住的地址(土豪啦)
public class Address {
private Integer addressid;
private String addressDetail;
//set get ...
}
public class Person {
private Integer id;
private String name;
private int age;
//如果一个人有多个地址,而一个地址 又像上面,有多个人,这样就形成了 N:N 所以 1:N 包含了(N:N)
private Set<Address> addresses=new HashSet<Address>();//1:N(包含了 N:N)
//set get...
}
<!--方式一:没有中间表--> <!--在Person.hbm.xml中配置--> <set name="addresses"> <key column="person_id"/> <one-to-many class="Address" not-found="ignore"/> </set> <!--方式二:有中间表(person_address(person_id,address_id))--> <!--还是在Person.hbm.xml中配置--> <set name="addresses" table="person_addesses" cascade="all"> <key column="person_id"/> <many-to-many class="Address" column="address_id" unique="true"/> </set>
4.单向 N:N
单向N:N的关联,必须使用中间表
public class Address {
private Integer addressid;
private String addressDetail;
//set get ...
}
public class Person {
private Integer id;
private String name;
private int age;
//如果一个人有多个地址,而一个地址 又像上面,有多个人,这样就形成了 N:N 所以 1:N 包含了(N:N)
private Set<Address> addresses=new HashSet<Address>();//1:N(包含了 N:N)
//set get...
}
<!--方式二:有中间表(person_address(person_id,address_id))--> <!--还是在Person.hbm.xml中配置--> <set name="addresses" table="person_addesses" cascade="all"> <key column="person_id"/> <many-to-many class="Address" column="address_id"/> </set>
5.双向 1:N
public class Address {
private Integer addressid;
private String addressDetail;
private Person person;
//set get ...
}
public class Person {
private Integer id;
private String name;
private int age;
private Set<Address> addresses=new HashSet<Address>();
//set get...
}
<!--方式一:没有中间表--> <!--在Person.hbm.xml中配置--> <set name="addresses" inverse="true"> <key column="person_id"/> <one-to-many class="Address"/> </set> <!--在Address.hbm.xml中配置--> <many-to-one name="person" class="Person" column="person_id" not-null="true"/> <!--方式二:有中间表(person_address(person_id,address_id))--> <!--在Person.hbm.xml中配置--> <set name="addresses" inverse="true" table="person_address"> <key column="person_id"/> <many-to-many column="address_id" class="Address" unique="true"/> </set> <!--在Address.hbm.xml中配置--> <join table="person_address"> <key column="address_id"/> <many-to-one name="person" column="person_id" not-null="true"></many-to-one> </join> </set>
6.双向 N:N
双向N:N的关联,必须使用中间表
public class Address {
private Integer addressid;
private String addressDetail;
private Set<Person> persons=new HashSet<Person>();
//set get ...
}
public class Person {
private Integer id;
private String name;
private int age;
private Set<Address> addresses=new HashSet<Address>();
//set get...
}
<!--在Person.hbm.xml中配置--> <set name="addresses" inverse="true" table="person_address"> <key column="person_id"/> <many-to-many column="address_id" class="Address"/> </set> <!--在Address.hbm.xml中配置--> <set name="persons" table="peson_addresses"> <key column="address_id"/> <many-to-many column="person_id" class="Person"/> </set>
6.双向 1:1
public class Address {
private Integer addressid;
private String addressDetail;
private Person person;
//set get ...
}
public class Person {
private Integer id;
private String name;
private int age;
private Address address;
//set get...
}
//基于外键的双向1:1
<!--方式1:没有关联表--> <!--在Person.hbm.xml中配置--> <one-to-one name="address" property/> <!--在Address.hbm.xml中配置--> <many-to-one name="person" class="Person" unique="true" column="person_id" not-null="true"/> <!--方式2:有关联表--> <!--在Person.hbm.xml中配置--> <join table="person_address" inverse="true"> <key column="person_id" unique="true"/> <many-to-one name="address" unique="true" class="Address" column="address_id"/> </join> <!--在Address.hbm.xml中配置--> <join table="person_address" optional="true"> <key column="address_id" unique="true"/> <many-to-one name="person" unique="true" column="person_id" not-null="true"/> </join>
//基于主键的双向1:1
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Generated 2013-12-2 22:01:23 by Hibernate Tools 3.4.0.CR1 --> <hibernate-mapping> <class name="com.crazyit.app.domain.mapping.Person" table="PERSON"> <id name="id" type="java.lang.Integer"> <column name="ID" /> <!-- <generator class="native" /> --> <generator class="foreign"> <!--通过property 指定 映射的主键为 自己的属性 address这个对象 --> <param name="property">address</param> </generator> </id> <property name="name" type="java.lang.String"> <column name="NAME" /> </property> <property name="age" type="int"> <column name="AGE" /> </property> <!--单向 主键关联(即,该表不能自己生成主键 ,只能引用其他表的主键 比如下面,是引用 Address表 主键 --> <one-to-one name="address"/> </class> </hibernate-mapping> <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Generated 2013-12-2 22:01:23 by Hibernate Tools 3.4.0.CR1 --> <hibernate-mapping> <class name="com.crazyit.app.domain.mapping.Address" table="ADDRESS"> <id name="id" type="java.lang.Integer"> <column name="ID" /> <generator class="native" /> </id> <property name="addressDetail" type="java.lang.String"> <column name="ADDRESSDETAIL" /> </property> <one-to-one name="person"/> </class> </hibernate-mapping> 这中配置,可以互换 ,现在是person的主键,有address 生成 反过来也可以.
7.组建属性包含关联实体
//不是持久化类
public class Address {
private Integer addressid;
private String addressDetail;
private Set<School> schools=new HashSet<School>();
//set get ...
}
public class School {
private Integer schoolId;
private String schoolname;
//get set
}
public class Person {
private Integer id;
private String name;
private int age;
private Address address; //单向(N:1) 反过来(1:1)
//set get...
}
//在person中进行配置 <!--Person 中 的address是组件 不是持久化类 --> <component name="address" class="Address"> <parent name="person"/> <!--Address 类中的pseron类 --> <property name="addressDetail"/> <set name="schools"> <key column="address_id"/> <one-to-many class="School"/> </set> </component>
8.复合主键的关联关系
public class Person {
//多列 联合组件
private String first;
private String last;
private String name;
private int age;
private Set<Address> addresses=new HashSet<Address>();//1:N(包含了 N:N)
//get set
}
public class Address {
private Integer id;
private String addressDetail;
private Person person;
}
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Generated 2013-12-2 22:01:23 by Hibernate Tools 3.4.0.CR1 --> <hibernate-mapping> <class name="com.crazyit.app.domain.mapping.Person" table="PERSON"> <composite-id> <key-property name="first" type="string"/> <key-property name="last" type="string"/> </composite-id> <property name="name" type="java.lang.String"> <column name="NAME" /> </property> <property name="age" type="int"> <column name="AGE" /> </property> <set name="addresses" inverse="true" cascade="all"> <key> <column name="fisrt"/> <column name="last"/> </key> <one-to-many class="Address"/> </set> </class> </hibernate-mapping> <?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Generated 2013-12-2 22:01:23 by Hibernate Tools 3.4.0.CR1 --> <hibernate-mapping> <class name="com.crazyit.app.domain.mapping.Address" table="PERSON"> <id name="id" type="java.lang.Integer"> <column name="ID" /> <generator class="native" /> </id> <property name="addressDetail" type="java.lang.String"> <column name="ADDRESSDETAIL" /> </property> <many-to-one name="person" class="Person" not-null="true"> <column name="fisrt"/> <column name="last"/> </many-to-one> </class> </hibernate-mapping>
9.复合主键的成员属性为关联实体
public class Order {
private Integer orderId;
private Date orderDate;
private Set<OrderItem> items=new HashSet<OrderItem>();
//get set
}
public class OrderItem {
private Order order;
private Product product;
private int count;
//get set
}
public class Product {
private Integer productId;
private String name;
//get set
}
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Generated 2013-12-2 22:01:23 by Hibernate Tools 3.4.0.CR1 --> <hibernate-mapping> <class name="com.crazyit.app.domain.mapping.OrderItem" table="order_item_info"> <composite-id> <key-many-to-one name="product" class="Product" column="product_id"/> <key-many-to-one name="order" class="Order" column="order_id"/> <key-property name="count" type="int"/> </composite-id> </class> </hibernate-mapping>
10.采用subclass 进行继承映射
public class Person {
private Integer id;
private String name;
private char gender;
private Address address;
//get set
}
public class Address {
private String detail;
private String zip;
private String country;
//get set
}
public class Employee extends Person {
private String title;
private double salary;
private Set<Customer> customers=new HashSet<Customer>();
private Manager manager;
//get set
}
public class Customer extends Person {
private String commnets;
private Employee employee;
//get set
}
public class Manager extends Employee {
private String department;
private Set<Employee> employees=new HashSet<Employee>();
//get set
}
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Generated 2014-1-12 13:35:14 by Hibernate Tools 3.4.0.CR1 --> <hibernate-mapping> <class name="com.crazyit.app.domain.extenr.Person" table="PERSON" discriminator-value="普通人"> <id name="id" type="java.lang.Integer" access="field"> <column name="ID" /> <generator class="assigned" /> </id> <discriminator column="wawa" type="string"/> <property name="name" type="java.lang.String" access="field"> <column name="NAME" /> </property> <property name="gender" type="char" access="field"> <column name="GENDER" /> </property> <component name="address"> <property name="detail"/> <property name="zip"/> <property name="country"/> </component> <subclass name="Employee" discriminator-value="雇员"> <property name="title"/> <property name="salary"/> <many-to-one name="manager" column="manager_id"/> <set name="customer" inverse="true"> <key column="employee_id"/> <one-to-many class="Customer"/> </set> <subclass name="Manager" discriminator-value="经理"> <property name="department"/> <set name="employees" inverse="false"> <key column="manager_id"/> <one-to-many class="Employee"/> </set> </subclass> </subclass> <subclass name="Customer" discriminator-value="顾客"> <property name="comments"/> <many-to-one name="employee" column="employee_id"/> </subclass> <!-- 采用这中配置的缺点:定义的子类字段不能有非空约束 否则保存其他子类的 时候出现冲突, 优点:不用采用多表连接查询,性能比较好 父类和子类的所有属性都在一个表中 --> </class> </hibernate-mapping>
11.采用joined-subclass 进行继承映射
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Generated 2014-1-12 13:35:14 by Hibernate Tools 3.4.0.CR1 --> <hibernate-mapping> <class name="com.crazyit.app.domain.extenr.Person" table="PERSON" discriminator-value="普通人"> <id name="id" type="java.lang.Integer" access="field"> <column name="ID" /> <generator class="assigned" /> </id> <discriminator column="wawa" type="string"/> <property name="name" type="java.lang.String" access="field"> <column name="NAME" /> </property> <property name="gender" type="char" access="field"> <column name="GENDER" /> </property> <component name="address"> <property name="detail"/> <property name="zip"/> <property name="country"/> </component> <joined-subclass name="Employee"> <key column="employee_id"/> <property name="title" not-null="true"/> <property name="salary" not-null="true"/> <many-to-one name="manager" column="manager_id"/> <set name="customers" inverse="true"> <key column="employee_id"/> <one-to-many class="Customer"/> </set> <joined-subclass name="Manager"> <key column="manager_id"/> <property name="department"/> <set name="employees" inverse="true"> <key column="manager_id"/> <one-to-many class="Employee"/> </set> </joined-subclass> </joined-subclass> <joined-subclass name="Customer"> <key column="customer_id"/> <property name="commnets" not-null="true"/> <many-to-one name="employee" column="employee_id" not-null="true"/> </joined-subclass> </class> </hibernate-mapping> <!--这中配置特点是:子类的特性保存在子表中,共性保存在父类中,子类的属性可以加入非空约束了-->
21.采用union-subclass 进行继承映射
<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <!-- Generated 2014-1-12 13:35:14 by Hibernate Tools 3.4.0.CR1 --> <hibernate-mapping> <class name="com.crazyit.app.domain.extenr.Person" table="PERSON" discriminator-value="普通人"> <id name="id" type="java.lang.Integer" access="field"> <column name="ID" /> <generator class="assigned" /> </id> <discriminator column="wawa" type="string"/> <property name="name" type="java.lang.String" access="field"> <column name="NAME" /> </property> <property name="gender" type="char" access="field"> <column name="GENDER" /> </property> <component name="address"> <property name="detail"/> <property name="zip"/> <property name="country"/> </component> <union-subclass name="Employee" table="employee_inf"> <property name="title" not-null="true"/> <property name="salary" not-null="true"/> <many-to-one name="manager" column="manager_id"/> <set name="customers" inverse="true"> <key column="employee_id"/> <one-to-many class="Customer"/> </set> <union-subclass name="Manager" table="manager_inf"> <property name="department"/> <set name="employees" inverse="true"> <key column="manage_id"/> <one-to-many class="Employee"/> </set> </union-subclass> </union-subclass> <union-subclass name="Customer" table="customer_inf"> <property name="commnents" not-null="true"/> <many-to-one name="employee" column="employee_id" not-null="true"/> </union-subclass> </class> </hibernate-mapping> <!-- 子类的特性和共性,在子表中都会存在,和 joined-subclass的最他区别. 使用union-subclass 持久化的主键生成方式不能是 identity ,sequence,native. -->