?? 用hibernate和spring開發事務持久層.htm
字號:
user from User user where user.group is null"<BR> *
<BR> * @hibernate.query
name="UsersBySalaryGreaterThan" <BR> * query="from
User user inner join user.contactInfo info where
info.salary > ?1"<BR> * <BR> *
@hibernate.query name="UsersBySalaryBetween" <BR> *
query="from User user join user.contactInfo info where
info.salary between ?1 AND ?2"<BR> * <BR> *
@hibernate.query name="UsersByLastNameLike" <BR> *
query="from User user join user.contactInfo info where
info.lastName like ?1"<BR> * <BR> *
@hibernate.query name="GetEmailsOfUsers" <BR> *
query="select user.email from Group g join g.users as
user where g.name = ?1"<BR> *
<BR> */<BR>public class User
{<BR> .<BR> .<BR> . </P>
<P> 上述代碼定義了幾個預定義查詢。預定義查詢 是存儲在 *.hbm.xml 文件中的查詢。在清單 5
中,可以看到如何執行預定義查詢。</P>
<P> 清單 5. 使用預定義查詢<BR> [UserDAO.java]</P>
<P style="BACKGROUND: #eeeeee"> /**<BR> *
Demonstrates a query that returns a String.<BR>
*/
<BR> public String[] getUserEmailsInGroup(String
groupName){<BR> List emailList
=<BR> getHibernateTemplate().findByNamedQuery("GetEmailsOfUsers");
<BR> return (String
[])<BR> emailList.toArray(new
String[emailList.size()]);<BR> }<BR><BR> /**<BR>
* Demonstrates a query that returns a list of
Users<BR> *<BR> * @return A list of emails
of all of the users in the authentication
system.<BR> * <BR>
*/
<BR> public List getUsers(){<BR> return
getHibernateTemplate().findByNamedQuery("AllUsers");<BR> }<BR><BR>
/**<BR> * Demonstrates passing a single argument to
a query. <BR> *<BR> * @return A list of
UserValue objects.<BR> *
<BR> */
<BR> public List getUsersBySalary(float
salary){<BR> return
getHibernateTemplate()<BR>
.findByNamedQuery("UsersBySalaryGreaterThan",<BR>
new
Float(salary));<BR> }<BR><BR> /**<BR> *
Demonstrates passing multiple arguments to a
query<BR> * <BR> * @return A list of
UserValue objects.<BR> * <BR>
*/
<BR> public List getUsersBySalaryRange(float start,
float
stop){<BR>
return getHibernateTemplate()<BR>
.findByNamedQuery("UsersBySalaryBetween",<BR> new
Object[] {new Float(start), new
Float(stop)});<BR> }</P>
<P> 查詢進行時,可以在持久層中加上最后一層:使用 Spring 的事務管理。</P>
<P> <STRONG>用 Spring 管理事務</STRONG></P>
<P> Spring 可以聲明式地管理事務。例如,UserDAO.addUser
方法當前不是在單個事務中執行的。因此,組中的每一個用戶都插入到自己的事務中,如清單 6 所示。</P>
<P> 清單 6. 添加一組用戶<BR> [UserDAO.java]</P>
<P style="BACKGROUND: #eeeeee">/**<BR> * @param
group<BR> */<BR>public void addGroup(Group group)
{<BR> getHibernateTemplate().save(group);<BR> <BR>}</P>
<P>[UserDAOTest.java]</P>
<P style="BACKGROUND: #eeeeee">public void
testAddGroupOfUsers(){<BR> Group group = new
Group();<BR> <BR> for (int index=0; index <
10; index++){<BR> User user = new
User();<BR> user.setEmail("rick"+index+"@foobar.com"
);<BR> user.setPassword("foobar");<BR> group.addUser(user); <BR> }<BR> <BR> group.setName("testGroup");<BR> <BR> userDAO.addGroup(group);<BR> assertNotNull(group.getId());<BR> <BR> Group
group2 =
userDAO.findPopulatedGroupByName("testGroup");<BR> <BR> assertEquals("testGroup",group2.getName());<BR> assertEquals(10,
group2.getUsers().size());<BR> String email =
((User)group2.getUsers().get(0)).getEmail();<BR> assertEquals("rick0@foobar.com",
email);<BR><BR>}</P>
<P> 不建議使用上述解決方案,因為每一個 User
都要在自己的事務中插入到數據庫中。如果出現問題,那么只能添加部分用戶。如果希望保留 ACID
屬性(即保證所有都發生或者所有都不發生),可以通過程序進行事務管理,但是它很快就會變得一團糟了。相反,應使用
Spring 的 AOP 來支持聲明式的事務,如清單 7 所示。</P>
<P> 清單 7. 聲明式管理事務<BR> [applicationContext.xml]</P>
<P style="BACKGROUND: #eeeeee"><!-- Pass the session
factory to our UserDAO --><BR> <bean
id="userDAOTarget"
class="net.sf.hibernateExamples.UserDAOImpl"><BR> <property
name="sessionFactory"><ref
local="sessionFactory"/></property><BR>
</bean><BR> <BR> <bean
id="transactionManager" <BR>
class="org.springframework.orm.hibernate.HibernateTransactionManager"><BR>
<property name="sessionFactory"><ref
bean="sessionFactory"/></property><BR>
</bean><BR><BR><bean
id="userDAO"<BR>
class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"><BR> <property
name="transactionManager"><ref
local="transactionManager"/></property><BR> <property
name="target"><ref
local="userDAOTarget"/></property><BR> <property
name="transactionAttributes"><BR> <props><BR> <prop
key="addGroup">PROPAGATION_REQUIRED</prop><BR> </props><BR> </property><BR></bean></P>
<P> 注意在準備清單 7 的代碼時,我重新改寫了 UserDAO 并提取了其接口。這個接口現在是
UserDAO,它的實現類是 UserDAOImpl。這樣清單 7 中的事務代碼就使用了帶有事務屬性
(PROPAGATION_REQUIRED) 的 UserDAO.addGroup()
方法?,F在只要底層數據庫支持,就可以在一個事務中添加所有用戶。</P>
<P> <STRONG>結束語</STRONG></P>
<P> 在本文中,介紹了如何使用 Hibernate 和 Spring 實現一個事務持久層。Hibernate
是一種先進的 OR 映射工具,而 Spring 是一個 AOP 框架和 IOC
容器。這兩種技術的綜合使用,使得開發人員可以編寫媲美數據庫廠商的代碼,它可以在 J2EE
容器中運行,也可以單獨運行。使用了 DbUnit (JUnit
的擴展)構建和測試本文中例子的所有代碼,雖然這不是討論的重點。</P></TD></TR></TBODY></TABLE></TD></TR>
<TR>
<TD width=10 height=11><IMG height=11
src="用Hibernate和Spring開發事務持久層.files/u_16.gif" width=10></TD>
<TD style="BORDER-BOTTOM: #e8e8e8 1px solid" width=695
bgColor=#f9f9f9 height=11><IMG height=1 src="" width=1></TD>
<TD width=10 height=11><IMG height=11
src="用Hibernate和Spring開發事務持久層.files/u_17.gif"
width=10></TD></TR></TBODY></TABLE></TD></TR></TBODY></TABLE><BR>
<DIV align=right>頁面功能 【<A
href="javascript:window.external.AddFavorite(location.href,document.title+'--www.JavaFan.NET');">加入收藏</A>】
【<A
onclick="window.open(this.href,'','top=180,left=240,width=342,height=326,scrollbars=yes,resizable=no');return false;"
href="http://www.javafan.net/sendarticle.jsp?title=用Hibernate和Spring開發事務持久層&URL=20041223180912482">推薦給朋友</A>】
【字體:<A class=black href="javascript:fontZoom(15)">大</A> <A
class=black href="javascript:fontZoom(13)">中</A> <A class=black
href="javascript:fontZoom(12)">小</A>】 【<A class=black
href="javascript:window.close()">關閉</A>】 </DIV></TD></TR>
<TR>
<TD vAlign=top><IMG height=12
src="用Hibernate和Spring開發事務持久層.files/u_06.gif"
width=751></TD></TR></TBODY></TABLE><BR>
<TABLE cellSpacing=0 cellPadding=0 width=750 align=center border=0>
<TBODY>
<TR>
<TD bgColor=#cacaca height=1></TD></TR>
<TR>
<TD vAlign=center align=middle height=30>Copyright © 2003 - 2005
JavaFan.NET All Rights Reserved</TD></TR></TBODY></TABLE></BODY></HTML>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -