??xml version="1.0" encoding="utf-8" standalone="yes"?>
CZ囄Q?br />
]]>
日记本程?br />
http://m.tkk7.com/Files/junglesong/MyDiary20080809155951.zip
个h通讯?br />
http://m.tkk7.com/Files/junglesong/MyMemo20080809160003.zip
公共资源理pȝ
http://m.tkk7.com/Files/junglesong/PublicResMngSys20080809160011.rar
其实是关键一句话Q?br />
window.opener.document.getElementById("XXX").value=“123456”;
例程如下Q?br />
http://m.tkk7.com/Files/junglesong/ParentChildWnd20080520140659.rar
在JavaE序?cM间存在多U包含关p?典型的三U关联关pL:一个类拥有另一个类的成?一个类拥有另一个类的集合的成员;两个cȝ互拥有对象的集合的成?在Hibernate?我们可以使用映射文g中的many-to-one, one-to-many, many-to-many来实现它?q样的关pdHibernate中简UCؓ多对一,一对多和多对多.
多对一的类代码
事g与地Ҏ(gu)典型的多对一关系,多个事g可以在一个地点发?旉不同),一个地点可发生多个事g.它们的对应关pL(?事g?一)地点.
两个cȝ代码如右:
public class Event{
private String id;
private String name;
private Location location;
}
public class Location{
private String id;
private String name;
}
多对一的映文?/strong>
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.hibernate.auction">
<class name="com.sitinspring.domain.Event"
table="Event_TB">
<id name="id" column="ID" >
<generator class="uuid.hex"/>
</id>
<property name="name" column="name" />
<many-to-one name="location" column="locationId" class="com.sitinspring.domain.Location"/>
</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">
<hibernate-mapping package="org.hibernate.auction">
<class name="com.sitinspring.domain.Location"
table="Location_TB">
<id name="id" column="ID" >
<generator class="uuid.hex"/>
</id>
<property name="name" column="name" />
</class>
</hibernate-mapping>
多对一的表数据
一对多的类代码
如果一个用h多个权限,那么UsercdPrivilegecd构成了一对多的关p?Usercd包含一个Privilegecȝ集合.
public class User{
private String id;
private String name;
private Set<Privilege> privileges=new LinkedHashSet<Privilege>();
}
public class Privilege{
private String id;
private String userId;
private int privilegeLevel;
}
一对多的映文?/strong>
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.hibernate.auction">
<class name="com.sitinspring.domain.User"
table="User_TB">
<id name="id" column="ID" >
<generator class="uuid.hex"/>
</id>
<property name="name" column="name" />
<set name="privileges">
<key column="userId"/>
<one-to-many class="com.sitinspring.domain.Privilege"/>
</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">
<hibernate-mapping package="org.hibernate.auction">
<class name="com.sitinspring.domain.Privilege"
table="Privilege_TB">
<id name="id" column="ID" >
<generator class="uuid.hex"/>
</id>
<property name="userId" column="userId" />
<property name="privilegeLevel" column="privilegeLevel" />
</class>
</hibernate-mapping>
一对多的表数据
多对?/strong>
多对多关p?是指两个cȝ互拥有对方的集合,如文章和标签两个c?一文章可能有多个标签,一个标{֏能对应多文?要实现这U关p需要一个中间表的辅?
cM码如?
public class Article{
private String id;
private String name;
private Set<Tag> tags = new HashSet<Tag>();
}
public class Tag{
private String id;
private String name;
private Set<Article> articles = new HashSet<Article>();
}
多对多的映射文g
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.hibernate.auction">
<class name="com.sitinspring.domain.Article" table="ARTICLE_TB">
<id name="id" column="ID" >
<generator class="uuid.hex"/>
</id>
<property name="name" column="NAME" />
<set name="tags" table="ARTICLETAG_TB" cascade="all" lazy="false">
<key column="ARTICLEID" />
<many-to-many column="TAGID" class="com.sitinspring.domain.Tag" />
</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">
<hibernate-mapping package="org.hibernate.auction">
<class name="com.sitinspring.domain.Tag" table="TAG_TB">
<id name="id" column="ID" >
<generator class="uuid.hex"/>
</id>
<property name="name" column="NAME" />
<set name="articles" table="ARTICLETAG_TB" cascade="all" lazy="false">
<key column="TAGID" />
<many-to-many column="ARTICLEID" class="com.sitinspring.domain.Article" />
</set>
</class>
</hibernate-mapping>
多对多的表数?/strong>
源码下蝲Q?br />
http://m.tkk7.com/Files/junglesong/HibernateMapping20080430203526.rar
Hibernate中的Criteria API提供了另一U查询持久化的方法。它让你能够使用单的API动态的构徏查询Q它灉|的特性通常用于搜烦条g的数量可变的情况?br /> Criteria查询之所以灵zL因ؓ它可以借助Java语言,在Java的帮助下它拥有超HQL的功能。Criteria查询也是Hibernate竭力推荐的一U面向对象的查询方式?br /> Criteria查询的缺点在于只能检索完整的对象Q不支持l计函数Q它本n的API也抬高了一定的学习坡度?/p>
Criteria查询CZ代码
Session session=HibernateUtil.getSession();
Criteria criteria=session.createCriteria(User.class);
// 条g一Q名UC兛_?br />
criteria.add(Restrictions.like("name", "?"));
// 条g二:email出现在数l中
String[] arr={"1@2.3","2@2.3","3@2.3"};
criteria.add(Restrictions.in("email", arr));
// 条g三:password{于一
criteria.add(Restrictions.eq("password", "1"));
// 排序条gQ按d旉升序
criteria.addOrder(Order.asc("lastLoginTime"));
List<User> users=(List<User>)criteria.list();
System.out.println("q回的User实例Cؓ"+users.size());
for(User user:users){
System.out.println(user);
}
HibernateUtil.closeSession(session);
Criteria查询实际产生的SQL语句
select
this_.ID as ID0_0_,
this_.name as name0_0_,
this_.pswd as pswd0_0_,
this_.email as email0_0_,
this_.lastLoginTime as lastLogi5_0_0_,
this_.lastLoginIp as lastLogi6_0_0_
from
USERTABLE_OKB this_
where
this_.name like '?'
and this_.email in (
'1@2.3', '2@2.3', '3@2.3'
)
and this_.pswd='1'
order by
this_.lastLoginTime asc
注:参数是手工加上的?br />
Hibernate中不使用SQL而是有自q面向对象查询语言,该语a名ؓHibernate查询语言(Hibernate Query Language).HQL被有意设计成cMSQL,q样开发h员可以利用已有的SQL知识,降低学习坡度.它支持常用的SQLҎ(gu)?q些Ҏ(gu)被装成面向对象的查询语言,从某U意义上来说,由HQL是面向对象的,因此比SQL更容易编?
本文逐渐介绍HQL的特?
查询数据库中所有实?/strong>
要得到数据库中所有实?HQL写ؓ”from 对象?#8221;卛_,不需要select子句,当然更不需要Where子句.代码如右.
Query query=session.createQuery("from User");
List<User> users=(List<User>)query.list();
for(User user:users){
System.out.println(user);
}
限制q回的实例数
讄查询的maxResults属性可限制q回的实?记录)?代码如右:
Query query=session.createQuery("from User order by name");
query.setMaxResults(5);
List<User> users=(List<User>)query.list();
System.out.println("q回的User实例Cؓ"+users.size());
for(User user:users){
System.out.println(user);
}
分页查询
分页是Web开发的常见N,每种数据库都有自q定的分页Ҏ(gu),从简单到复杂都有.在Hibernate中分问题可以通过讄firstResult和maxResultL的解?
代码如右:
Query query=session.createQuery("from User order by name");
query.setFirstResult(3);
query.setMaxResults(5);
List<User> users=(List<User>)query.list();
System.out.println("q回的User实例Cؓ"+users.size());
for(User user:users){
System.out.println(user);
}
条g查询
条g查询只要增加Where条g卛_.
代码如右:
Hibernate中条件查询的实现方式有多U?q种方式的优点在于能昄完整的SQL语句(包括参数)如下.
select
user0_.ID as ID0_,
user0_.name as name0_,
user0_.pswd as pswd0_,
user0_.email as email0_,
user0_.lastLoginTime as lastLogi5_0_,
user0_.lastLoginIp as lastLogi6_0_
from
USERTABLE_OKB user0_
where
user0_.name like '?'
public static void fetchByName(String prefix){
Session session=HibernateUtil.getSession();
Query query=session.createQuery("from User where name like'"+prefix+"%'");
List<User> users=(List<User>)query.list();
System.out.println("q回的User实例Cؓ"+users.size());
for(User user:users){
System.out.println(user);
}
HibernateUtil.closeSession(session);
}
位置参数条g查询
HQL中也可以象jdbc中PreparedStatement一样ؓSQL讑֮参数,但不同的是下标从0开?
代码如右:
public static void fetchByPos(String prefix){
Session session=HibernateUtil.getSession();
Query query=session.createQuery("from User where name=?");
// 注意下标是从0开?和jdbc中PreparedStatement?开始不?br />
query.setParameter(0, prefix);
List<User> users=(List<User>)query.list();
System.out.println("q回的User实例Cؓ"+users.size());
for(User user:users){
System.out.println(user);
}
HibernateUtil.closeSession(session);
}
命名参数条g查询
使用位置参数条g查询最大的不便在于下标?号位|的对应?如果参数较多Ҏ(gu)D错误.q时采用命名参数条g查询更好.
使用命名参数时无需知道每个参数的烦引位|?q样可以节省填充查询参数的旉.
如果有一个命名参数出现多?那在每个地方都会讄?
public static void fetchByNamedParam(){
Session session=HibernateUtil.getSession();
Query query=session.createQuery("from User where name=:name");
query.setParameter("name", "李白");
List<User> users=(List<User>)query.list();
System.out.println("q回的User实例Cؓ"+users.size());
for(User user:users){
System.out.println(user);
}
HibernateUtil.closeSession(session);
}
命名查询
命名查询是嵌在XML映射文g中的查询。通常Q将l定对象的所有查询都攑֜同一文g中,q种方式可ɾl护相对Ҏ(gu)些。命名查询语句写在映定义文件的最后面?/p>
执行代码如下Q?br /> Session session=HibernateUtil.getSession();
Query query=session.getNamedQuery("user.sql");
List<User> users=(List<User>)query.list();
System.out.println("q回的User实例Cؓ"+users.size());
for(User user:users){
System.out.println(user);
}
HibernateUtil.closeSession(session);
映射文g节选:
<hibernate-mapping package="org.hibernate.auction">
<class name="com.sitinspring.domain.User"
table="USERTABLE_OKB" lazy="false">
<id name="id" column="ID" >
<generator class="uuid.hex"/>
</id>
<property name="name" column="name" />
<property name="password" column="pswd" />
<property name="email" column="email" />
<property name="lastLoginTime" column="lastLoginTime" />
<property name="lastLoginIp" column="lastLoginIp" />
</class>
<query name="user.sql">
<![CDATA[from User where email='2@2.3']]>
</query>
</hibernate-mapping>
Configurationc?/strong>
Configurationcd动Hibernate的运行环境部分,用于加蝲映射文g以及为它们创Z个SessionFacotry。完成这两项功能后,可丢弃ConfigurationcR?/p>
// 从hibernate.cfg.xml创徏SessionFactory CZ
sessionFactory = new Configuration().configure()
.buildSessionFactory();
SessionFactoryc?/strong>
Hibernate中Session表示到数据库的连接(不止于此Q,而SessionFactory接口提供Sessioncȝ实例?br /> SessionFactory实例是线E安全的Q通常在整个应用程序中׃n?br /> 从Configuration创徏SessionFacotry的代码如叟?/p>
// 从hibernate.cfg.xml创徏SessionFactory CZ
SessionFactory sessionFactory = new Configuration().configure()
.buildSessionFactory();
Sessionc?/strong>
Session表示到数据库的连接,sessioncȝ实例是到Hibernate框架的主要接口,使你能够持久化对象,查询持久化以及将持久化对象{换ؓ临时对象?br /> Session实例不是U程安全的,只能其用于应用中的事务和工作单元?br /> 创徏Session实例的代码如叻I
SessionFactory sessionFactory = new Configuration().configure()
.buildSessionFactory();
Session session=sessionFactory.openSession();
保存一个对?/strong>
用Hibernate持久化一个时对象也是它保存在Session实例中:
对user实例调用saveӞ给该实例分配一个生成的ID|q持久化该实例,在此之前实例的id是nullQ之后具体的idq成器{略军_Q如果生成器cd是assigndQHibernate不会给其设|ID倹{?br />
FlushQ)Ҏ(gu)内存中的持久化对象同步到数据库。存储对象时QSession不会立即其写入数据库;相反Qsession大量数据库写操作加入队列,以最大限度的提高性能?/p>
User user=new User(“Andy”,22);
Session session=sessionFatory.openSession();
session.save(user);
session.flush();
session.close();
保存或更C个对?/strong>
Hibernate提供了一U便利的Ҏ(gu)用于在你不清楚实例对应的数据在数据库中的状态时保存或更C个对象,也就是说Q你不能定具体是要保存saveq是更新updateQ只能确定需要把对象同步到数据库中。这个方法就是saveOrUpdate?br /> Hibernate在持久化时会查看实例的id属性,如果其ؓnull则判断此对象是时的Q在数据库中找不到对应的实例Q其后选择保存q个对象Q而不为空时则意味着对象已经持久化,应该在数据库中更新该对象Q而不是将其插入?/p>
User user=。。?
Session session=sessionFatory.openSession();
session.saveOrUpdate(user);
Session.flush();
session.close();
删除一个对?/strong>
从数据库删除一个对象用session的deleteҎ(gu)Q执行删除操作后Q对象实例依然存在,但数据库中对应的记录已经被删除?/p>
User user=。。?
Session session=sessionFatory.openSession();
session.delete(user);
session.flush();
session.close();
以ID从数据库中取得一个对?/strong>
如果已经知道一个对象的idQ需要从数据库中取得它,可以使用Session的loadҎ(gu)来返回它。代码如?
注意此放在id对应的记录不存在时会抛出一个HibernateException异常Q它是一个非查性异常。对此的正确处理是捕莯个异常ƈq回一个null?br />
使用此想法如果采用默认的懒惰加蝲会导致异常,Ҏ(gu)最单的解决Ҏ(gu)是把默认的懒惰加载属性修改ؓfalse。如叻I
User user=(User)session.load(User.class,"008");
session.close();
-----------------------------------------------
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.hibernate.auction">
<class name="com.sitinspring.domain.User"
table="USERTABLE_OKB" lazy="false">
<id name="id" column="ID" >
<generator class="uuid.hex"/>
</id>
。。。?br />
</class>
</hibernate-mapping>
索一批对?/strong>
索一批对象需要用HQLQsession接口允许你创建Query对象以检索持久化对象QHQL是面向对象的Q你需要针对类和属性来书写你的HQL而不是表和字D名?br />
从数据库中查询所有用户对象如下:
Query query=session.createQuery(“from User”);// 注意q里User是类名,from前没有select?br />
List<User> users=(List<User>)query.list();
从数据库中查询名?#8220;Andy”的用户如下:
String name=“Andy”;
Query query=session.createQuery(“from User where name=‘”+name+”’”);
List<User> users=(List<User>)query.list();
以上Ҏ(gu)cM于Statement的写法,你还可以如下书写Q?br />
Query query=session.createQuery("from User user where user.name = :name");
query.setString("name", “Andy");
List<User> users=(List<User>)query.list();
映射文g也称映射文档,用于向Hibernate提供关于对象持久化到关pL据库中的信息.
持久化对象的映射定义可全部存储在同一个映文件中,也可每个对象的映射定义存储在独立的文g?后一U方法较?因ؓ大量持久化cȝ映射定义存储在一个文件中比较ȝ,采用每个cM个文件的Ҏ(gu)来组l映文?使用多个映射文gq有一个优?如果所有映定义都存储C个文件中,难以调试和隔离特定cȝ映射定义错误.
映射文g的命名规则是,使用持久化类的类?q用扩展名hbm.xml.
映射文g需要在hibernate.cfg.xml中注?最好与领域对象cL在同一目录?q样修改h很方?
领域对象和类
public class User{
// ID
private String id;
// 名称
private String name;
// 密码
private String password;
// 邮g
private String email;
// 上次d旉
private String lastLoginTime;
// 上次dip
private String lastLoginIp;
public User(String name,String password,String email){
this.name=name;
this.password=password;
this.email=email;
}
}
<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping package="org.hibernate.auction">
<class name="com.sitinspring.domain.User"
table="USERTABLE_OKB" lazy="false">
<id name="id" column="ID" >
<generator class="uuid.hex"/>
</id>
<property name="name" column="name" />
<property name="password" column="pswd" />
<property name="email" column="email" />
<property name="lastLoginTime" column="lastLoginTime" />
<property name="lastLoginIp" column="lastLoginIp" />
</class></hibernate-mapping>
hibernate.cfg.xml中的映射文g讄
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory name="java:comp/env/hibernate/SessionFactory">
<!-- JNDI数据源设|?-->
<property name="connection.datasource">
java:comp/env/jdbc/myoracle
</property>
<!-- SQL方言Qorg.hibernate.dialect.OracleDialect适合所有Oracle数据?-->
<property name="dialect">
org.hibernate.dialect.OracleDialect
</property>
<!-- 昄SQL语句 -->
<property name="show_sql">true</property>
<!-- SQL语句整Ş -->
<property name="format_sql">true</property>
<!-- 启动时创.q个选项在第一ơ启动程序时攑ּ,以后切记关闭 -->
<!-- <property name="hbm2ddl.auto">create</property> -->
<!-- 持久化类的映文?-->
<mapping resource="com/sitinspring/domain/User.hbm.xml" />
<mapping resource="com/sitinspring/domain/Privilege.hbm.xml" />
<mapping resource="com/sitinspring/domain/Article.hbm.xml" />
<mapping resource="com/sitinspring/domain/Record.hbm.xml" />
</session-factory>
</hibernate-configuration>
映射文g物理位置CZ
映射文g的基本结?/strong>
映射定义以hibernate-mapping元素开? package属性设|映中非限定类名的默认?讄q个属性后,对于映射文g中列出的其它持久化类,只需l出cd卛_.要引用指定包外的持久化类,必须在映文件中提供全限定类?
在hibernate-mapping标签之后是class标签.class标签开始指定持久化cȝ映射定义.table属性指定用于存储对象状态的关系?class元素有很多属?下面逐个介绍.
ID
Id元素描述了持久化cȝȝ以及他们的值如何生?每个持久化类必须有一个ID元素,它声明了关系表的ȝ.如右:
Name属性指定了持久化类中用于保存主码值的属?该元素表?UsercM有一个名为id的属?如果ȝ字段与对象属性不?则可以用column属?
<id name="id" column="ID" >
<generator class="uuid.hex"/>
</id>
生成?/strong>
生成器创建持久化cȝȝ?Hibernate提供了多个生成器实现,它们采用了不同的Ҏ(gu)来创Z码?有的是自增长式的,有点创徏十六q制字符? q可以让外界生成q指定对象ID,另外q有一USelect生成器你那个从数据库触发器trigger索值来获得ȝ?
双使用了用一?28-bit的UUID法生成字符串类型的标识W, q在一个网l中是唯一的(使用了IP地址Q。UUID被编码ؓ一?2?6q制数字的字W串 .q对字段cd是字W串的id字段特别有效.UUID作ؓID字段主键是非常合适的Q比自动生成的longcdid方式要好?/p>
UUIDCZ
<id name="id" column="ID" >
<generator class="uuid.hex"/>
</id>
自动增长的id
<id name="id" column="ID" type="long">
<generator class="native"/>
</id>
属?/strong>
在映定义中,property元素与持久化对象的一个属性对?name表示对象的属性名,column表示对应表中的列(字段),type属性指定了属性的对象cd,如果type被忽略的?Hibernate用运行阶D反机制来判断cd.
<property name="name" column="name" />
<property name="password" column="pswd" />
<property name="email" column="email" />
<property name="lastLoginTime" column="lastLoginTime" />
<property name="lastLoginIp" column="lastLoginIp" />
在创建Hibernate目之前Q我们需要从|站获得最新的Hibernate版本。Hibernate主页是www.hibernate.orgQ找到其菜单中的downloadq接Q选择最新的Hibernate版本卛_。下载后其解开C个目录中?br /> 双是解开后的主要目录。其中最重要的是hibernate.jarQ它包含全部框架代码Qlib目录Q包括Hibernate的所有依赖库Qdoc目录Q包括JavDocs和参考文档?/p>
Hibernate的配|文?/strong>
Hibernate能够与从应用服务器(受控环境Q如TomcatQWeblogicQJBossQ到独立的应用程序(非受控环境,如独立应用程序)的各U环境和谐工作,q在一定程度上要归功于光|文件hibernate.cfg.xmlQ通过特定的设|Hibernatep与各U环境配合。右Ҏ(gu)hibernate.cfg.xml的一个示例?br /> 配置Hibernate的所有属性是一艰巨的dQ下面将依此介绍Hibernate部v用到的基本配置?/p>
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory name="java:comp/env/hibernate/SessionFactory">
<!-- JNDI数据源设|?-->
<property name="connection.datasource">
java:comp/env/jdbc/myoracle
</property>
<!-- SQL方言Qorg.hibernate.dialect.OracleDialect适合所有Oracle数据?-->
<property name="dialect">
org.hibernate.dialect.OracleDialect
</property>
<!-- 昄SQL语句 -->
<property name="show_sql">true</property>
<!-- SQL语句整Ş -->
<property name="format_sql">true</property>
<!-- 启动时创.q个选项在第一ơ启动程序时攑ּ,以后切记关闭 -->
<!-- <property name="hbm2ddl.auto">create</property> -->
<!-- 持久化类的配|文?-->
<mapping resource="com/sitinspring/domain/User.hbm.xml" />
<mapping resource="com/sitinspring/domain/Privilege.hbm.xml" />
<mapping resource="com/sitinspring/domain/Article.hbm.xml" />
<mapping resource="com/sitinspring/domain/Record.hbm.xml" />
</session-factory>
</hibernate-configuration>
使用Hibernate理的JDBCq接
双配置文g中的Database connection settings 部分制定了Hibernate理的JDBCq接Q?q在非受控环境如桌面应用E序中很常见?br />
其中各项属性ؓQ?br />
connection.driver_classQ用于特定数据库的JDBCq接c?br />
connection.urlQ数据库的完整JDBC URL
connection.usernameQ用于连接到数据库的用户?br />
connection.passwordQ用户密?/p>
q种Ҏ(gu)可用于非受控环境和基本测试,但不宜在生环境中用?/p>
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">org.hsqldb.jdbcDriver</property>
<property name="connection.url">jdbc:hsqldb:hsql://localhost</property>
<property name="connection.username">sa</property>
<property name="connection.password"></property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.HSQLDialect</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
。。。。。。。?/p>
</session-factory>
</hibernate-configuration>
使用JNDI 数据?/strong>
在受控环境中Q我们可以用容器提供的数据源,q将使数据库讉K更加快捷Q右边就是用Tomcat提供的数据源的配|部分?/p>
附:Server.Xml中的数据源设|?/p>
<Context path="/MyTodoes" reloadable="true" docBase="E:\Program\Programs\MyTodoes" workDir="E:\Program\Programs\MyTodoes\work" >
<Resource name="jdbc/myoracle" auth="Container"
type="javax.sql.DataSource" driverClassName="oracle.jdbc.OracleDriver"
url="jdbc:oracle:thin:@192.168.104.173:1521:orcl"
username="hy" password="123456" maxActive="20" maxIdle="10"
maxWait="-1"/>
</Context>
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory name="java:comp/env/hibernate/SessionFactory">
<!-- JNDI数据源设|?-->
<property name="connection.datasource">
java:comp/env/jdbc/myoracle
</property>
<!-- SQL方言Qorg.hibernate.dialect.OracleDialect适合所有Oracle数据?-->
<property name="dialect">
org.hibernate.dialect.OracleDialect
</property>
</hibernate-configuration>
数据库方a
Dialect属性能告知Hibernate执行特定的操作如分页旉要用那USQL方言Q如MySql的分|案和Oracle的大相径庭,如设|错误或没有讄一定会D问题?/p>
附录Q常见的数据库方a
DB2 Qorg.hibernate.dialect.DB2Dialect
MySQL Qorg.hibernate.dialect.MySQLDialect
Oracle (any version) Qorg.hibernate.dialect.OracleDialect
Oracle 9i/10g Qorg.hibernate.dialect.Oracle9Dialect
Microsoft SQL Server Qorg.hibernate.dialect.SQLServerDialect
Sybase Anywhere Qorg.hibernate.dialect.SybaseAnywhereDialect
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory name="java:comp/env/hibernate/SessionFactory">
<!-- JNDI数据源设|?-->
<property name="connection.datasource">
java:comp/env/jdbc/myoracle
</property>
<!-- SQL方言Qorg.hibernate.dialect.OracleDialect适合所有Oracle数据?-->
<property name="dialect">
org.hibernate.dialect.OracleDialect
</property>
<!-- 昄SQL语句 -->
<property name="show_sql">true</property>
<!-- SQL语句整Ş -->
<property name="format_sql">true</property>
</hibernate-configuration>
其它属?/strong>
show_sqlQ它可以在程序运行过E中昄出真正执行的SQL语句来,这个属性始l打开Q它?yu)有益于错误诊断?/p>
format_sqlQ将q个属性设|ؓtrue能将输出的SQL语句整理成规范的形状Q更方便用于查看SQL语句?/p>
hbm2ddl.autoQ将其设|ؓcreate能在E序启动是根据类映射文g的定义创建实体对象对应的表,而不需要手动去Q这在程序初ơ安装时很方ѝ?br /> 如果表已l创建ƈ有数据,切记关闭q个属性,否则在创时也会清除掉原有的数据,q也怼D很严重的后果?br /> 从后果可能带来的影响来考虑Q在用户处安装完一ơ后应该删除掉q个节点
<hibernate-configuration>
<session-factory name="java:comp/env/hibernate/SessionFactory">
。。。。。?/p>
<!-- 昄SQL语句 -->
<property name="show_sql">true</property>
<!-- SQL语句整Ş -->
<property name="format_sql">true</property>
<!-- 启动时创.q个选项在第一ơ启动程序时攑ּ,以后切记关闭 -->
<!-- <property name="hbm2ddl.auto">create</property> -->
。。。。。?br />
</hibernate-configuration>
映射定义
在hibernate.cfg.xml中,q有一个重要部分就是映定义,q些文g用于向Hibernate提供关于对象持久化到关pL据库的信息?br /> 一般来_领域层有一个领域对象就有一个映文Ӟ它们放在同一目录QdomainQ下以便查阅和修改,映射文g的命名规则是Q持久化cȝcd+.hbm.xml
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory name="java:comp/env/hibernate/SessionFactory">
<!-- JNDI数据源设|?-->
<property name="connection.datasource">
java:comp/env/jdbc/myoracle
</property>
。。。。。?br />
<!-- 持久化类的配|文?-->
<mapping resource="com/sitinspring/domain/User.hbm.xml" />
<mapping resource="com/sitinspring/domain/Privilege.hbm.xml" />
<mapping resource="com/sitinspring/domain/Article.hbm.xml" />
<mapping resource="com/sitinspring/domain/Record.hbm.xml" />
</session-factory>
</hibernate-configuration>
本文假定读者已l熟知以下知?/p>
能够熟练使用JDBC创徏Java应用E序Q?br /> 创徏q以数据库ؓ中心的应?br /> 理解基本的关pȝ论和l构化查询语aSQL QStrutured Query LanguageQ?/p>
Hibernate
Hibernate是一个用于开发Java应用的对?关系映射框架。它通过在数据库中ؓ开发h员存储应用对象,在数据库和应用之间提供了一座桥梁,开发h员不必编写大量的代码来存储和索对象,省下来的_֊更多的放在问题本w上?/p>
持久化与关系数据?/strong>
持久化的常见定义Q数据的存?gu)zL间超q创数据的进E的存活旉。数据持久化后可以重新获得它Q如果外界进E没有修改它Q它?yu)与持久化之前相同。对于一般应用来_持久化指的是数据存储在关系数据库中?br /> 关系数据库是为管理数据而设计的Q它在存储数据方面很行Q这主要归功于易于用SQL来创建和讉K?br /> 关系数据库用的模型被称为关pL型,它用二l表来表C数据。这U数据逻辑视图表示了用户如何看待包含的数据。表可以通过ȝ和外码相互关联。主码唯一的标识了表中的一行,而外码是另一个表中的ȝ?/p>
对象/关系L不匹?/strong>
关系数据库是为管理数据设计的Q它适合于管理数据。然而,在面向对象的应用中,对象持久化为关pL型可能会遇到问题。这个问题的Ҏ(gu)是因为关pL据库理数据Q而面向对象的应用是ؓ业务问题建模而设计的。由于这两种目的不同Q要使这两个模型协同工作可能h挑战性。这个问题被UCؓ 对象/关系L不匹配(Object/relational impedance mismatchQ或UCؓL不匹?/p>
L不匹配的几个典型斚w
在应用中L实现的对象相同或相等Q这L关系在关pL据库中不存在?br /> 在面向对象语a的一Ҏ(gu)心特性是l承Q承很重要Q因为它允许创徏问题的精模型,同时可以在层ơ结构中自上而下的共享属性和行ؓ。而关pL据库不支持承的概念?br /> 对象之间可以L的实C对一Q一对多和多对多的关联关p,而数据库q不理解q些Q它只知道外码指向主码?/p>
对象/关系映射
前页列D了一些阻抗不匚w的问题,当然开发h员是可以解决q些问题Q但q一q程q不Ҏ(gu)。对?关系映射QObject/Relational MappingQ就是ؓ解决q些问题而开发的?br /> ORM在对象模型和关系模型之间架v了一座桥梁,让应用能够直接持久化对象Q而不要求在对象和关系之间q行转换。Hibernate是ORM工具中最成功的一U。它的主要优Ҏ(gu)单,灉|Q功能完备和高效?/p>
Hibernate的优点之一Q简?/strong>
Hibernate不像有些持久化方案那样需要很多的cd配置属性,它只需要一个运行阶D配|文件已lؓ每个要持久化的应用对象指定一个XML格式的映文件?br /> 映射文g可以很短Q让框架军_映射的其它内容,也可以通过制定额外的属性,如属性的可选列名,向框架提供更多信息。如叛_是一个映文档的CZ?/p>
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.hibernate.auction">
<class name="com.sitinspring.domain.User"
table="USERTABLE_OKB" lazy="false">
<id name="id" column="ID" >
<generator class="uuid.hex"/>
</id>
<property name="name" column="name" />
<property name="password" column="pswd" />
<property name="email" column="email" />
<property name="lastLoginTime" column="lastLoginTime" />
<property name="lastLoginIp" column="lastLoginIp" />
</class>
</hibernate-mapping>
Hibernate的优点之二:功能完备
Hibernate支持所有的面向对象Ҏ(gu),包括l承Q自定义对象cd和集合。它可以让你创徏模型时不必考虑持久层的局限性?br /> Hibernate提供了一个名为HQL的查询语aQ它与SQL非常怼Q只是用对象属性名代替了表的列。很多通过SQL实现的常用功能都能用HQL实现?/p>
Hibernate的优点之三:高效
Hibernate使用懒惰加蝲提高了性能Q在Hibernateq不在加载父对象时就加蝲对象集合Q而只在应用需要访问时才生成。这避免了索不必要的对象而媄响性能?br /> Hibernate允许索主对象旉择性的止索关联的对象Q这也是一Ҏ(gu)善性能的特性?br /> 对象~存在提高应用性能斚w也发挥了很大的作用。Hibernate支持各种开源和~存产品Q可为持久化cL持久化对象集合启用缓存?/p>
ȝ
在同一性,l承和关联三斚wQ对象模型和关系模型存在着L不匹配,q是众多ORM框架致力解决的问题,hibernate是这些方案中最成功的一个,它的主要优点是简单,灉|Q功能完备和高效?br />
使用Hibernate不要求领域对象实现特别的接口或用应用服务器Q它支持集合Q承,自定义数据类型,q携带一U强大的查询语言HQLQ能减少很多持久化方面的工作量,使程序员能把更多_֊转移到问题本w上来?/p>