欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
無(wú)需容器的對象關(guān)系映射

2004 年 4 月 01 日

當您自以為已經(jīng)了解了所有開(kāi)發(fā)工具時(shí),肯定又會(huì )冒出一個(gè)新的工具。在本文中,developerWorks 的固定撰稿人 Rick Hightower 用一個(gè)真實(shí)世界的例子向您介紹兩個(gè)最激動(dòng)人心的企業(yè)新技術(shù)。Hibernate 是一個(gè)對象關(guān)系映射工具,而 Spring 是一個(gè) AOP 框架和 IOC 容器。Rick 介紹了如何結合這兩者,為企業(yè)應用程序構建一個(gè)事務(wù)持久層。

如果關(guān)心開(kāi)發(fā)人員的最新熱點(diǎn),那么您可能聽(tīng)說(shuō)過(guò) IOC (控制倒置,Inversion of Control)容器和 AOP (面向方面編程)。不過(guò),像許多開(kāi)發(fā)人員一樣,您可能不清楚在自己的開(kāi)發(fā)工作中如何使用這些技術(shù)。在本文中,通過(guò)具體介紹使用 Hibernate 和 Spring 在企業(yè)應用程序中構建一個(gè)事務(wù)持久層,您會(huì )認識到這些技術(shù)。

Hibernate 是 Java 平臺上的一種流行的、容易使用的開(kāi)放源代碼對象關(guān)系(OR)映射框架。Spring 是一個(gè) AOP 框架和 IOC 容器。這兩種技術(shù)一起提供了本文中介紹的開(kāi)發(fā)工作的基礎。將使用 Hibernate 把一些持久性對象映射到關(guān)系數據庫中,用 Spring 使 Hibernate 更容易使用并提供聲明性事務(wù)支持。由于為示例類(lèi)編寫(xiě)測試代碼時(shí)使用了 DbUnit,我還附帶介紹了一點(diǎn) TDD (測試驅動(dòng)的開(kāi)發(fā))的內容。

注意,本文假定讀者熟悉 Java 平臺上的企業(yè)開(kāi)發(fā),包括 JDBC、OR 映射內容、J2EE 設計模式如 DAO,以及聲明性事務(wù)支持,如 Enterprise JavaBean (EJB)技術(shù)所提供的事務(wù)支持。理解這里的討論不需要成為這些技術(shù)的專(zhuān)家,也不需要熟悉 AOP、IOC 或者 TDD,因為在本文中對這三者都做了介紹。

我將首先介紹兩種開(kāi)發(fā)技術(shù),然后分析例子。

Hibernate 簡(jiǎn)介

Hibernate 是 Java 平臺上的一種全功能的、開(kāi)放源代碼 OR 映射框架。Hibernate 在許多方面類(lèi)似于 EJB CMP CMR (容器管理的持久性/容器管理的關(guān)系)和 JDO(Java Data Objects)。與 JDO 不同,Hibernate 完全著(zhù)眼于關(guān)系數據庫的 OR 映射,并且包括比大多數商業(yè)產(chǎn)品更多的功能。大多數 EJB CMP CMR 解決方案使用代碼生成實(shí)現持久性代碼,而 JDO 使用字節碼修飾。與之相反,Hibernate 使用反射和運行時(shí)字節碼生成,使它對于最終用戶(hù)幾乎是透明的(以前 Hibernate 的實(shí)現只使用反射,它有助于調試,當前版本保留了這種選項)。

移植基于 Hibernate 的應用程序

如果應用程序必須在多個(gè) RDBMS 系統上運行 ,那么基于 Hibernate 的應用程序可以毫不費力地移植到 IBM DB2、MySQL、PostgreSQL、Sybase、Oracle、HypersonicSQL 和許多其他數據庫。我最近甚至將一個(gè)應用程序從 MySQL 移植到 Hibernate 沒(méi)有很好支持的 Firebird,而這種移植是很容易的。有關(guān)在 Postgres 和 MySQL 之間轉換的案例分析,請參閱 參考資料。

Hibernate 可以模擬繼承(有幾種方式)、關(guān)聯(lián)(一對一或者一對多、containment 和 aggregation)和 composition。我將在本文中討論每種關(guān)系類(lèi)型的幾個(gè)例子。

Hibernate 提供了一種稱(chēng)為 Hibernate Query Language (HQL) 的 查詢(xún)語(yǔ)言,它類(lèi)似于 JDO 的 JDOQL 和 EJB 的 EJB QL,盡管它更接近于前者。但是 Hibernate 沒(méi)有就此止步:它還可以進(jìn)行直接的 SQL 查詢(xún)和/或使用 object criteria很容易地在運行時(shí)構成查詢(xún)條件。在本文的例子中我將只使用 HQL。

