[size=medium][b]1.单向 N:1 [/b]
例如:一个地方有多个人住.
(在1 的一端进行配置,每个同学记住老师,比老师记住每个同学简单.效率高)
[/size]
[size=medium][b]2.单向 1:1 [/b]
[/size]
基于外键的单向1:1
基于主键的单向 1:1
[size=medium][b]3.单向 1:N [/b]
例如:一个人有多个住的地址(土豪啦)
[/size]
[size=medium][b]4.单向 N:N [/b]
单向N:N的关联,必须使用中间表
[/size]
[size=medium][b]5.双向 1:N [/b]
[/size]
[size=medium][b]6.双向 N:N [/b]
双向N:N的关联,必须使用中间表
[/size]
[size=medium][b]6.双向 1:1 [/b]
[/size]
//基于外键的双向1:1
//基于主键的双向1:1
[size=medium][b]7.组建属性包含关联实体[/b][/size]
[size=medium][b]8.复合主键的关联关系[/b][/size]
[size=medium][b]9.复合主键的成员属性为关联实体[/b][/size]
[size=medium][b]10.采用subclass 进行继承映射[/b][/size]
[size=medium][b]11.采用joined-subclass 进行继承映射[/b][/size]
[size=medium][b]21.采用union-subclass 进行继承映射[/b][/size]
例如:一个地方有多个人住.
(在1 的一端进行配置,每个同学记住老师,比老师记住每个同学简单.效率高)
[/size]
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>
[size=medium][b]2.单向 1:1 [/b]
[/size]
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>
[size=medium][b]3.单向 1:N [/b]
例如:一个人有多个住的地址(土豪啦)
[/size]
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>
[size=medium][b]4.单向 N:N [/b]
单向N:N的关联,必须使用中间表
[/size]
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>
[size=medium][b]5.双向 1:N [/b]
[/size]
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>
[size=medium][b]6.双向 N:N [/b]
双向N:N的关联,必须使用中间表
[/size]
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>
[size=medium][b]6.双向 1:1 [/b]
[/size]
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 生成
反过来也可以.
[size=medium][b]7.组建属性包含关联实体[/b][/size]
//不是持久化类
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>
[size=medium][b]8.复合主键的关联关系[/b][/size]
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>
[size=medium][b]9.复合主键的成员属性为关联实体[/b][/size]
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>
[size=medium][b]10.采用subclass 进行继承映射[/b][/size]
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>
[size=medium][b]11.采用joined-subclass 进行继承映射[/b][/size]
<?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>
<!--这中配置特点是:子类的特性保存在子表中,共性保存在父类中,子类的属性可以加入非空约束了-->
[size=medium][b]21.采用union-subclass 进行继承映射[/b][/size]
<?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.
-->