??xml version="1.0" encoding="utf-8" standalone="yes"?> 当应用程序通过new语句创徏了一个对象,q个对象的生命周期就开始了Q当不再有Q何引用变量引用它Q这个对象就l束生命周期Q它占用的内存就可以被JVM的垃圑֛收器回收。对于需要被持久化的Java对象Q在它的生命周期中,可处于以下三个状态之一Q?br />
?为Java对象的完整状态{换图QSession的特定方法触发Java对象׃个状态{换到另一个状态。从?看出Q当Java对象处于临时状态或游离状态,只要不被M变量引用Q就会结束生命周期,它占用的内存可以被JVM的垃圑֛收器回收Q当处于持久化状态,׃Session的缓存会引用它,因此它始l处于生命周期中?br />
持久化对象的特征 Customer a=(Customer)session1.load(Customer.class,new Long(1)); System.out.println(a= =b); //true tx1.commit(); Customer c=(Customer)session1.load(Customer.class,new Long(1)); //Customer对象被session1兌 tx1.commit(); //执行update语句 当执行session1的load()Ҏ(gu)ӞOID?的Customer对象被加入到session1的缓存中Q因此它是session1的持久化对象Q此时它q没有被session2兌Q因此相对于session2Q它处于游离状态。当执行session2的update()Ҏ(gu)ӞCustomer对象被加入到session2的缓存中Q因此也成ؓsession2的持久化对象。接下来修改Customer对象的name属性,会导致两个Session实例在清理各自的~存Ӟ都执行相同的update语句Q?br />
兌U别索策略有立即索、gq检索和q切左外q接索。对于关联别检索,又可分ؓ一对多和多对多、多对一和一对一两种情况讨论?/p>
一对多和多对多兌关系一般?lt;set>配置?lt;set>有lazy和outer-join属性,它们的不同取值绝对了索策略?/p>
1Q立x索:q是一对多默认的检索策略,此时lazy=falseQouter-join=false.管q是默认的检索策略,但如果关联的集合是无用的Q那么就不要使用q种索方式?/p>
2Qgq检索:此时lazy=trueQouter-join=falseQouter-join=true是无意义的)Q这是优先考虑的检索方式?/p>
3Q迫切左外连接检索:此时 lazy=falseQouter-join=trueQ这U检索策略只适用于依靠id索方式(load、getQ,而不适用于query的集合检索(它会采用立即索策略)。相比于立即索,q种索策略减了一条sql语句Q但在Hibernate中,只能有一?lt;set>配置?outer-join=true. 多对一和一对一索策略一般?lt;many-to-one>?lt;one-to-one>配置?lt;many-to-one>中需要配|的属性是 outer-joinQ同时还需要配|one端关联的<class>的lazy属性(配置的可不是<many-to-one>中的lazy哦)Q它们的l合后的索策略如下: 1Q?outer-join=autoQ这是默认|如果lazy=true为gq检索,如果lazy=false切左外连接检索?/p>
2Q?outer-join=trueQ无关于lazyQ都切左外连接检索?/p>
3Q?outer-join=falseQ如果lazy=true为gq检索,否则为立x索?/p>
可以看到Q在默认的情况下Qouter-join=autoQlazy=falseQ,对关联的one端对象Hibernate采用的迫切左外连接检索。依我看Q很多情况下Q我们ƈ不需要加载one端关联的对象Q很可能我们需要的仅仅是关联对象的idQ;另外Q如果关联对象也采用了迫切左外连接检索,׃出现select语句中有多个外连接表Q如果个数多的话会媄响检索性能Q这也是Z么Hibernate通过hibernate.max_fetch_depth属性来控制外连接的深度。对于迫切左外连接检索,query的集合检索ƈ不适用Q它会采用立x索策略?/p>
对于索策略,需要根据实际情况进行选择。对于立x索和延迟索,它们的优点在于select语句单(每张表一条语句)、查询速度快,~点在于兌表时需要多条select语句Q增加了讉K数据库的频率。因此在选择x索和延迟索时Q可以考虑使用扚w索策略来减少select语句的数量(配置batch-size属性)。对于切左外q接索,优点在于select较少Q但~点是select语句的复杂度提高Q多表之间的兌会是很耗时的操作。另外,配置文g是死的,但程序是zȝQ可以根据需要在E序里显C的指定索策略(可能l常需要在E序中显C指定迫切左外连接检索)。ؓ了清楚检索策略的配置效果如何Q可以配|show_sql属性查看程序运行时Hibernate执行的sql语句?/p>
选自<<_NHibernateQJava对象持久化技术详?gt;> 作者:孙卫?/font> 来源:www.javathinker.org
(1) 临时状态(transientQ:刚刚用new语句创徏Q还没有被持久化Q不处于Session的缓存中。处于(f)时状态的Java对象被称Z(f)时对象?br />
(2) 持久化状态(persistentQ:已经被持久化Q加入到Session的缓存中。处于持久化状态的Java对象被称为持久化对象?br />
(3) 游离状态(detachedQ:已经被持久化Q但不再处于Session的缓存中。处于游ȝ态的Java对象被称为游d象?br />
临时对象的特?/strong>
临时对象h以下特征Q?br />
(1) 不处于Session的缓存中Q也可以_不被M一个Session实例兌?br />
(2) 在数据库中没有对应的记录?
在以下情况下QJava对象q入临时状态:
(1) 当通过new语句刚创Z一个Java对象Q它处于临时状态,此时不和数据库中的Q何记录对应?br />
(2) Session的delete()Ҏ(gu)能一个持久化对象或游d象{变ؓ临时对象。对于游d象,delete()Ҏ(gu)从数据库中删除与它对应的记录Q对于持久化对象Qdelete()Ҏ(gu)从数据库中删除与它对应的记录Qƈ且把它从Session的缓存中删除?/p>
持久化对象具有以下特征:
(1) 位于一个Session实例的缓存中Q也可以_持久化对象L被一个Session实例兌?br />
(2) 持久化对象和数据库中的相兌录对应?br />
(3) Session在清理缓存时Q会Ҏ(gu)持久化对象的属性变化,来同步更新数据库?br />
Session的许多方法都能够触发Java对象q入持久化状态:
(1) Session的save()Ҏ(gu)把(f)时对象{变ؓ持久化对象?br />
(2) Session的load()或get()Ҏ(gu)q回的对象L处于持久化状态?br />
(3) Session的find()Ҏ(gu)q回的List集合中存攄都是持久化对象?br />
(4) Session的update()、saveOrUpdate()和lock()Ҏ(gu)使游d象{变ؓ持久化对象?nate?/font>:Ҏ(gu)hibernate reference的说法当试图用update更新一个持久化对象时会抛异?
(5)当一个持久化对象兌一个(f)时对象,在允许联保存的情况下,Session在清理缓存时会把q个临时对象也{变ؓ持久化对象?
Hibernate保证在同一个Session实例的缓存中Q数据库表中的每条记录只对应惟一的持久化对象。例如对于以下代码,共创Z两个Session实例Qsession1和session2。session1和session2拥有各自的缓存。在session1的缓存中Q只会有惟一的OID?的Customer持久化对象,在session2的缓存中Q也只会有惟一的OID?的Customer持久化对象。因此在内存中共有两个Customer持久化对象,一个属于session1的缓存,一个属于session2的缓存。引用变量a和b都引用session1~存中的Customer持久化对象,而引用变量c引用session2~存中的Customer持久化对象:
Session session1=sessionFactory.openSession();
Session session2=sessionFactory.openSession();
Transaction tx1 = session1.beginTransaction();
Transaction tx2 = session2.beginTransaction();
Customer b=(Customer)session1.load(Customer.class,new Long(1));
Customer c=(Customer)session2.load(Customer.class,new Long(1));
System.out.println(a= =c); //false
tx2.commit();
session1.close();
session2.close();
Java对象的持久化状态是相对于某个具体的Session实例的,以下代码试图使一个Java对象同时被两个Session实例兌Q?br />
Session session1=sessionFactory.openSession();
Session session2=sessionFactory.openSession();
Transaction tx1 = session1.beginTransaction();
Transaction tx2 = session2.beginTransaction();
session2.update(c); //Customer对象被session2兌
c.setName("Jack"); //修改Customer对象的属?/p>
tx2.commit(); //执行update语句
session1.close();
session2.close();
update CUSTOMERS set NAME='Jack' …… where ID=1;
在实际应用程序中Q应该避免一个Java对象同时被多个Session实例兌Q因会导致重复执行SQL语句Qƈ且极Ҏ(gu)出现一些ƈ发问题?br />
]]>
create table db_iteam(
id int identity not null,
iteamNum"char(10) not null,
paId int null,
primary key ("id")
)
go
/*************/
创徏db_user?br />
create table db_user (
id int identity not null,
name char(10) not null,
iteamId int null,
primary key ("id")
)
/***********************/
创徏db_passport
create table db_passport(
"id" int not null, //主键兌与db_user
"number" char(10) not null,
primary key ("id")
)
go
*******************
vo:
*******************
package wsq.vo;
import java.util.HashSet;
import java.util.Set;
public class DbIteam implements java.io.Serializable {
private Integer id;
private String iteamNum;
private DbIteam subIteam;
private Set subIteams=new HashSet();
private Set users=new HashSet();
public Set getUsers() {
return users;
}
public void setUsers(Set users) {
this.users = users;
}
public DbIteam() {
}
public DbIteam(String iteamNum) {
this.iteamNum = iteamNum;
}
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public String getIteamNum() {
return this.iteamNum;
}
public void setIteamNum(String iteamNum) {
this.iteamNum = iteamNum;
}
public DbIteam getSubIteam() {
return subIteam;
}
public void setSubIteam(DbIteam subIteam) {
this.subIteam = subIteam;
}
public Set getSubIteams() {
return subIteams;
}
public void setSubIteams(Set subIteams) {
this.subIteams = subIteams;
}
}
******************
package wsq.vo;
public class DbUser implements java.io.Serializable {
private Integer id;
private String name;
private DbIteam dbIteam;
private DbPassport dbPassport;
public DbPassport getDbPassport() {
return dbPassport;
}
public void setDbPassport(DbPassport dbPassport) {
this.dbPassport = dbPassport;
}
public DbUser() {
}
public DbUser(String name) {
this.name = name;
}
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 toString()
{
return name+" 试Q?;
}
public DbIteam getDbIteam() {
return dbIteam;
}
public void setDbIteam(DbIteam dbIteam) {
this.dbIteam = dbIteam;
}
}
/**********************************/
package wsq.vo;
public class DbPassport implements java.io.Serializable {
private Integer id;
private String number;
private DbUser dbUser;
public DbUser getDbUser() {
return dbUser;
}
public void setDbUser(DbUser dbUser) {
this.dbUser = dbUser;
}
public DbPassport() {
}
public DbPassport(String number) {
this.number = number;
}
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public String getNumber() {
return this.number;
}
public void setNumber(String number) {
this.number = number;
}
}
/******************************/
配置DbIteam.hbm.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="wsq.vo.DbIteam" table="db_iteam" schema="dbo"
catalog="dbs" >
<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="native" />
</id>
<property name="iteamNum" type="java.lang.String">
<column name="iteamNum" length="10" not-null="true" />
</property>
<many-to-one name="subIteam" class="wsq.vo.DbIteam" column="paId" />
<set name="users" cascade="all" table="db_user" lazy="true" batch-size="5">
<key column="iteamId"></key>
<one-to-many class="wsq.vo.DbUser" />
</set>
<set name="subIteams" cascade="all" table="db_iteam" lazy="true" batch-size="5">
<key column="paId"></key>
<one-to-many class="wsq.vo.DbIteam" />
</set>
</class>
</hibernate-mapping>
配置DbUser.hbm.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="wsq.vo.DbUser" table="db_user" schema="dbo" catalog="dbs">
<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="native" />
</id>
<property name="name" type="java.lang.String">
<column name="name" length="10" not-null="true" />
</property>
<many-to-one name="dbIteam" class="wsq.vo.DbIteam" column="iteamId" outer-join="true" ></many-to-one>
<one-to-one name="dbPassport" class="wsq.vo.DbPassport" cascade="all" ></one-to-one>
</class>
</hibernate-mapping>
配置DbPassport.hbm.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="wsq.vo.DbPassport" table="db_passport" schema="dbo"
catalog="dbs">
<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="foreign" >
<param name="property">dbUser</param>
</generator>
</id>
<property name="number" type="java.lang.String">
<column name="number" length="10" not-null="true" />
</property>
<one-to-one name="dbUser" class="wsq.vo.DbUser" constrained="true"></one-to-one>
</class>
</hibernate-mapping>
/*******************
试c?br />
package wsq.vo;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Transaction;
public class Test {
private static final Log log = LogFactory.getLog(Test.class);
Test() {
}
public static void main(String[] args) {
BaseHibernateDAO basedao = new BaseHibernateDAO( );
DbIteamDAO iteamDAO = new DbIteamDAO( );
DbUserDAO userDAO = new DbUserDAO( );
DbIteam iteam = new DbIteam( );
DbIteam iteam3 = new DbIteam( );
DbUser user = new DbUser( );
DbPassport ps = new DbPassport( );
Transaction tx = basedao.getSession( ).beginTransaction( );
iteam.setIteamNum("2");
iteam.setSubIteam(iteamDAO.findById(16)); //iteamDAO.findById(16)扑ֈ的是一U?nbsp; 此处d?U?br />
iteam3.setIteamNum("3");
iteam3.setSubIteam(iteam);//3U?br />
user.setName("djg");
user.setDbIteam(iteam3);
ps.setNumber("48");
user.setDbPassport(ps);
ps.setDbUser(user);
// iteamDAO.delete(iteamDAO.findById(23));
iteamDAO.save(iteam);
iteamDAO.save(iteam3);
userDAO.save(user);
log.info("ok!!!!!! !!ok!!! ok! 111111111111111111 !! !");
tx.commit( );
}
}
package wsq.po;
import java.util.Date;
public class PersonOne implements java.io.Serializable {
private static final long serialVersionUID = 3694568337955384021L;
private Integer id;
private String role;
private String username;
private String password;
private String sex;
private Date birthday;
// private String grade;
// private String schoolage;
public PersonOne() {
}
public PersonOne(String role, String username, String password, String sex,
Date birthday, String grade, String schoolage) {
this.role = role;
this.username = username;
this.password = password;
this.sex = sex;
this.birthday = birthday;
//this.grade = grade;
//this.schoolage = schoolage;
}
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public String getRole() {
return this.role;
}
public void setRole(String role) {
this.role = role;
}
public String getUsername() {
return this.username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return this.password;
}
public void setPassword(String password) {
this.password = password;
}
public String getSex() {
return this.sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Date getBirthday() {
return this.birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
// public String getGrade() {
// return this.grade;
// }
//
// public void setGrade(String grade) {
// this.grade = grade;
// }
//
// public String getSchoolage() {
// return this.schoolage;
// }
//
// public void setSchoolage(String schoolage) {
// this.schoolage = schoolage;
// }
}
package wsq.po;
public class Student extends PersonOne implements java.io.Serializable {
private static final long serialVersionUID = -2981420482383402755L;
private String grade;
public String getGrade() {
return this.grade;
}
public void setGrade(String grade) {
this.grade = grade;
}
}
Teacher :
package wsq.po;
public class Teacher extends PersonOne implements java.io.Serializable {
private static final long serialVersionUID = -8404469876025711535L;
private String schoolage;
public String getSchoolage() {
return schoolage;
}
public void setSchoolage(String schoolage) {
this.schoolage = schoolage;
}
}
配置Q?br />
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="wsq.po.PersonOne" table="personOne" schema="dbo"
catalog="J2EE">
<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="increment" />
</id>
<!-- important -->
<discriminator column="role" type="java.lang.String"/>
<property name="username" type="java.lang.String">
<column name="username" length="20" not-null="true" />
</property>
<property name="password" type="java.lang.String">
<column name="password" length="20" not-null="true" />
</property>
<property name="sex" type="java.lang.String">
<column name="sex" length="5" not-null="true" />
</property>
<property name="birthday" type="java.util.Date">
<column name="birthday" length="23" not-null="true" />
</property>
<subclass name="wsq.po.Student" discriminator-value="1">
<property name="grade" column="grade" type="java.lang.String" />
</subclass>
<subclass name="wsq.po.Teacher" discriminator-value="2">
<property name="schoolage" column="schoolage" type="java.lang.String" />
</subclass>
</class>
</hibernate-mapping>
person ?/span>
id;(主键) int;
username varchar;
password varchar;
sex varchar;
birthday DateTime;
*******************
student?nbsp;
id;(主键)
grade varchar;
*******************
teacher?/span>
id;(主键)
schoolage varchar;
/////////////////////******////////////////////////////////
再创建VO
Person
package wsq.po;
import java.util.Date;
public class Person implements java.io.Serializable {
private static final long serialVersionUID = -4431851578811178858L;
private Integer id;
private String username;
private String password;
private String sex;
private Date birthday;
public Person() {
}
public Person(String username, String password, String sex, Date birthday) {
this.username = username;
this.password = password;
this.sex = sex;
this.birthday = birthday;
}
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return this.username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return this.password;
}
public void setPassword(String password) {
this.password = password;
}
public String getSex() {
return this.sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Date getBirthday() {
return this.birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}
Student
注意id属性没有了package wsq.po;
public class Student extends Person implements java.io.Serializable {
private static final long serialVersionUID = -2981420482383402755L;
private String grade;
public Student() {
}
public String getGrade() {
return this.grade;
}
public void setGrade(String grade) {
this.grade = grade;
}
}
Teacher
package wsq.po;
public class Teacher extends Person implements java.io.Serializable {
private static final long serialVersionUID = -8404469876025711535L;
private String schoolage;
public Teacher() {
}
public String getSchoolage() {
return this.schoolage;
}
public void setSchoolage(String schoolage) {
this.schoolage = schoolage;
}
}
////////////////////****************/////////////////////////
最关键的就是配|了
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="wsq.po.Person" table="person" schema="dbo" catalog="J2EE">
<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="increment" />
</id>
<property name="username" type="java.lang.String">
<column name="username" length="20" not-null="true" />
</property>
<property name="password" type="java.lang.String">
<column name="password" length="20" not-null="true" />
</property>
<property name="sex" type="java.lang.String">
<column name="sex" length="2" not-null="true" />
</property>
<property name="birthday" type="java.util.Date">
<column name="birthday" length="8" not-null="true" />
</property>
<joined-subclass name="wsq.po.Student" table="student">
<key column="id"/>
<property name="grade" type="java.lang.String" column="grade" />
</joined-subclass>
<joined-subclass name="wsq.po.Teacher" table="teacher">
<key column="id"/>
<property name="schoolage" type="java.lang.String" column="schoolage" />
</joined-subclass>
</class>
</hibernate-mapping>