與 EJB CMP CMR 不同,Hibernate 像 JDO 一樣可以在 J2EE 容器內部或者外部工作,這可以讓那些進(jìn)行 TDD 和敏捷開(kāi)發(fā)的人受益。



回頁(yè)首


Spring 簡(jiǎn)介

AOP 專(zhuān)家 Nicholas Lesiecki 第一次向我解釋 AOP 時(shí),他說(shuō)的我一個(gè)詞也沒(méi)理解,我覺(jué)得就像第一次考慮使用 IOC 容器的可能性時(shí)一樣。每一種技術(shù)的概念基礎本身就需要很好地消化,每一種技術(shù)所使用的各種各樣的縮寫(xiě)讓事情更糟了——特別是其中許多術(shù)語(yǔ)與我們已經(jīng)使用的根本不一樣了。

像許多技術(shù)一樣,理解這兩種技術(shù)的實(shí)際使用比學(xué)習理論更容易。經(jīng)過(guò)自己對 AOP 和 IOC 容器實(shí)現(即 XWork、PicoContainer 和 Spring)的分析,我發(fā)現這些技術(shù)可以幫助我獲得功能,而不會(huì )在多框架中添加基于代碼的依賴(lài)性。它們都將成為我后面開(kāi)發(fā)項目的一部分。

簡(jiǎn)單地說(shuō),AOP 讓開(kāi)發(fā)人員可以創(chuàng )建非行為性的關(guān)注點(diǎn),稱(chēng)為橫切關(guān)注點(diǎn),并將它們插入到應用程序代碼中。使用 AOP 后,公共服務(wù)(比如日志、持久性、事務(wù)等)就可以分解成方面并應用到域對象上,同時(shí)不會(huì )增加域對象的對象模型的復雜性。

關(guān)于 DbUnit

用新的框架開(kāi)發(fā)而不進(jìn)行單元測試,就像不帶保護網(wǎng)走鋼絲:當然可以這樣做,但是很可能會(huì )受傷。我選擇在有保護網(wǎng)的條件下開(kāi)發(fā),對我來(lái)說(shuō)這個(gè)保護網(wǎng)就是 TDD。在有 DbUnit 之前,對依賴(lài)于數據庫的代碼進(jìn)行測試是不太容易的。DbUnit 是 JUnit 的一個(gè)擴展,它提供了依賴(lài)于數據庫的單元測試的框架。我用 DbUnit 編寫(xiě)本文中示例類(lèi)的測試代碼。雖然在本文中沒(méi)有出現,不過(guò)在本文源代碼中提供了 DbUnit 代碼(請參閱 參考資料)。有關(guān) DbUnit 的介紹,請參閱 Philippe Girolami 的“ Control your test-environment with DbUnit and Anthill” ( developerWorks,2004 年 4 月)。

IOC 允許創(chuàng )建一個(gè)可以構造對象的應用環(huán)境,然后向這些對象傳遞它們的協(xié)作對象。正如單詞 倒置 所表明的,IOC 就像反過(guò)來(lái)的 JNDI。沒(méi)有使用一堆抽象工廠(chǎng)、服務(wù)定位器、單元素(singleton)和直接構造(straight construction),每一個(gè)對象都是用其協(xié)作對象構造的。因此是由容器管理協(xié)作對象(collaborator)。

Spring 既是一個(gè) AOP 框架、也是一個(gè) IOC 容器。我記得 Grady Booch 說(shuō)過(guò),對象最好的地方是可以替換它們,而 Spring 最好的地方是它有助于您替換它們。有了 Spring,只要用 JavaBean 屬性和配置文件加入依賴(lài)性(協(xié)作對象)。然后可以很容易地在需要時(shí)替換具有類(lèi)似接口的協(xié)作對象。

Spring 為 IOC 容器和 AOP 提供了很好的入口(on-ramp)。因此,不需要熟悉 AOP 就可以理解本文中的例子。所需要知道的就是將要用 AOP 為示例應用程序聲明式地添加事務(wù)支持,與使用 EJB 技術(shù)時(shí)的方式基本相同。要了解 IOC 容器、AOP 和 Spring 的更多內容,請參閱 參考資料。



回頁(yè)首


具體到業(yè)務(wù)

