2009年8月7日 星期五

Hibernate實作資料關聯(一)─one-to-one


1.建立表格:
drop table if exists t_passport01;
drop table if exists t_user01;
drop table if exists t_group01;
create table t_group01(
id int(11),
name varchar(50) not null default '',
primary key(id));
create table t_user01(
id int(11) auto_increment,
name varchar(50) default '',
age int(3),
group_id int(11),
primary key(id),
foreign key(group_id) references t_group01(id));
create table t_passport01(
id int(11),
serial varchar(30) default '',
expiry int(11),
primary key(id),
foreign key(id) references t_user01(id));
2.建立TUser01.hbm.xml、TPassport01.hbm.xml、TGroup01.hbm.xml:
<?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 2009/8/7 ?U?? 06:54:10 by Hibernate Tools 3.2.4.GA -->
<hibernate-mapping>
<class name="org.redsaga.quickstart.TUser01" table="t_user01" catalog="manning">
<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="identity" />
</id>
<many-to-one name="TGroup01" class="org.redsaga.quickstart.TGroup01" fetch="select">
<column name="group_id" />
</many-to-one>
<property name="name" type="string">
<column name="name" length="50" />
</property>
<property name="age" type="java.lang.Integer">
<column name="age" />
</property>
<one-to-one name="TPassport01" class="org.redsaga.quickstart.TPassport01" cascade="all"></one-to-one>
</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 2009/8/7 ?U?? 06:54:10 by Hibernate Tools 3.2.4.GA -->
<hibernate-mapping>
<class name="org.redsaga.quickstart.TPassport01" table="t_passport01" catalog="manning">
<id name="id" type="int">
<column name="id" />
<generator class="foreign">
<param name="property">TUser01</param>
</generator>
</id>
<one-to-one name="TUser01" class="org.redsaga.quickstart.TUser01" constrained="true" cascade="all"></one-to-one>
<property name="serial" type="string">
<column name="serial" length="30" />
</property>
<property name="expiry" type="java.lang.Integer">
<column name="expiry" />
</property>
</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 2009/8/7 ?U?? 06:54:10 by Hibernate Tools 3.2.4.GA -->
<hibernate-mapping>
<class name="org.redsaga.quickstart.TGroup01" table="t_group01" catalog="manning">
<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="assigned" />
</id>
<property name="name" type="string">
<column name="name" length="50" not-null="true" />
</property>
<set name="TUser01s" inverse="true" lazy="true" table="t_user01" fetch="select">
<key>
<column name="group_id" />
</key>
<one-to-many class="org.redsaga.quickstart.TUser01" />
</set>
</class>
</hibernate-mapping>
========================================
3.建立TUser01.java、TPassport01.java、TGroup01.java:
package org.redsaga.quickstart;
// Generated 2009/8/7 下午 06:54:10 by Hibernate Tools 3.2.4.GA
/**
* TUser01 generated by hbm2java
*/
public class TUser01 implements java.io.Serializable {
private Integer id;
private TGroup01 TGroup01;
private String name;
private Integer age;
private TPassport01 TPassport01;
public TUser01() {
}
public TUser01(TGroup01 TGroup01, String name, Integer age,
TPassport01 TPassport01) {
this.TGroup01 = TGroup01;
this.name = name;
this.age = age;
this.TPassport01 = TPassport01;
}
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public TGroup01 getTGroup01() {
return this.TGroup01;
}
public void setTGroup01(TGroup01 TGroup01) {
this.TGroup01 = TGroup01;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return this.age;
}
public void setAge(Integer age) {
this.age = age;
}
public TPassport01 getTPassport01() {
return this.TPassport01;
}
public void setTPassport01(TPassport01 TPassport01) {
this.TPassport01 = TPassport01;
}
}
======================================
package org.redsaga.quickstart;
// Generated 2009/8/7 下午 06:54:10 by Hibernate Tools 3.2.4.GA
/**
* TPassport01 generated by hbm2java
*/
public class TPassport01 implements java.io.Serializable {
private int id;
private TUser01 TUser01;
private String serial;
private Integer expiry;
public TPassport01() {
}
public TPassport01(TUser01 TUser01) {
this.TUser01 = TUser01;
}
public TPassport01(TUser01 TUser01, String serial, Integer expiry) {
this.TUser01 = TUser01;
this.serial = serial;
this.expiry = expiry;
}
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
public TUser01 getTUser01() {
return this.TUser01;
}
public void setTUser01(TUser01 TUser01) {
this.TUser01 = TUser01;
}
public String getSerial() {
return this.serial;
}
public void setSerial(String serial) {
this.serial = serial;
}
public Integer getExpiry() {
return this.expiry;
}
public void setExpiry(Integer expiry) {
this.expiry = expiry;
}
}
==========================================
package org.redsaga.quickstart;
// Generated 2009/8/7 下午 06:54:10 by Hibernate Tools 3.2.4.GA
import java.util.HashSet;
import java.util.Set;
/**
* TGroup01 generated by hbm2java
*/
public class TGroup01 implements java.io.Serializable {
private Integer id;
private String name;
private Set TUser01s = new HashSet(0);
public TGroup01() {
}
public TGroup01(String name) {
this.name = name;
}
public TGroup01(String name, Set TUser01s) {
this.name = name;
this.TUser01s = TUser01s;
}
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public Set getTUser01s() {
return this.TUser01s;
}
public void setTUser01s(Set TUser01s) {
this.TUser01s = TUser01s;
}
}
=========================================
4.建立JUnit測試Method(testPrimaryKeyRel、testForeignKeyRel):
/** * testPrimaryKeyRel 資料關聯: One-To-One:一對一關聯 主鍵關聯 * @throws Exception */ public void testPrimaryKeyRel() throws Exception { Transaction tran = null; TUser01 user = null; TPassport01 passport = null; TGroup01 group = null; String hql = null; String groupName = null; Iterator it = null; Integer InId = new Integer(1); boolean groupFlag = false; user = new TUser01(); passport = new TPassport01(); group = new TGroup01(); user.setAge(20); user.setName("陳大明"); group.setName("AdminGroup"); passport.setSerial("PCN759386"); passport.setExpiry(new Integer(20091231)); //相互設置關聯 user.setTPassport01(passport); user.setTGroup01(group); passport.setTUser01(user); try{ hql = "select id from TGroup01 where name=?"; groupName = "AdminGroup"; Query query = session.createQuery(hql); query.setString(0, groupName); it = query.list().iterator(); while(it.hasNext()){ InId = (Integer)it.next(); if(InId==null){ InId = new Integer(1); }else{ groupFlag = true; } } group.setId(InId); tran = session.beginTransaction(); //由於TUser01類別的one-to-one節點被設置為cascade="all" //其關聯的passport對象將被cascade保存 //你可以嘗試把cascade設定為"none",然後執行,觀察結果為何? if(groupFlag==false){ session.save(group); } session.save(user); tran.commit(); List list = session.createQuery(" from TUser01").list(); it = list.iterator(); while(it.hasNext()){ user=(TUser01)it.next(); System.out.println("User name:"+user.getName()); System.out.println("Passport serial:"+user.getTPassport01().getSerial()); } }catch(HibernateException e){ e.printStackTrace(); } }
============================================


/**
* testForeignKeyRel 資料關聯: One-To-One: 唯一外鍵關聯
* @throws Exception
*/
public void testForeignKeyRel() throws Exception {
Transaction tran = null;
TUser01 user = null;
TGroup01 group = null;
Set users = null;
String groupName= null;
Integer InId = new Integer(1);
Integer idCount = new Integer(1);
Iterator it = null;
String hql = null;
boolean groupFlag = false;
user = new TUser01();
group = new TGroup01();
user.setName("陳文華");
user.setAge(25);
groupName = "SalesGroup";
group.setName(groupName);
users = new HashSet(0);
users.add(user);
try{
hql = "select id from TGroup01 where name=?";
Query query = session.createQuery(hql);
query.setString(0, groupName);
it = query.list().iterator();
if(it.hasNext()){
InId = (Integer)it.next();
if(InId == null){
InId = new Integer(1);
}else{
InId = ++idCount;
groupFlag = true;
}
}else{
hql = "select max(id) from TGroup01";
it = session.createQuery(hql).list().iterator();
if(it.hasNext()){
idCount = (Integer)it.next();
if(idCount==null){
InId = new Integer(1);
}else{
InId = ++idCount;
}
}
}
group.setId(InId);
//互相關聯
user.setTGroup01(group);
group.setTUser01s(users);
tran = session.beginTransaction();
if(groupFlag==false){
session.save(group);
}
session.save(user);
session.flush();
tran.commit();
List list = session.createQuery(" from TGroup01 order by name").list();
it = list.iterator();
groupName = null;
while(it.hasNext()){
group = (TGroup01)it.next();
Iterator itgp = group.getTUser01s().iterator();
if(groupName==null){
System.out.println("Group Name:"+group.getName());
}else if(groupName!=null && !groupName.equals(group.getName())){
System.out.println("Group Name:"+group.getName());
}
groupName = group.getName();
while(itgp.hasNext()){
user = (TUser01)itgp.next();
System.out.println("Group User:"+user.getName());
}
}
}catch(HibernateException e){
e.printStackTrace();
}
}
=========================================
5.測試結果:
5.1.一對一關聯,主鍵關聯測試結果:
MySql結果:
Console結果:


Hibernate: select tgroup01x0_.id as col_0_0_ from manning.t_group01 tgroup01x0_ where tgroup01x0_.name=?
Hibernate: insert into manning.t_group01 (name, id) values (?, ?)
Hibernate: insert into manning.t_user01 (group_id, name, age) values (?, ?, ?)
Hibernate: insert into manning.t_passport01 (serial, expiry, id) values (?, ?, ?)
Hibernate: select tuser01x0_.id as id8_, tuser01x0_.group_id as group2_8_, tuser01x0_.name as name8_, tuser01x0_.age as age8_ from manning.t_user01 tuser01x0_
User name:陳大明
Passport serial:PCN759386
5.2.一對一關聯,唯一外鍵關聯結果:

MySql結果:
Console結果:

Hibernate: select tgroup01x0_.id as col_0_0_ from manning.t_group01 tgroup01x0_ where tgroup01x0_.name=?
Hibernate: select max(tgroup01x0_.id) as col_0_0_ from manning.t_group01 tgroup01x0_
Hibernate: insert into manning.t_group01 (name, id) values (?, ?)
Hibernate: insert into manning.t_user01 (group_id, name, age) values (?, ?, ?)
Hibernate: select tgroup01x0_.id as id40_, tgroup01x0_.name as name40_ from manning.t_group01 tgroup01x0_ order by tgroup01x0_.name
Hibernate: select tuser01s0_.group_id as group2_2_, tuser01s0_.id as id2_, tuser01s0_.id as id38_1_, tuser01s0_.group_id as group2_38_1_, tuser01s0_.name as name38_1_, tuser01s0_.age as age38_1_, tpassport0x1_.id as id39_0_, tpassport0x1_.serial as serial39_0_, tpassport0x1_.expiry as expiry39_0_ from manning.t_user01 tuser01s0_ left outer join manning.t_passport01 tpassport0x1_ on tuser01s0_.id=tpassport0x1_.id where tuser01s0_.group_id=?
Group Name:AdminGroup
Group User:陳大明
Group Name:SalesGroup
Group User:陳文華

Hibernate實作Table per subclass之例子

testPerSubClass Table per subclass :每個子類別對應一張表,並與主類別共用主表
1.建立表格:

drop table if exists t_dvd02;
drop table if exists t_book02;
drop table if exists t_item02;
create table t_item02(
id int(11) auto_increment,
name varchar(30) default '',
manufacture varchar(50) default '',
primary key(id));
create table t_book02(
id int(11),
pagecount int(4),
primary key(id),
foreign key(id) references t_item02(id));
create table t_dvd02(
id int(11),
regioncode varchar(30),
primary key(id),
foreign key(id) references t_item02(id));
2.建立TItem02.hbm.xml及TBook02.hbm.xml及TDvd02.hbm.xml:
<?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 2009/8/7 ?W?? 11:20:42 by Hibernate Tools 3.2.4.GA -->
<hibernate-mapping>
<class name="org.redsaga.quickstart.TItem02" table="t_item02" catalog="manning">
<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="identity" />
</id>
<property name="name" type="string">
<column name="name" length="30" />
</property>
<property name="manufacture" type="string">
<column name="manufacture" length="50" />
</property>
<joined-subclass name="org.redsaga.quickstart.TDvd02" table="t_dvd02">
<key column="id"/>
<property name="regioncode" column="regioncode" type="string"/>
</joined-subclass>
<joined-subclass name="org.redsaga.quickstart.TBook02" table="t_book02">
<key column="id"/>
<property name="pagecount" column="pagecount" type="java.lang.Integer"></property>
</joined-subclass>
</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 2009/8/7 ?W?? 11:20:42 by Hibernate Tools 3.2.4.GA -->
<hibernate-mapping>
<class name="org.redsaga.quickstart.TBook02" table="t_book02" catalog="manning">
<id name="id" type="int">
<column name="id" />
<generator class="foreign">
<param name="property">TItem02</param>
</generator>
</id>
<one-to-one name="TItem02" class="org.redsaga.quickstart.TItem02" constrained="true"></one-to-one>
<property name="pagecount" type="java.lang.Integer">
<column name="pagecount" />
</property>
</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 2009/8/7 ?W?? 11:20:42 by Hibernate Tools 3.2.4.GA -->
<hibernate-mapping>
<class name="org.redsaga.quickstart.TDvd02" table="t_dvd02" catalog="manning">
<id name="id" type="int">
<column name="id" />
<generator class="foreign">
<param name="property">TItem02</param>
</generator>
</id>
<one-to-one name="TItem02" class="org.redsaga.quickstart.TItem02" constrained="true"></one-to-one>
<property name="regioncode" type="string">
<column name="regioncode" length="30" />
</property>
</class>
</hibernate-mapping>
======================================
3.建立TItem02.java及TBook02.java及TDvd02.java:
package org.redsaga.quickstart;
// Generated 2009/8/7 上午 11:20:42 by Hibernate Tools 3.2.4.GA
/**
* TItem02 generated by hbm2java
*/
public class TItem02 implements java.io.Serializable {
private Integer id;
private String name;
private String manufacture;
public TItem02() {
}
public TItem02(String name, String manufacture) {
this.name = name;
this.manufacture = manufacture;
}
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public String getManufacture() {
return this.manufacture;
}
public void setManufacture(String manufacture) {
this.manufacture = manufacture;
}
}
===================================
package org.redsaga.quickstart;
// Generated 2009/8/7 上午 11:20:42 by Hibernate Tools 3.2.4.GA
/**
* TBook02 generated by hbm2java
*/
public class TBook02 extends TItem02 implements java.io.Serializable {
private Integer pagecount;
public TBook02() {
}
public TBook02(Integer pagecount) {
this.pagecount = pagecount;
}
public Integer getPagecount() {
return this.pagecount;
}
public void setPagecount(Integer pagecount) {
this.pagecount = pagecount;
}
}
===================================
package org.redsaga.quickstart;
// Generated 2009/8/7 上午 11:20:42 by Hibernate Tools 3.2.4.GA
/**
* TDvd02 generated by hbm2java
*/
public class TDvd02 extends TItem02 implements java.io.Serializable {
private int id;
private String regioncode;
public TDvd02() {
}
public TDvd02(String regioncode) {
this.regioncode = regioncode;
}
public String getRegioncode() {
return this.regioncode;
}
public void setRegioncode(String regioncode) {
this.regioncode = regioncode;
}
}
====================================
4.建立JUnit測試Method(testPerSubClass):
/**
* testPerSubClass Table per subclass 每個子類別對應一張表,並與主類別共用主表
* @throws Exception
*/
public void testPerSubClass() throws Exception {
Transaction tran = null;
TBook02 book = new TBook02();
TDvd02 dvd = new TDvd02();
book.setName("倚天屠龍記");
book.setManufacture("金庸");
book.setPagecount(288);
dvd.setName("今天不回家");
dvd.setManufacture("全家");
dvd.setRegioncode("亞洲");
try{
tran = session.beginTransaction();
session.save(book);
session.save(dvd);
session.flush();
tran.commit();
List list = session.createQuery(" from TItem02").list();
Iterator it = list.iterator();
while(it.hasNext()){
TItem02 item = (TItem02)it.next();
System.out.println(item.getId()+","+item.getName()+","+item.getManufacture());
}
}catch(HibernateException e){
e.printStackTrace();
}
}
==================================
5.測試結果:
MySql結果:
console結果:

Hibernate: insert into manning.t_item02 (name, manufacture) values (?, ?)
Hibernate: insert into t_book02 (pagecount, id) values (?, ?)
Hibernate: insert into manning.t_item02 (name, manufacture) values (?, ?)
Hibernate: insert into t_dvd02 (regioncode, id) values (?, ?)
Hibernate: select titem02x0_.id as id5_, titem02x0_.name as name5_, titem02x0_.manufacture as manufact3_5_, titem02x0_1_.regioncode as regioncode6_, titem02x0_2_.pagecount as pagecount7_, case when titem02x0_1_.id is not null then 1 when titem02x0_2_.id is not null then 2 when titem02x0_.id is not null then 0 end as clazz_ from manning.t_item02 titem02x0_ left outer join t_dvd02 titem02x0_1_ on titem02x0_.id=titem02x0_1_.id left outer join t_book02 titem02x0_2_ on titem02x0_.id=titem02x0_2_.id
1,倚天屠龍記,金庸
2,今天不回家,全家