总结了Hibernate中实体对象与数据的映射方式……图文并茂,配置实例代码,为david吃饱了撑着之大作。
1 Entity's relation
1.1 One to One
一个对象的一个实例对应另一个对象的一个实例从数据库角度描述,一个表中的一条记录对应另外一个表中唯一一条记录
public class Image{
private Long id;
private String imgName;
private Blog value; //to store binary of image
......
}
Image.hbm.xml
<class name="Image" dynamic-update="true">
<id...
<property...
</class>
public class Product{
private Long id;
private String name;
private double price;
private Image photo;
}
<class name=...dynamic-update="true" lazy="true"
<id...
<property...
<one-to-one name="photo" class="package.Image" cascade="all" outer-join="auto" constrained="false"/>
</class>
1.2 Many to One
一个对象对应另一个对象的多个实例,从数据库角度描述,是在一个数据表中的一条记录对应另外一个数据表中对条记录.
public class PersonalCompute{
private Long computerId;
private String cpu;
......
private Programmer owner;
}
<class name="Programmer" table="Programmer">
<id...
<property...
</class>
<class name="PersonalCompute" table="PCS">
<id....
<property...
<many-to-one name="owner" column="programmerId" class="Programmer">
</many-to-one>
1.3 One to Many
The same example as Many to One.But we stand at Programmer class's view point.
public class Programmer{
...
private Set computers = new HashSet();
}
<class name="Programmer" table="Programmer">
<id...
<property...
<set name="computers" inverse="true" cascade="all">
<key column="programmerId" />
<one-to-many class="PersonalComputers">
</one-to-many>
</set>
2 Collection
2.1 Map
<class name="Team">
...
<map name="members">
<key foreign-key="fk">
<column name="teamNumber">
</key>
<index column="teamRole" type="string"/>
<element column="name" ...
</map>
showcase:
Team team1 = new Team();
team1.setName(xx);
team1.getMembers.put("index","content");
......
sess.save...
2.1.1 many-to-any
2.1.2 One to many
单单使用Map做存储往往无法表达复杂的对象,如果要讲对象 map进行映射:
One Team,multi-members
Public class Member{
...
private Team team;
}
<class name="Team">
...
<map name="members" inverse="false">
<key column="team" foreign-key="fk"/>
<index type="string" column="teamRole"/>
<one-to-many class="Member"/>
</map>
<class name="member">
<id...
<property...
<many-to-one name="team" />
showcase:
Team team = new Team();
team.setName("xx");
Member mem1 = new Member();
mem1.setXX
mem1.setXX
Member mem2 = new Member();
mem2.setXX
mem2.setXX
team.getMembers().put("xx",mem1);
team.getMembers().put("xx2",mem2);
2.1.3 many to many
<class name="Team">
<id
<propery
<map name="members" inverse="false" table="teamHasMembers">
<key column="team" foreign-key="fk"/>
<index type="string" column="teamRole"/>
<many-to-many class="member" outer-join="auto">
<column name="member"/>
</many-to-many>
</map>
<class name="Member">
<id
<property
<map name="teams" table="memberAtTeams">
<key....
teamRole is their common key of Map.
Team
Member
memberAtTeams
member |
team |
teamRole |
1 |
2 |
coach |
teamHasMembers
team |
member |
teamRole |
2 |
1 |
coach |
2.1.4 Composite-index
复杂Index 可以是一个类。
public class Position{
private String role;
private String scene;
public Position()....
getter...
setter...
}
<class name="Team">
<id...
<property...
<map name="members" inverse="false">
<key column="team" foreign-key="fk"/>
<composite-index class="Position">
<key-property..
<key-property...
</composite-index>
<one-to-many class="Member"/>
</map>
...
<class name="Member">
<id...
<property...
<many-to-one name="team"/>
</class>
index-many-to-one
index-many-to-many
index-many-to-any
2.1.5 composite-element
<import class="Member"/>
<class name="Team">
<id...
<property...
<map name="members" table="teamMembers">
<key column="teamId"/>
<index...
<composite-element class="Member">
<parent name="parent"/>
<property...
<property...
</composite-element>
</map>
2.2 Set
<class name="Team">
<..
<set name="members" inverse="false">
<key column="team" foreign-key="fk"/>
<elemnet column="name" type="string"/>
</set>
2.2.1 one-to-many
<set name="xx" column="">
<key column="" foreign-key="fk"/>
<one-to-many class="BB"/>
</set>
2.2.2 many-to-many
<class name="Team">
<id..
<property...
<set name="members" inverse="false" table="teamHasMembers">
<key column="team" foreign-key="fk">
<many-to-many class="Member" outer-join="auto">
<column name="member"/>
</set>
</class>
<class name="Member">
<id..
<property...
<set name="members" inverse="true" table="memberAtTeams">
<key column="member" foreign-key="fk">
<many-to-many class="Member" outer-join="auto">
<column name="team"/>
</set>
</class>
2.2.3 many-to-any
2.2.4 composite-element
2.3 List
<list name="members" inverse="false">
<key column="team" foreign-key="fk"/>
<index column="teamMember"/>
<element column="name" type="string"/>
</list>
2.3.1 one-to-many
2.3.2 many-to-many
2.3.3 many-to-many
2.3.4 composite-element
2.4 Bag
It can contains JDK's Collection and List interface type's object.
2.5 idBag
与bag相比多出了collection-id属性
<ibdbag name="">
<collection-id column="mbid" type="long">
<generator class="hilo"/>
</collection-id>
<key..
<element..
</idbag>
2.6 array
public class Team{
//...
private String[] members;
}
<array name="members" inverse="false">
<key column="team" foreign-key="fk"/>
<index column="teamNumber"/>
<element column="name" type="string"/>
</array>
3 Component
<class name="Country">
<id..
<property...
<component name="position">
<property...
</component>
Public class Country{
//..
private Position position;
}
3.1 One-to-one
3.2 many-to-one
3.3 dynamic-component
4 Dynamic class
<dynamic-class entity-name="Country">
<id name="id" type="long">
<generator class="hilo"/>
</id>
<property name="name" column="NAME" type="string"/>
</..
4.1 One-to-one
4.2 many-to-one
5 Mapping type
5.1 Java type to SQL type
5.2 3.0 enmu
5.3 user defined data type
need implements org.hibernate.usertype.CompositeUserType or org.hibernate.usertype.UserType interface.
6 Class Hierarchy's mapping
6.1 Subclasses are saved in on Table
6.1.1 discriminator
Sapmle:
Class AbstractParent{
String id;
/*important*/
String discriminator
}
Class ChildA{
String childA;
}
Class ChildB{
String childB;
}
=========DB=========
colum name |
data type |
memo |
id |
varchar |
|
childA |
varchar |
|
childB |
varchar |
|
class_type |
varchar |
used to identify subclass:A B |
========mapping config file====
<class name="AbstractParent" table="PARENT" abstract="true">
<id...
<discriminator column="CLASS_TYPE" type="string"/>
<property......
<subclass name="ChildA" discriminator-value="A">
<property name="childA"/>
</subclass>
<subclass......
id generator
· increment
· identity
· sequence
· hilo
· seqhilo
· uuid
· guid
· native
· assigned
· foreign
composite id
<composite-id>
<key-property name=""/>
<key-property name=""/>
</composite-id>
6.2 Subclasses are saved in separated Table
并不为父类Container建立映射文件 Box与Bottle的映射文件也如没有关系一样普通的建立 但是对Container取得操作
List pcs = sess.createQuery("from com.be.david.Container").list();
if(!cs.isEmpty()){
...
}
会将Box与Container数据都取出来 这是Hibernate默认隐式完成的
6.3 Parent Class and Subclasses are saved in separated Table
<class name="Container" table="CONTAINER">
<id...
<property...
<joined-subclass name="Box" table="CONTAINER_BOX">
<key column="ContainerId"/>
<property...
</joined-subclass>
<joined-subclass name="Bottle" table="CONTAINER_BOTTLE">
<key...
<property...
</joined-subclass>
</class>
6.4 One PO multi-table
public Class Person{
public String id;
public String name;
public String sex;
public String address;
public String city;
public String zipcode;
}
we wanna save address related attributes(blue ones).Use join
<class name="Person" table="PERSON">
<id...
<property ...
<join table="ADDRESS">
<key column="addressID"/>
<property name="address"/>
...
</join>
</class>
6.5 Class A Class B not inherited from Parent Class
6.5.1 subselect
We can use subselct to make ChildA and ChildB standalone.So how can we get all data including ChindA and ChildB?
<class name="ChildA" table="parent">
<id...
<property...
</class>
<class name="ChildB" table="parent">
<id...
<property...
</class>
<class name="Parent" mutable="false">
<subselect>
select * from ChildA
union
select * from ChildB
</subselect>
<sychronize table="ChildA"/>
<sychronize table="ChildB"/>
<id...
<property...
</class>