在本文的其余部分,所有的討論都將基于一個(gè)實(shí)際的例子。起點(diǎn)是一個(gè)企業(yè)應用程序,要為它實(shí)現一個(gè)事務(wù)持久層。持久層是一個(gè)對象關(guān)系數據庫,它包括像 User 、 User Group 、 RolesContactInfo 這些熟悉的抽象。

在深入到數據庫的要素——查詢(xún)和事務(wù)管理——之前,需要建立它的基礎:對象關(guān)系映射。我將用 Hibernate 設置它,并只使用一點(diǎn) Spring。



回頁(yè)首


用 Hibernate 進(jìn)行 OR 映射

Hibernate 使用 XML ( *.hbm.xml) 文件將 Java 類(lèi)映射到表,將 JavaBean 屬性映射到數據庫表。幸運的是,有一組 XDoclet 標簽支持 Hibernate 開(kāi)發(fā),這使得創(chuàng )建所需要的 *.hbm.xml 文件更容易了。清單 1 中的代碼將一個(gè) Java 類(lèi)映射到數據庫表。關(guān)于 XDoclet 標簽的更多內容,請參閱 參考資料。

清單 1. 將 Java 類(lèi)映射到 DB 表
                                [User.java]                        /**                        *                        @hibernate.class table="TBL_USER"                        * ..                        * ..                        * ...                        */                        public class User {                        private Long id = new Long(-1);                        private String email;                        private String password;                        .                        .                        .                        /**                        * @return                        *                        @hibernate.id column="PK_USER_ID"                        * 		unsaved-value="-1"                        *              generator-class="native"                         */                        public Long getId() {                        return id;                        }                        ...                        /**                        *                        @hibernate.property column="VC_EMAIL"                        * 			type="string"                        * 			update="false"                        * 			insert="true"                        * 			unique="true"                        * 			not-null="true"                        * 			length="82"                         * @return                        */                        public String getEmail() {                        return email;                        }                        /**                        *                        @hibernate.property column="VC_PASSWORD"                        * 			type="string"                        * 			update="false"                        * 			insert="true"                        * 			unique="true"                        * 			not-null="true"                        * 			length="20"                         * @return                        */                        public String getPassword() {                        return password;                        }                        ...                        ...                        ...                        }                        

可以看到, @hibernate.class table="TBL_USER" 標簽將 User 映射到 TBL_USER 表。 @hibernate.property column="VC_PASSWORD" 將 JavaBean 屬性 password 映射到 VC_PASSWORD 列。 @hibernate.id column="PK_USER_ID" 標簽聲明 id 屬性是主鍵,它將使用本機( generator-class="native" )數據庫機制生成鍵(例如,Oracle sequences 和 SQL Server Identity 鍵)。Hibernate 可以指定 generator-class="native" 以外的、其他可以想象的得到主鍵獲得策略,不過(guò)我更愿意使用 native。 typelength屬性用于從 Hibernate *.hbm.xml OR 映射文件生成表。這些 final 屬性是可選的,因為使用的可能不是 green-field 數據庫。在這個(gè)例子中,已經(jīng)有數據庫了,所以不需要額外的屬性。( green-field 應用程序是一個(gè)新的應用程序, green-field 數據是新應用程序的一個(gè)新數據庫。不會(huì )經(jīng)常開(kāi)發(fā)一個(gè)全新的應用程序,不過(guò)偶爾有一兩次也不錯)。

看過(guò)了表如何映射到類(lèi)以及列如何映射到 JavaBean 屬性,該使用 Hibernate 在 OR 數據庫中設置一些關(guān)系了。

設置對象關(guān)系

在本節中,我將只觸及 Hibernate 提供的設置對象間關(guān)系的選項的一小部分。首先設置像 User 、 User Group 、 RolesContactInfo 這些類(lèi)之間的關(guān)系。其中一些關(guān)系如圖 1 所示,這是數據庫的驗證對象模型。


圖 1. 關(guān)系的圖示

如您所見(jiàn),在上述抽象中存在各種各樣的關(guān)系。 UserContactInfo 有一對一關(guān)系。 ContactInfo 的生命周期與 User 相同(用數據庫的術(shù)語(yǔ),UML 中的組成 aka 級聯(lián)刪除)。如果刪除 User ,則相應的 ContactInfo 也會(huì )刪除。在 User s 與 Role s 之間存在多對多關(guān)系(即與獨立生命周期相關(guān)聯(lián))。在 Group s 與 User s 之間存在一對多關(guān)系,因為組有許多用戶(hù)。用戶(hù)可以存在于組外,即是 aggregation 而不是 composition (用數據庫的說(shuō)法,在 Group s 和 Users 之間沒(méi)有級聯(lián)刪除關(guān)系)。此外, UserEmployee 有子類(lèi)關(guān)系,就是說(shuō), Employee 的類(lèi)型為 User 。表 1 顯示了如何用 XDoclet 標簽創(chuàng )建一些不同類(lèi)型的對象關(guān)系。

表 1. 用 XDoclet 創(chuàng )建對象關(guān)系
關(guān)系 Java/XDoclet SQL DDL(由 Hibernate Schema Export 生成的 MySQL)
組包含用戶(hù)

一對多

Aggregation

雙向
(Group<-->Users)

[Group.java]
/**
*
* @return
*
* @hibernate.bag name="users"
* cascade="save-update"
* lazy="true"
* inverse="true"
*
* @hibernate.collection-key
* column="FK_GROUP_ID"
*
* @hibernate.collection-one-to-many
* class="net.sf.hibernateExamples.User"
*/
public List getUsers() {
return users;
}

[User.java]
/**
* @hibernate.many-to-one
* column="FK_GROUP_ID"
* class="net.sf.hibernateExamples.Group"
*/
public Group getGroup() {
return group;
}


create table TBL_USER (
PK_USER_ID BIGINT NOT NULL AUTO_INCREMENT,
USER_TYPE VARCHAR(255) not null,
FK_GROUP_ID BIGINT,
VC_EMAIL VARCHAR(82) not null unique,
primary key (PK_USER_ID)
)


create table TBL_GROUP (
PK_GROUP_ID BIGINT NOT NULL AUTO_INCREMENT,
VC_DESCRIPTION VARCHAR(255),
VC_NAME VARCHAR(40) unique,
primary key (PK_GROUP_ID)
)

alter table TBL_USER add index (FK_GROUP_ID),
add constraint FK_111 foreign key (FK_GROUP_ID)
references TBL_GROUP (PK_GROUP_ID)

用戶(hù)有聯(lián)系信息

一對一

Composition
單向
(User-->ContactInfo)

[User.java]
/**
* @return
*
* @hibernate.one-to-one cascade="all"
*
*/
public ContactInfo getContactInfo() {
return contactInfo;
}

[ContactInfo.java]
(Nothing to see here. Unidirectional!)
create table TBL_USER (
PK_USER_ID BIGINT NOT NULL AUTO_INCREMENT,
USER_TYPE VARCHAR(255) not null,
FK_GROUP_ID BIGINT,
VC_EMAIL VARCHAR(82) not null unique,
primary key (PK_USER_ID)
)

create table TBL_CONTACT_INFO (
PK_CONTACT_INFO_ID BIGINT not null,
...
...
...
primary key (PK_CONTACT_INFO_ID)
)

用戶(hù)與角色關(guān)聯(lián)

多對多

Association

單向
(Users-->Roles)

[User.java]
/**
* @return
* @hibernate.bag
* table="TBL_JOIN_USER_ROLE"
* cascade="all"
* inverse="true"
*
* @hibernate.collection-key
* column="FK_USER_ID"
*
* @hibernate.collection-many-to-many
* class="net.sf.hibernateExamples.Role"
* column="FK_ROLE_ID"
*
*/
public List getRoles() {
return roles;
}

[Role.java]
Nothing to see here. Unidirectional!
create table TBL_ROLE (
PK_ROLE_ID BIGINT NOT NULL AUTO_INCREMENT,
VC_DESCRIPTION VARCHAR(200),
VC_NAME VARCHAR(20),
primary key (PK_ROLE_ID)
)

create table TBL_USER (
PK_USER_ID BIGINT NOT NULL AUTO_INCREMENT,
USER_TYPE VARCHAR(255) not null,
FK_GROUP_ID BIGINT,
VC_EMAIL VARCHAR(82) not null unique,
primary key (PK_USER_ID)
)

create table TBL_JOIN_USER_ROLE (
FK_USER_ID BIGINT not null,
FK_ROLE_ID BIGINT not null
)

雇員是用戶(hù)

Inheritance

用戶(hù)

雇員

[User.java]
/**
* @hibernate.class table="TBL_USER"
* discriminator-value="2"
* @hibernate.discriminator column="USER_TYPE"
*
...
...
...
*/
public class User {

[Employee.java]
/**
* @hibernate.subclass discriminator-value = "1"
*/
public class Employee extends User{

create table TBL_USER (
PK_USER_ID BIGINT NOT NULL AUTO_INCREMENT,
USER_TYPE VARCHAR(255) not null,
FK_GROUP_ID BIGINT,
VC_EMAIL VARCHAR(82) not null unique,
primary key (PK_USER_ID)
)

要了解在 Hibernate 中設置對象關(guān)系的更多內容,請參閱 參考資料。



回頁(yè)首


Hibernate 中的查詢(xún)

Hibernate 有三種類(lèi)型的查詢(xún):

  • Criteria, object composition
  • SQL
  • HQL

在下面的例子中將只使用 HQL。本節還要使用 Spring,用它的 AOP-driven HibernateTemplate 簡(jiǎn)化 Hibernate 會(huì )話(huà)的處理。在本節將開(kāi)發(fā)一個(gè) DAO(Data Access Object)。要了解更多關(guān)于 DAO 的內容,請參閱 參考資料。

清單 2 展示了兩個(gè)方法:一個(gè)使用 HQL 查詢(xún)的組查詢(xún),另一個(gè)是后面接一個(gè)操作的組查詢(xún)。注意在第二個(gè)方法中,Spring HibernateTemplate 是如何簡(jiǎn)化會(huì )話(huà)管理的。

清單 2. 使用查詢(xún)
                        import net.sf.hibernate.HibernateException;                        import net.sf.hibernate.Session;                        import net.sf.hibernate.Query;                        import org.springframework.orm.hibernate.HibernateCallback;                        import org.springframework.orm.hibernate.support.HibernateDaoSupport;                        /**                        * @author Richard Hightower                        * ArcMind Inc. http://www.arc-mind.com                        */                        public class UserDAO extends HibernateDaoSupport{                        .                        .                        .                        /**                        * Demonstrates looking up a group with a HQL query                        * @param email                        * @return                        */                        public Group findGroupByName(String name) {                        return (Group) getHibernateTemplate().find("from Group g where g.name=?",name).get(0);                        }                        /**                        * Demonstrates looking up a group and forcing it to populate users (relationship was lazy)                        * @param email                        * @return                        */                        public Group findPopulatedGroupByName(final String name) {                        HibernateCallback callback = new HibernateCallback(){                        public Object doInHibernate(Session session) throws HibernateException, SQLException {                        Group group =null;                        String query = "from Group g where g.name=?";                        Query queryObject = getHibernateTemplate().createQuery(session, query);                        queryObject.setParameter(0, name);                        group = (Group) queryObject.list().get(0);                        group.getUsers().size();//force load                        return group;                        }                        };                        return (Group) getHibernateTemplate().execute(callback);                        }                        .                        .                        .                        }                        

您可能會(huì )注意到第二個(gè)方法比第一個(gè)方法復雜得多,因為它強迫加載 users 集合。因為 Group->Users 之間的關(guān)系設置為 lazy initialize(即表 2 中 lazy="true" ),組對象需要一個(gè)活躍的會(huì )話(huà)以查詢(xún)用戶(hù)。在定義 GroupUser s 之間關(guān)系時(shí)設置這個(gè)屬性為 lazy="false" ,則不需要第二個(gè)方法。在這種情況下,可能使用第一種方法 ( findGroupByName ) 列出組,用第二種方法( findPopulatedGroupByName )查看組細節。



回頁(yè)首


Spring IOC 和 Hibernate

使用 Spring 時(shí),在 J2EE 容器內和容器外工作一樣容易。比如在最近的項目中,我在 Eclipse 中,使用 HSQL 和本地數據庫對使用 Hibernate 事務(wù)管理器的 Hypersonic SQL 數據庫進(jìn)行持久性單元測試。然后,在部署到 J2EE 服務(wù)器時(shí),將持久層轉換為使用 J2EE 數據源(通過(guò) JNDI)、JTA 事務(wù)和使用 FireBird (一個(gè)開(kāi)放源代碼版本的 Interbase)。這是用 Spring 作為 IOC 容器完成的。

從清單 3 中可以看出,Spring 允許加入依賴(lài)性。注意清單中應用程序上下文文件是如何配置 dataSource 的。 dataSource 傳遞給 sessionFactory , sessionFactory 傳遞給 UserDAO 。

清單 3. Spring IOC 和 Hibernate
                        <beans>                        <!-- Datasource that works in any application server                        You could easily use J2EE data source instead if this were                        running inside of a J2EE container.                        -->                        <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">                        <property name="driverClassName"><value>com.mysql.jdbc.Driver</value></property>                        <property name="url"><value>jdbc:mysql://localhost:3306/mysql</value></property>                        <property name="username"><value>root</value></property>                        <property name="password"><value></value></property>                        </bean>                        <!-- Hibernate SessionFactory -->                        <bean id="sessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">                        <property name="dataSource"><ref local="dataSource"/></property>                        <!-- Must references all OR mapping files. -->                        <property name="mappingResources">                        <list>                        <value>net/sf/hibernateExamples/User.hbm.xml</value>                        <value>net/sf/hibernateExamples/Group.hbm.xml</value>                        <value>net/sf/hibernateExamples/Role.hbm.xml</value>                        <value>net/sf/hibernateExamples/ContactInfo.hbm.xml</value>                        </list>                        </property>                        <!-- Set the type of database; changing this one property will port this to Oracle,                        MS SQL etc. -->                        <property name="hibernateProperties">                        <props>                        <prop key="hibernate.dialect">net.sf.hibernate.dialect.MySQLDialect</prop>                        </props>                        </property>                        </bean>                        <!-- Pass the session factory to our UserDAO -->                        <bean id="userDAO" class="net.sf.hibernateExamples.UserDAO">                        <property name="sessionFactory"><ref local="sessionFactory"/></property>                        </bean>                        </beans>                        

設置了 UserDAO 后,下一步就是定義并使用更多的查詢(xún)以展示可以完成的操作。Hibernate 可以用預定義查詢(xún)將查詢(xún)存儲到源代碼之外,如清單 4 所示。

清單 4. 預定義查詢(xún)
                                [User.java]                        /**                        * @author Richard Hightower                        * ArcMind Inc. http://www.arc-mind.com                        * @hibernate.class table="TBL_USER" discriminator-value="2"                        * @hibernate.discriminator column="USER_TYPE"                        *                        * @hibernate.query name="AllUsers" query="from User user order by user.email asc"                        *                        * @hibernate.query name="OverheadStaff"                        * query="from Employee employee join employee.group g where g.name not in (‘ENGINEERING‘,‘IT‘)"                        *                        * @hibernate.query name="CriticalStaff"                        * query="from Employee employee join employee.group g where g.name in (‘ENGINEERING‘,‘IT‘)"                        *                        * @hibernate.query name="GetUsersInAGroup"                        * query="select user from Group g join g.users user"                        *                        * @hibernate.query name="GetUsersNotInAGroup"                        * query="select user from User user where user.group is null"                        *                        * @hibernate.query name="UsersBySalaryGreaterThan"                        * query="from User user inner join user.contactInfo info where info.salary > ?1"                        *                        * @hibernate.query name="UsersBySalaryBetween"                        * query="from User user join user.contactInfo info where info.salary between ?1 AND ?2"                        *                        * @hibernate.query name="UsersByLastNameLike"                        * query="from User user join user.contactInfo info where info.lastName like ?1"                        *                        * @hibernate.query name="GetEmailsOfUsers"                        * query="select user.email from Group g join g.users as user where g.name = ?1"                        *                        */                        public class User {                        .                        .                        .                        

上述代碼定義了幾個(gè)預定義查詢(xún)。 預定義查詢(xún) 是存儲在 *.hbm.xml文件中的查詢(xún)。在清單 5 中,可以看到如何執行預定義查詢(xún)。

清單 5. 使用預定義查詢(xún)
                                [UserDAO.java]                        /**                        * Demonstrates a query that returns a String.                        */                        public String[] getUserEmailsInGroup(String groupName){                        List emailList =                        getHibernateTemplate().findByNamedQuery("GetEmailsOfUsers");                        return (String [])                        emailList.toArray(new String[emailList.size()]);                        }                        /**                        * Demonstrates a query that returns a list of Users                        *                        * @return A list of emails of all of the users in the authentication system.                        *                        */                        public List getUsers(){                        return getHibernateTemplate().findByNamedQuery("AllUsers");                        }                        /**                        * Demonstrates passing a single argument to a query.                        *                        * @return A list of UserValue objects.                        *                        */                        public List getUsersBySalary(float salary){                        return getHibernateTemplate()                        .findByNamedQuery("UsersBySalaryGreaterThan",                        new Float(salary));                        }                        /**                        * Demonstrates passing multiple arguments to a query                        *                        * @return A list of UserValue objects.                        *                        */                        public List getUsersBySalaryRange(float start, float stop){                        return getHibernateTemplate()                        .findByNamedQuery("UsersBySalaryBetween",                        new Object[] {new Float(start), new Float(stop)});                        }                        

查詢(xún)進(jìn)行時(shí),可以在持久層中加上最后一層:使用 Spring 的事務(wù)管理。



回頁(yè)首


用 Spring 管理事務(wù)

Spring 可以聲明式地管理事務(wù)。例如, UserDAO.addUser 方法當前不是在單個(gè)事務(wù)中執行的。因此,組中的每一個(gè)用戶(hù)都插入到自己的事務(wù)中,如清單 6 所示。

清單 6. 添加一組用戶(hù)
                                [UserDAO.java]                        /**                        * @param group                        */                        public void addGroup(Group group) {                        getHibernateTemplate().save(group);                        }                        [UserDAOTest.java]                        public void testAddGroupOfUsers(){                        Group group = new Group();                        for (int index=0; index < 10; index++){                        User user = new User();                        user.setEmail("rick"+index+"@foobar.com" );                        user.setPassword("foobar");                        group.addUser(user);                        }                        group.setName("testGroup");                        userDAO.addGroup(group);                        assertNotNull(group.getId());                        Group group2 = userDAO.findPopulatedGroupByName("testGroup");                        assertEquals("testGroup",group2.getName());                        assertEquals(10, group2.getUsers().size());                        String email = ((User)group2.getUsers().get(0)).getEmail();                        assertEquals("rick0@foobar.com", email);                        }                        

不建議使用上述解決方案,因為每一個(gè) User 都要在自己的事務(wù)中插入到數據庫中。如果出現問(wèn)題,那么只能添加部分用戶(hù)。如果希望保留 ACID 屬性(即保證所有都發(fā)生或者所有都不發(fā)生),可以通過(guò)程序進(jìn)行事務(wù)管理,但是它很快就會(huì )變得一團糟了。相反,應使用 Spring 的 AOP 來(lái)支持聲明式的事務(wù),如清單 7 所示。

清單 7. 聲明式管理事務(wù)
                                [applicationContext.xml]                        <!-- Pass the session factory to our UserDAO -->                        <bean id="userDAOTarget" class="net.sf.hibernateExamples.UserDAOImpl">                        <property name="sessionFactory"><ref local="sessionFactory"/></property>                        </bean>                        <bean id="transactionManager"                        class="org.springframework.orm.hibernate.HibernateTransactionManager">                        <property name="sessionFactory"><ref bean="sessionFactory"/></property>                        </bean>                        <bean id="userDAO"                        class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">                        <property name="transactionManager"><ref local="transactionManager"/></property>                        <property name="target"><ref local="userDAOTarget"/></property>                        <property name="transactionAttributes">                        <props>                        <prop key="addGroup">PROPAGATION_REQUIRED</prop>                        </props>                        </property>                        </bean>                        

注意在準備清單 7 的代碼時(shí),我重新改寫(xiě)了 UserDAO 并提取了其接口。這個(gè)接口現在是 UserDAO ,它的實(shí)現類(lèi)是 UserDAOImpl 。這樣清單 7 中的事務(wù)代碼就使用了帶有事務(wù)屬性 (PROPAGATION_REQUIRED) UserDAO.addGroup() 方法?,F在只要底層數據庫支持,就可以在一個(gè)事務(wù)中添加所有用戶(hù)。



回頁(yè)首


結束語(yǔ)

在本文中,介紹了如何使用 Hibernate 和 Spring 實(shí)現一個(gè)事務(wù)持久層。Hibernate 是一種先進(jìn)的 OR 映射工具,而 Spring 是一個(gè) AOP 框架和 IOC 容器。這兩種技術(shù)的綜合使用,使得開(kāi)發(fā)人員可以編寫(xiě)媲美數據庫廠(chǎng)商的代碼,它可以在 J2EE 容器中運行,也可以單獨運行。使用了 DbUnit (JUnit 的擴展)構建和測試本文中例子的所有代碼,雖然這不是討論的重點(diǎn)。

要了解有關(guān) AOP、IOC 容器和測試驅動(dòng)開(kāi)發(fā)的更多內容,請參閱 參考資料。



回頁(yè)首


參考資料

  • 您可以參閱本文在 developerWorks 全球站點(diǎn)上的 英文原文.

  • Hibernate 的創(chuàng )始人 Gavin King 為編寫(xiě) Hibernate 的文檔(以及框架?。┰O置了很高的標準。要了解 Java 平臺上這種讓人激動(dòng)的 OR 映射工具的更多內容,請參閱 Hibernate 主頁(yè)上的 Hibernate User Guide。



  • 可以通過(guò) Rod Johnson 的 “ Introducing the Spring framework”(ServerSide.com,2003 年 10 月),直接跟 Spring 的發(fā)明者學(xué)習有關(guān)它的更多內容。



  • Matt Raible 的 AppFuse 很實(shí)用地介紹了對幾個(gè) J2EE 應用服務(wù)器上的數據庫使用 Hibernate 和 Spring 。



  • Juergen Hoeller 通過(guò)其教程“ Hibernate -- Data Access with a Spring Framework”(2003 年 7 月)制定了關(guān)于 Hibernate、AOP、Spring 和事務(wù)管理的規則。



  • 還想了解 Spring 的更多內容?請訪(fǎng)問(wèn) Spring 主頁(yè)。



  • DbUnit 主頁(yè)是學(xué)習 Junit 這個(gè)方便擴展的第一資源。



  • 有關(guān) DbUnit 的介紹,請參閱 Philippe Girolami 的“ Control your test-environment with DbUnit and Anthill”( developerWorks,2004 年 4 月)。



  • 當然,Andrew Glover 的“ Effective unit testing with DbUnit”(OnJava.com,2004 年 1 月)是另一個(gè)很好的資源。



  • 通過(guò) Malcolm Davis 的“ 利用 Ant 和 JUnit 進(jìn)行增量開(kāi)發(fā)”( developerWorks,2000 年 11 月)學(xué)習更多有關(guān) DbUnit 及其前身 JUnit 的內容。



  • 至于 AOP,它是由 Nicholas Lesiecki 一手開(kāi)創(chuàng )的(至少我認為是這樣)。閱讀他的“ 使用面向 Aspect 的編程改進(jìn)模塊性”( developerWorks,2002 年 1 月),了解這種強大的面向對象編程的補充技術(shù)。



  • 在“ AOP 解決緊密耦合的難題”( developerWorks,2004 年 2 月)中,Andrew Glover 又回來(lái)了,這一次他展示了如何用靜態(tài)橫切來(lái)解耦企業(yè)應用程序。



  • Sean Sullivan 的“ 高級 DAO 編程”( developerWorks,2003 年 10 月)提供了對 DAO 模式的簡(jiǎn)要介紹,然后直接進(jìn)入如何在 J2EE 編程中發(fā)揮它的強大功能。



  • 對于那些剛開(kāi)始接觸 CMP CMR 的人,Richard Hightower 編寫(xiě)了一個(gè)關(guān)于這個(gè)主題的全系列教程,首先是“ Introduction to container-managed persistence and relationships”( developerWorks,2003 年 3 月)。



  • 有關(guān) XDoclet 的簡(jiǎn)要教程,請參閱也是由 Richard Hightower 所寫(xiě)的“ Enhance J2EE component reuse with XDoclet”( developerWorks,2003 年 5 月)。



  • 當然,還可以查看 SourceForge 上的 Hibernate XDoclet 標簽。



  • developerWorks Java 技術(shù)專(zhuān)區中可以找到關(guān)于 Java 編程各個(gè)方面的文章。



  • 訪(fǎng)問(wèn) Developer Bookstore,獲得技術(shù)書(shū)籍的完整列表,其中包括數百本 Java 相關(guān)主題的書(shū)籍。



  • 還可以參閱 Java 技術(shù)專(zhuān)區教程頁(yè),獲得 developerWorks 免費 Java 教程的完整清單。




回頁(yè)首


關(guān)于作者

Richard 在 Arc-Mind Inc. 工作,在那里他主要從事 Struts 和 J2EE 的技術(shù)指導和咨詢(xún)。Rick 是一位天生的軟件開(kāi)發(fā)人員,已有 14 年軟件開(kāi)發(fā)經(jīng)驗(其中 7 年是在 Java 平臺上)。Rick 編寫(xiě)過(guò)幾本 Java 技術(shù)書(shū)籍,并為 Java Developer‘s Journal和 IBM developerWorks 撰寫(xiě)文章。Rick 最近在 SourceBeat 上完成了一本關(guān)于 Struts 的書(shū)籍。


本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
Object-relation mapping without the container
MyEclipse Spring Hibernate整合開(kāi)發(fā) - liuxinglanyue - JavaEye技術(shù)網(wǎng)站
Hibernate left join(左連接)
yanghuw的專(zhuān)欄,第一個(gè)Spring程序
MyEclipse開(kāi)發(fā)SSH(Struts+Spring+Hibernate)入門(mén)
Structs Spring Hibernate快速入門(mén)
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久