版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
市場(chǎng)營(yíng)銷第4章注冊(cè)登錄和注銷第4章注冊(cè)、登錄和注銷用戶注冊(cè)是網(wǎng)上書店的基本功能之一。用戶如果想從網(wǎng)上書店購(gòu)買商品,必須有一個(gè)網(wǎng)上書店的賬號(hào),用戶可以通過“注冊(cè)”功能獲得賬號(hào),注冊(cè)頁面效果如圖4-1所示。當(dāng)注冊(cè)成功之后,會(huì)進(jìn)入注冊(cè)成功頁面;如果注冊(cè)信息不對(duì),則顯示注冊(cè)失敗。圖4-1用戶注冊(cè)界面第4章注冊(cè)、登錄和注銷當(dāng)用戶購(gòu)物完成離開網(wǎng)站的時(shí)候,應(yīng)該讓用戶注銷,關(guān)閉會(huì)話。在用戶沒有登錄的時(shí)候,菜單欄目應(yīng)該顯示包含“登錄”;當(dāng)用戶登錄以后,菜單欄目顯示包含“注銷”。效果如圖4-3、圖4-4所示。圖4-3用戶沒有登錄時(shí)的菜單圖4-4用戶登錄以后的菜單 4.1開發(fā)步驟在J2EE的開發(fā)中,服務(wù)器端Web應(yīng)用程序分為若干層。每層在處理程序上都有一項(xiàng)明確的責(zé)任。不應(yīng)該將它們混合,并且每層都要與其它層分開,各個(gè)層之間通過通信接口聯(lián)系。如圖4-5所示。Spring容器客戶端瀏覽器數(shù)據(jù)庫(kù)Web服務(wù)器(Tomcat)ActionServiceDAO核心控制器JSP視圖JavaBeans圖4-5J2EE的分層結(jié)構(gòu)4.1開發(fā)步驟● DAO層DAO層完成連接數(shù)據(jù)庫(kù)增刪改等實(shí)現(xiàn)細(xì)節(jié),例如SQL語句怎么寫、怎樣把對(duì)象放入數(shù)據(jù)庫(kù)等等。DAO將底層數(shù)據(jù)訪問操作和業(yè)務(wù)層邏輯分離開,對(duì)業(yè)務(wù)層提供面向?qū)ο蟮臄?shù)據(jù)訪問接口。而業(yè)務(wù)層調(diào)用DAO接口實(shí)現(xiàn)各種業(yè)務(wù)方法,如驗(yàn)證用戶密碼是否正確?!?/p>
Service業(yè)務(wù)層業(yè)務(wù)層位于上層的表示層和控制層,依賴于下層的業(yè)務(wù)層的實(shí)現(xiàn)(DAO),而下層業(yè)務(wù)層不應(yīng)該依賴于上層的表示層和控制器的實(shí)現(xiàn)。業(yè)務(wù)層提供了處理應(yīng)用程序的業(yè)務(wù)邏輯和業(yè)務(wù)校驗(yàn),如驗(yàn)證用戶登錄系統(tǒng)的密碼是否正確;提供了管理事務(wù),允許與其它層相互作用的接口。Servcie層是面向功能的,一個(gè)功能模塊比如說銀行等級(jí)并完成一次存款,把請(qǐng)求給Service層,Service層將這個(gè)功能分解成許多步驟調(diào)用底層的DAO來實(shí)現(xiàn)這次存款。有時(shí),會(huì)看到Servcie層和DAO層的方法是類似的,是因?yàn)镾ervice層的需求不是很復(fù)雜,不用再對(duì)Service層完成太多包裝或者處理就可以直接調(diào)用DAO的方法?!?/p>
Action控制層
控制層的控制器Action接受用戶的輸入并調(diào)用業(yè)務(wù)層的業(yè)務(wù)方法和表示層的組件去完成用戶的請(qǐng)求。當(dāng)Web應(yīng)用單擊Web頁面中的提交按鈕來發(fā)送HTML表單時(shí),控制器接受請(qǐng)求并調(diào)用相應(yīng)的業(yè)務(wù)層方法去處理請(qǐng)求,然后調(diào)用相應(yīng)的視圖來顯示業(yè)務(wù)層返回的數(shù)據(jù)。4.1開發(fā)步驟Struts中的控制器由ActionServlet類和Action類來實(shí)現(xiàn),ActionServlet主要負(fù)責(zé)接受HTTP請(qǐng)求信息,根據(jù)配置文件struts-config.xml的配置信息,把請(qǐng)求轉(zhuǎn)發(fā)給適當(dāng)?shù)腁ction對(duì)象。如果該Action對(duì)象不存在,ActionServlet會(huì)先創(chuàng)建這個(gè)Action對(duì)象,Action充當(dāng)用戶請(qǐng)求和業(yè)務(wù)邏輯處理之間的適配器,其功能是將請(qǐng)求與業(yè)務(wù)邏輯分開,Action根據(jù)用戶請(qǐng)求調(diào)用相關(guān)的業(yè)務(wù)邏輯組件,Action類側(cè)重控制應(yīng)用程序的流程,而不是實(shí)現(xiàn)應(yīng)用程序的邏輯?!?/p>
Spring服務(wù)器各種組件的生成都是由Spring容器來控制,被看作是Spring中的一個(gè)Bean,它可享受Spring提供的所有服務(wù)(依賴注入、實(shí)例管理、事務(wù)管理等)?!?/p>
JSP視圖層視圖是用戶看到并與之交互的界面,視圖向用戶顯示相關(guān)的數(shù)據(jù),并能接受用戶的輸入數(shù)據(jù),但不能進(jìn)行任何實(shí)際的業(yè)務(wù)處理。視圖可以向業(yè)務(wù)層查詢業(yè)務(wù)狀態(tài),但不能改變業(yè)務(wù)層,視圖還可以接受模型發(fā)出的數(shù)據(jù)更新事件,從而對(duì)用戶界面進(jìn)行同步更新。視圖其實(shí)就是一組JSP文件,在這些JSP文件中沒有業(yè)務(wù)邏輯,也沒有業(yè)務(wù)層信息,只有標(biāo)簽,這些標(biāo)簽可以是標(biāo)準(zhǔn)的JSP標(biāo)簽或客戶端標(biāo)簽,如Struts標(biāo)簽庫(kù)中的標(biāo)簽。使用框架的最大好處是不僅在于減少重復(fù)開發(fā)工作量,縮短開發(fā)時(shí)間,降低開發(fā)成本,同時(shí),使程序設(shè)計(jì)更加合理,程序運(yùn)行更加穩(wěn)定等?;谶@些原因,基本上現(xiàn)在開發(fā)中,都會(huì)選擇某些合適的開發(fā)框架,從而達(dá)到快捷,高效的目的。4.1.1注冊(cè)
開發(fā)為5個(gè)步驟:步驟1DAO步驟2Service步驟3Action步驟4Spring步驟5JSP具體步驟如下:步驟1DAODAO層所涉及的類,接口如圖4-6所示。圖4-6DAO層主要類圖4.1.1注冊(cè)其中,IUserDAO接口中的saveUser()用于將一個(gè)User對(duì)象保存到數(shù)據(jù)庫(kù)中。UserDAO類中的saveUser()具體實(shí)現(xiàn)了這個(gè)方法。BaseDAO是將對(duì)數(shù)據(jù)庫(kù)進(jìn)行的操作進(jìn)行封裝,這樣,在UserDAO中就可以直接使用Session。在這里使用了DAO模式。這三個(gè)類和接口在工程中的位置如圖4-7所示。圖4-7文件在項(xiàng)目中的位置4.1.1注冊(cè)創(chuàng)建IUserDAO.java,代碼如下://包名為packageorg.apex.bookstore.dao;//引入另一個(gè)包的User類importorg.apex.bookstore.vo.User;//定義用戶DAO的接口IUserDAOpublicinterfaceIUserDAO{//保存用戶注冊(cè)的信息publicvoidsaveUser(Useruser);}4.1.1注冊(cè)創(chuàng)建BaseDAO.java,代碼如下://包名為packageorg.apex.bookstore.dao;//引入需要的類importorg.hibernate.SessionFactory;importorg.hibernate.classic.Session;//對(duì)一些基本操作進(jìn)行封裝,在它的子類中可以直接使用publicclassBaseDAO{ privateSessionFactorysessionFactory; publicSessionFactorygetSessionFactory(){ returnsessionFactory; } publicvoidsetSessionFactory(SessionFactorysessionFactory){ this.sessionFactory=sessionFactory; } publicSessiongetSession(){ Sessionsession=sessionFactory.openSession(); returnsession; }}4.1.1注冊(cè)創(chuàng)建UserDAO.java,代碼如下://包名org.apex.bookstore.dao.impl;packageorg.apex.bookstore.dao.impl;//引入需要的類;importorg.apex..bookstore.dao.BaseDAO;importorg.apex..bookstore.dao.IUserDAO;importorg.apex.bookstore.vo.User;importorg.hibernate.Query;importorg.hibernate.Session;importorg.hibernate.Transaction;publicclassUserDAOextendsBaseDAOimplementsIUserDAO{//保存用戶的信息到數(shù)據(jù)庫(kù)中 publicvoidsaveUser(Useruser){ Sessionsession=getSession();//將user對(duì)象保存到數(shù)據(jù)庫(kù)中 Transactiontx=session.beginTransaction(); session.save(user); txmit(); session.close(); }}4.1.1注冊(cè)● 步驟2ServiceService層主要用于處理各種業(yè)務(wù)。主要的類和接口是:IUserService,UserService,如圖4-8所示。其中,IUserService是一個(gè)接口,定義了兩個(gè)方法,saveUser()方法用于將User對(duì)象存儲(chǔ)到數(shù)據(jù)庫(kù)中。validateUser()方法用于驗(yàn)證用戶輸入的名稱和密碼是否正確。UserService實(shí)現(xiàn)IUserService接口,通過IUserDAO類,實(shí)現(xiàn)了這兩個(gè)方法。圖4-8Service層的主要類4.1.1注冊(cè)文件IUserService.java和UserService.java在項(xiàng)目中的位置如圖4-9所示。圖4-9文件在項(xiàng)目中的位置4.1.1注冊(cè)IUserService.java代碼如下://包名packageorg.apex.bookstore.service;//引入需要的類importorg.apex.bookstore.vo.User;publicinterfaceIUserService{ //用戶注冊(cè)時(shí),保存用戶的信息
publicvoidsaveUser(Useruser);
//用戶登陸時(shí),驗(yàn)證用戶的信息
publicUservalidateUser(Stringusername,Stringpassword);}UserService.java代碼如下://包名packageorg.apex.bookstore.service.impl;//引入需要的類importorg.apex.bookstore.dao.IUserDAO;importorg.apex.bookstore.service.IUserService;importorg.apex.bookstore.vo.User;4.1.1注冊(cè)publicclassUserServiceimplementsIUserService{//屬性u(píng)serDAO,service層調(diào)用DAO層完成相關(guān)操作
privateIUserDAOuserDAO;
//保存用戶注冊(cè)時(shí)的信息
publicvoidsaveUser(Useruser){ this.userDAO.saveUser(user); }
//用戶登錄時(shí),用于驗(yàn)證用戶的信息
publicUservalidateUser(Stringusername,Stringpassword){
returnnull; }//屬性u(píng)serDAO的get方法
publicIUserDAOgetUserDAO(){ returnuserDAO; }//屬性u(píng)serDAO的set方法
publicvoidsetUserDAO(IUserDAOuserDAO){ this.userDAO=userDAO; }}4.1.1注冊(cè)● 步驟3ActionUserAction類含有是三個(gè)方法,如圖4-10所示。register()方法用于用戶注冊(cè),execute()方法用于用戶登錄,logout()方法用于用戶注銷。這些方法的實(shí)現(xiàn)依賴于Service層,在屬性中,有一個(gè)userService屬性,它的類型是IUserServe。圖4-10Action類圖4.1.1注冊(cè)UserAction.java文件在項(xiàng)目中的位置如圖4-11所示。圖4-11文件在項(xiàng)目中的位置4.1.1注冊(cè)UserAction.java代碼如下:struts.xml文件中配置UserAction,struts.xml在項(xiàng)目中的位置如圖4-12所示。圖4-12struts.xml在項(xiàng)目中的位置<!DOCTYPEstrutsPUBLIC"-//ApacheSoftwareFoundation//DTDStrutsConfiguration2.0//EN"":///dtds/struts-2.0.dtd"><struts> <includefile="struts-default.xml"/> <packagename="default"extends="struts-default"> <actionname="register"class="userAction"method="register"> <resultname="success">/register_success.jsp</result></action> </package></struts>4.1.1注冊(cè)注意在上面代碼中,對(duì)應(yīng)名為register.action的動(dòng)作,對(duì)應(yīng)的類為userAction,方法為該類的register方法。但是,其實(shí)對(duì)應(yīng)的類為。這里,主要是因?yàn)樵诤竺鎸⑹褂肧pringIoC功能,所以,這里為起了一個(gè)別名:userAction?!?步驟4Spring各種組件的生成都是由Spring容器來控制。Spring的配置文件applicationContext.xml項(xiàng)目中的位置,如圖4-13所示。圖4-13applicationContext.xml在項(xiàng)目中的位置4.1.1注冊(cè)applicationContext.xml代碼如下:●
步驟5JSP層創(chuàng)建注冊(cè)視圖register.jsp,注冊(cè)成功視圖register_success.jsp。register.jsp、register_success.jsp文件所在的位置如圖4-14所示。圖4-14文件在工程中的位置4.1.1注冊(cè)創(chuàng)建register.jsp文件,代碼如下:<%@pagecontentType="text/html;charset=gb2312"%><%@taglibprefix="s"uri="/struts-tags"%><html><body>
<formaction="register.action"method="post">
用戶名*:<inputtype="text"name="user.username"/><br><br>
密碼*:<inputtype="password"name="user.password"/><br><br>
性別:<inputtype="text"name="user.sex"/><br><br>
年齡:<inputtype="text"name="user.age"/><br><br><inputtype="submit"value="注冊(cè)"><br></form></body></html>創(chuàng)建注冊(cè)成功頁面register_success.jsp文件,代碼如下:<%@pagecontentType="text/html;charset=gb2312"%><%@taglibprefix="s"uri="/struts-tags"%><html><body>
您好!用戶<s:propertyvalue="user.username"/>歡迎您注冊(cè)成功</h2><ahref="login.jsp">登錄</a></body></html>4.1.2登錄開發(fā)為5個(gè)步驟:步驟1DAO步驟2Service步驟3Action步驟4Spring步驟5JSP具體步驟如下:● 步驟1DAODAO層所設(shè)計(jì)的類和接口如圖4-6所示。其中,IUserDAO接口的validateUser()用于驗(yàn)證用戶,UserDAO類中的validateUser()實(shí)現(xiàn)了這個(gè)方法。根據(jù)用戶輸入的用戶名和密碼到數(shù)據(jù)庫(kù)中查找相關(guān)用戶。如果找到,返回記錄;如果沒有找到,返回空記錄。這兩個(gè)類和接口在工程中的位置如圖4-5所示。IUserDAO.java代碼如下:packageorg.apex.bookstore.dao; //包名importorg.apex.bookstore.vo.User; //引入相關(guān)類publicinterfaceIUserDAO{ publicvoidsaveUser(Useruser); //用戶注冊(cè)時(shí),保存用戶信息
publicUservalidateUser(Stringusername,Stringpassword);//用戶登錄時(shí),驗(yàn)證用戶信息}4.1.2登錄UserDAO.java代碼如下:●
步驟2Service這一層主要涉及到IUserService接口和UserService類,如圖4-8所示。在IUserServie接口中定義了validateUser()方法,用于用戶登錄驗(yàn)證。在類UserService類中具體實(shí)現(xiàn)了這個(gè)類。兩個(gè)文件在工程中的位置如圖4-9所示。創(chuàng)建IUserService.jsp文件,代碼如下:packageorg.apex.bookstore.service; //包名importorg.apex.bookstore.vo.User; //引入相關(guān)類
publicinterfaceIUserService{ publicvoidsaveUser(Useruser); //保存用戶信息
publicUservalidateUser(Stringusername,Stringpassword);//驗(yàn)證用戶信息}創(chuàng)建UserService.java文件,代碼如下:4.1.2登錄●
步驟3ActionUserAction類execute()方法用于用戶登錄,如圖4-10所示。方法的實(shí)現(xiàn)依賴于Service層,在屬性中,有一個(gè)userService屬性,它的類型是IUserServe。類所在工程中的位置如圖4-11所示。修改UserAction.java文件,增加execute()方法的實(shí)現(xiàn),代碼如下:●
步驟4Spring修改applicationContext.xml文件,Spring容器applicationContext.xml,前面已經(jīng)配置好。<beanid="userDAO"class="org.apex.bookstore.dao.impl.UserDAO"parent="baseDAO"></bean><beanid="userService"class="org.apex.bookstore.service.impl.UserService"> <propertyname="userDAO"> <refbean="userDAO"/> </property> </bean><beanid="userAction"class="org.apex.bookstore.action.UserAction"> <propertyname="userService"> <refbean="userService"/> </property></bean>4.1.2登錄●
步驟5JSP創(chuàng)建login.jsp文件,文件的位置如圖4-14所示。<%@pagecontentType="text/html;charset=gb2312"%><jsp:includepage="head.jsp"></jsp:include><%@taglibprefix="s"uri="/struts-tags"%><html><head><title>用戶登錄</title></head><body> <formaction="login.action"method="post"name="login">
用戶名:<inputtype="text"name="user.username"/><br>
密碼:<inputtype="password"name="user.password"/><br> <inputtype="submit"value="登錄"><br></form></body></html> 4.1.3注銷開發(fā)為3個(gè)步驟:步驟1Action步驟2Spring步驟3JSP具體步驟如下:● 步驟1ActionUserAction類logout()方法用于用戶登錄,如圖4-10所示。方法的實(shí)現(xiàn)依賴于Service層,在屬性中,有一個(gè)userService屬性,它的類型是IUserServe。類所在工程中的位置如圖4-11所示。修改UserAction.java文件,添加logout()方法,用于注銷,代碼如下:publicStringlogout()throwsException{ //用戶注銷
Mapsession=ActionContext.getContext().getSession();
session.remove("user"); returnSUCCESS;}配置struts.xml文件,代碼片段如下<actionname="logout"class="userAction"method="logout"><resultname="success">/index.jsp</result></action 4.1.3注銷● 步驟2SpringSpring已經(jīng)在前面章節(jié)配置好,applicaionContext.xml代碼片段如下:<beanid="baseDAO"class="org.apex.bookstore.dao.BaseDAO"abstract="true"> <propertyname="sessionFactory"> <refbean="sessionFactory"/> </property></bean><beanid="userDAO"class="org.apex.bookstore.dao.impl.UserDAO"parent="baseDAO"></bean>…<beanid="userService"class="org.apex.bookstore.service.impl.UserService"> <propertyname="userDAO"> <refbean="userDAO"/> </property></bean>…<beanid="userAction"class="org.apex.bookstore.action.UserAction"> <propertyname="userService"> <refbean="userService"/> </property></bean>4.1.3注銷●
步驟3JSPhead.jsp用于存放網(wǎng)頁的頭部信息,如菜單等。菜單根據(jù)用戶是否登錄有不同的顯示。文件的位置如圖4-14所示。修改head.jsp文件,代碼片段如下:<ahref="index.jsp">首頁</a><s:iftest="#session.user==null"><aclass=title01href="login.jsp">登錄</a></s:if><s:else><ahref="logout.action">注銷</a></s:else><ahref="register.jsp">注冊(cè)</a><ahref="#">聯(lián)系我們</a><ahref="#">網(wǎng)站地圖4.2知識(shí)點(diǎn):DAO模式
數(shù)據(jù)源不同數(shù)據(jù)訪問也不同。根據(jù)存儲(chǔ)的類型(關(guān)系數(shù)據(jù)庫(kù),面向?qū)ο髷?shù)據(jù)庫(kù),文件等等)和供應(yīng)商實(shí)現(xiàn)不同,持久性存儲(chǔ)(比如數(shù)據(jù)庫(kù))的訪問差別也很大。比如,在一個(gè)應(yīng)用系統(tǒng)中使用JDBCAPI對(duì)Oracle數(shù)據(jù)庫(kù)進(jìn)行連接和數(shù)據(jù)訪問,這些JDBCAPI與SQL語句分散在系統(tǒng)各個(gè)程序文件中,當(dāng)需要其他RDBMS(如INFORMIX)時(shí),就面臨重寫數(shù)據(jù)庫(kù)連接和訪問數(shù)據(jù)的模塊。一個(gè)軟件模塊(類,函數(shù),代碼塊等)在擴(kuò)展性方面應(yīng)該是開放的,而在更改性方面應(yīng)該是封閉的,這就是開閉原則。要實(shí)現(xiàn)這個(gè)原則,在軟件面向?qū)ο笤O(shè)計(jì)時(shí)要精良考慮接口封裝機(jī)制,抽象機(jī)制和多態(tài)技術(shù)。這里的關(guān)鍵就是將這個(gè)軟件模塊的功能部分和不同的實(shí)現(xiàn)細(xì)節(jié)清晰地分開來。在數(shù)據(jù)庫(kù)訪問對(duì)象中,應(yīng)該運(yùn)用這個(gè)原則。在數(shù)據(jù)庫(kù)編程的時(shí)候,經(jīng)常遇到這種情況,一個(gè)用戶的數(shù)據(jù)訪問對(duì)象,里面的操作方法有insert,delete,update,select等,對(duì)不同數(shù)據(jù)庫(kù)其實(shí)現(xiàn)的細(xì)節(jié)是不相同的。因此,不太可能針對(duì)每種類型的數(shù)據(jù)庫(kù)做一個(gè)通用的對(duì)象來實(shí)現(xiàn)這些操作。但是,可以定義一個(gè)用戶數(shù)據(jù)訪問對(duì)象的接口IUserDAO,提供inser,delete,update,select等抽象方法。不同類型的數(shù)據(jù)庫(kù)的用戶訪問對(duì)象實(shí)現(xiàn)這個(gè)接口就可以了。如圖4-15所示。4.2知識(shí)點(diǎn):DAO模式MySqlImpSQLServerImpOracleMySqlImpClientIUserDAOinsert()delete()update()select()圖4-15DAO4.3知識(shí)點(diǎn):HIBERNATE:QUERY接口4.3.1綁定參數(shù)1.使用“?”指定參數(shù)通過Query接口可以先設(shè)定查詢參數(shù),然后通過setXXX()等方法,將指定的參數(shù)值填入,而不用每次都編寫完整的HQL。來看下面的例子Queryquery=session.createQuery("fromStudentswheres.age>?andlike?")query.setInteger(0,25);//設(shè)置age>?中的問號(hào)為整型25query.setString(1,"%clus%");//設(shè)置namelike?中的問號(hào)為字符串"%clus%"2.使用“:”后跟變量的方法設(shè)置參數(shù)可以使用命名參數(shù)來取代使用“?”設(shè)置參數(shù)的方法,這可以不用依據(jù)特定的順序來設(shè)定參數(shù)值,比如上面的代碼可以寫為:Queryquery=session.createQuery("fromStudentswheres.age>:minAgeandlike:likeName");query.setInteger("minAge",25);//設(shè)置:號(hào)后的minAge變量值query.setStringString("ikeName","%clus%");//設(shè)置:號(hào)后的likeName變量值使用命名參數(shù)時(shí),在建立Query時(shí)先使用“:”后跟著參數(shù)名,然后就可以在setXXX()方法中直接指定參數(shù)名來設(shè)定參數(shù)值。命名參數(shù)的好處如下:● 命名參數(shù)不依賴于它們?cè)诓樵冏址谐霈F(xiàn)的順序● 在同一個(gè)查詢中可以使用多次● 可讀性好4.3.1綁定參數(shù)
3.setParameter()方法setParameter()方法的全稱是setParameter(StringparamName,實(shí)例,實(shí)例類型)。這個(gè)方法可以綁定任意類型的參數(shù)。在實(shí)際應(yīng)用中,Hibernate可以根據(jù)類實(shí)例推斷出絕大部分對(duì)應(yīng)的映射類型,因此setParameter()中的第三個(gè)參數(shù)也可以不要。例子如下:Stringhql="fromUseruwhereu.username=?andu.password=?";Queryquery=session.createQuery(hql);query.setParameter(0,username);query.setParameter(1,password);4.3.2LIST()方法4.3.2list()方法Query的list()方法用于取得一個(gè)List類的示例,此示例中包括的可能是一個(gè)Object集合,也可能是Object數(shù)組集合。最常見的是使用list()取得一組符合條件實(shí)例對(duì)象,如下程序所示:Queryquery=session.createQuery("fromStudentswheres.age>20";Listlist=query.list();for(inti=0;i<list.size();i++){Studentstu=(Student)list.get(i);System.out.println(stu.getName());}4.4知識(shí)點(diǎn):HIBERNATE:QUERY接口在Hibernate中,數(shù)據(jù)查詢與檢索機(jī)制很完善。相對(duì)其他ORM實(shí)現(xiàn)而言,Hibernate提供了靈活多樣的查詢機(jī)制。其中包括:●
CriteriaQuery(條件查詢API)● HibernateQueryLanguage(HQL)● SQL傳統(tǒng)的SQL語句采用的是結(jié)構(gòu)化的查詢方法,而這種方法對(duì)于查詢以對(duì)象形式存在的數(shù)據(jù)卻無能為力。Hibernate為用戶提供了一種類似于SQL的語言,Hibernate查詢語言(HQL)。和SQL不同的是,HQL是一種面向?qū)ο蟮牟樵冋Z言,它可以查詢以對(duì)象形式存在的數(shù)據(jù)。在Hibernate中不提倡使用SQL。雖然Criteria提供了更加符合面向?qū)ο缶幊棠J降牟樵兎庋b模式,但HQL提供了更加強(qiáng)大的功能。在官方開發(fā)手冊(cè)中,也將HQL作為推薦的查詢方式。這里,介紹HQL檢索語言。實(shí)體查詢:
有關(guān)實(shí)體查詢技術(shù),如下面的例子:
Stringhql="fromUser"; Queryquery=session.createQuery(hql); Listlist=query.list();上面的hql="fromUser",將取出use表的所有對(duì)應(yīng)記錄,對(duì)應(yīng)SQL為"select…fromuser"。也可以在hql中采用全路徑名,如:”fromcom.apex.bookstore.vo.User”hql子句本身大小寫無關(guān),但是其中出現(xiàn)的類名和屬性名必須注意大小寫區(qū)分。如果需要取出名為"Tom"的用戶的記錄,可以通過hql語句加以限定:
Stringhql=”fromUserasuserwhere=‘Tom’”; Queryquery=session.createQuery(hql); ListuserList=query.list();這里引入兩個(gè)子句“as”和“where”,as子句為類名創(chuàng)建了一個(gè)別名,而where子句指定了限定條件。其中as子句可忽略,如:”fromUseruserwhere=’Tom’
”where子句中,可以通過比較操作符指定甄選條件,如:=,<>,<,>,>=,<=,between,notbetween,in,notin,is,like等。幾個(gè)簡(jiǎn)單的示例:
fromUseruserwhereuser.age>20 fromUseruserwhereuser.agebetween20and30 fromUseruserwhereuser.agein(18,28) fromUseruserwhereisnull fromUseruserwherelike‘T%’與SQL相同,通過and、or等邏輯連接符組合各個(gè)邏輯表達(dá)式:
fromUseruserwhere(user.age>20)and(like‘T%’)
4.4.2實(shí)體的更新和刪除在Hibernate2之前版本中,HQL僅用于數(shù)據(jù)查詢。而在Hibernate3中,HQL具備了更加強(qiáng)大的功能。實(shí)體更新與刪除就是其中的主要特性之一。delete和update子句是Hibernate3中新引入的HQL子句。通過delete、update子句,數(shù)據(jù)的刪除與更新操作可以以更加靈活的方式實(shí)現(xiàn)。在Hibernate2中,完成用戶年齡屬性的更新,必須通過以下代碼實(shí)現(xiàn)://加載ID=1的用戶記錄Useruser=(User)session.get(User.class,newInteger(1));user.setAge(newInteger(18));//通過Session.save方法保存session.save(user);以上代碼完成了ID=1的用戶數(shù)據(jù)的更新。如果需要將庫(kù)表中所有的用戶的年齡設(shè)置為18,該如何操作呢?別無他法,只能首先利用HQL“fromUser”查詢出所有的實(shí)體,設(shè)置年齡屬性后再逐一保存。Hibernate3HQL提供了更加靈活邊界的實(shí)現(xiàn)方式(bulkdelete/update):Stringhql="updateUsersetage=18wherid=1";Queryquery=session.createQuery(hql);query.executeUpdate();4.4.2實(shí)體的更新和刪除這段代碼完成與上例同樣的功能。對(duì)于單個(gè)對(duì)象的更新也許代碼量并沒有減少太多,但如果對(duì)于批量更新操作,其便捷性及性能的提高就相當(dāng)可觀。以下代碼將所有用戶的年齡屬性更新為18:Stringhql="updateUsersetage=18";Queryquery=session.createQuery(hql);intret=query.executeUpdate();Hibernate3HQLdelete子句的使用同樣非常簡(jiǎn)單。以下代碼刪除了所有年齡大于18的用戶記錄:Stringhql="deleteUserwhereage>18";Queryquery=session..createQuery(hql);intret=query.executeUpdate(); 4.5知識(shí)點(diǎn):STRUTS2:ACTION4.5.1概述Struts2控制器最重要的組成部分就是Action,它是WEB框架的控制中心,是連接模型和視圖的橋梁和紐帶。Action接受來自視圖層的請(qǐng)求,并接受請(qǐng)求參數(shù),同時(shí)負(fù)責(zé)調(diào)用模型層方法來完成業(yè)務(wù)邏輯的處理,最后控制程序的流程,選擇一個(gè)合適的視圖將結(jié)果顯示給客戶。4.5.2ACTION的定義Struts2中的Action只需要在一個(gè)普通的類中定義一個(gè)方法,如:publicclassXXXAction{publicStringmethod(){return“returnValue”;}}XXXAction:Action的類名,習(xí)慣上以Action結(jié)尾,更容易閱讀和理解Method:用于接受請(qǐng)求的方法,名稱可以自定義,默認(rèn)情況下,會(huì)調(diào)用execute()方法。該方法不能帶任何參數(shù),且必須返回字符串類型。ReturnValue:返回值,類型必須是字符串,Struts2會(huì)根據(jù)返回值控制程序流程。一個(gè)簡(jiǎn)單的例子。定義一個(gè)HelloAction,訪問該Action的時(shí)候在控制臺(tái)打印“你好”。publicclassHelloAction{publicStringhello(){System.out.println(“你好”);returnnull;}}在struts.xml配置文件中,將剛才創(chuàng)建的Action注冊(cè)到這里。<actionname="helloAction"class="HelloAction"method="hello"></action>4.5.2ACTION的定義name:自定義名稱,訪問Action時(shí)用到,如:helloAction.action。class:Action的類名method:訪問該Action時(shí),調(diào)用hello()方法。因?yàn)閔ello()方法的返回值是null,表示不跳轉(zhuǎn)到任何地方。如果返回一個(gè)字符串,則必須配置<action>的子標(biāo)簽<result>,通過該標(biāo)簽映射一個(gè)跳轉(zhuǎn)路徑,如:<resultname=”success”>/my.jsp</result>,表示如果方法的返回值為success,則跳轉(zhuǎn)到my.jsp文件。<method>是可選的,在定義Action的響應(yīng)方法時(shí),如果將方法名稱定義為execute,則<method>可省略。如:publicclassHelloAction{publicStringexecute(){System.out.println(“你好”);Returnnulll;}}配置修改如下:<actionname="helloAction"class="HelloAction"></action>4.5.3通過ACTION獲取請(qǐng)求參數(shù)通過HttpServletRequest的getParameter()或getParameterValues()方法固然可以得到從客戶端傳送過來的請(qǐng)求參數(shù),但是這樣做很麻煩,而且增加了應(yīng)用程序的耦合度,增強(qiáng)了對(duì)容器的依賴。Struts2在Action中改進(jìn)了獲取請(qǐng)求參數(shù)的方式,自動(dòng)獲取請(qǐng)求參數(shù)。Struts2獲取請(qǐng)求參數(shù)的名稱,拼成該參數(shù)的set方法與get方法,調(diào)用方法實(shí)現(xiàn)屬性的存取操作。比如,從客戶端傳送一個(gè)名叫name的參數(shù),則會(huì)拼成setName和getName方法名,通過反射調(diào)用setName()方法進(jìn)行賦值,程序員通過getName()方法就能取到值了。存取值的代碼寫在Action中就可以。上面的操作是交給OGNL實(shí)現(xiàn)的。以下是一個(gè)Action獲取請(qǐng)求參數(shù)的例子。本示例用于演示用戶登陸的過程。用戶輸入用戶名和密碼,如果分別為admin和admin,則顯示登陸成功的信息,否則顯示登陸失敗的信息。login.jsp…<formaction="loginAction.action"method="post">
用戶名:<inputname="username"><br>
密碼:<inputname="password"type="password"><br><inputtype="submit"value="登錄"></form>4.5.3通過ACTION獲取請(qǐng)求參數(shù)在表單中,表單域的name屬性值必須和Action中定義的屬性名稱一致,才能正確被Action接收,如果讀者懂得反射原理,更容易理解。
LoginAction.java作為控制器則負(fù)責(zé)接收視圖層發(fā)送過來的用戶名和密碼,并通過execute()方法調(diào)用業(yè)務(wù)方法,根據(jù)執(zhí)行結(jié)果控制程序流程:如果登陸成功,則跳轉(zhuǎn)到success.jsp,否則跳轉(zhuǎn)到failure.jsp。4.5.3通過ACTION獲取請(qǐng)求參數(shù)publicclassLoginAction{ privateStringusername; privateStringpassword;
publicStringgetPassword(){ returnpassword; } publicvoidsetPassword(Stringpassword){ this.password=password; } publicStringgetUsername(){ returnusername; } publicvoidsetUsername(Stringusername){ this.username=username; } publicStringexecute(){//調(diào)用業(yè)務(wù)組件,如果成功,返回“success”;否則,返回“failure”。
if(….){return“success”;}else{return“failure”;}}}4.5.3通過ACTION獲取請(qǐng)求參數(shù)提交表單后,請(qǐng)求提交給是在struts.xml文件中預(yù)先配置好的,可以自定義,但最好用一個(gè)比較有意義的名字,增強(qiáng)程序的易讀性。LoginAction的配置<actionname="loginAction"class="LoginAction"> <resultname="success">/success.jsp</result> <resultname="failure">/failure.jsp</result></action>也可以將定義在Action中的屬性封裝成一個(gè)實(shí)體類,更利于控制器與屬性的分離。將屬性定義在Action中的做法,違背了控制器的初衷。Struts2的開發(fā)者們提供了一種更好的處理方式,類似于struts1.x中的ActionForm,但是比ActionForm更加靈活和解耦。4.5.3通過ACTION獲取請(qǐng)求參數(shù)將username和password封裝到User類中,源代碼如下:User.javapublicclassUser{ privateStringusername; privateStringpassword; publicStringgetPassword(){ returnpassword; } publicvoidsetPassword(Stringpassword){ this.password=password; } publicStringgetUsername(){ returnusername; } publicvoidsetUsername(Stringusername){ this.username=username; }}4.5.3通過ACTION獲取請(qǐng)求參數(shù)在LoginAction類中,保存一個(gè)User的引用就行了。該類的配置不需要改變。LoginAction.java(修改版)publicclassLoginAction{ privateUseruser; publicUsergetUser(){ returnuser; } publicvoidsetUser(Useruser){ this.user=user; } publicStringexecute(){ //同上
}}4.5.3通過ACTION獲取請(qǐng)求參數(shù)最后,修改login.jsp中的表單域的name屬性值,基本格式為:引用名.屬性名。在上例中,引用名是指定義在LoginAction類中的user,屬性名是指定義在Users為中的username和password。為了將用戶名傳遞到User類的username屬性中保存,修改<inputname="username">為<inputname="user.username">即可,所以login.jsp最后的代碼如下:login.jsp的修改版,代碼如下:
<body><formaction="loginAction.action"method="post">
用戶名:<inputname="user.username"><br>
密碼:<inputname="user.password"type="password"><br> <inputtype="submit"value="登錄"></form></body> 4.5.4ACTIONSUPPORT在Struts2中,Action與容器已經(jīng)做到完全解耦,不再繼承某個(gè)類或?qū)崿F(xiàn)某個(gè)接口,但是,在特殊情況下,為了降低編程的工作難度,充分利用Struts2提供的功能,定義Action時(shí)會(huì)繼承類ActionSupport,該類位于xwork2提供的包中。ActionSupport類為Action提供了一些默認(rèn)實(shí)現(xiàn),主要包括:●預(yù)定義常量●從資源文件中讀取文本資源●接收驗(yàn)證錯(cuò)誤信息●驗(yàn)證的默認(rèn)實(shí)現(xiàn)下面是ActionSupport類所實(shí)現(xiàn)的接口:publicclassActionSupportimplementsAction,Validateable,ValidationAware,TextProvider,LocaleProvider,Serializable{}Action接口同樣位于包,定義了一些常量和一個(gè)execute()方法。publicinterfaceAction{publicstaticfinalStringSUCCESS="success";publicstaticfinalStringNONE="none";publicstaticfinalStringERROR="error";publicstaticfinalStringINPUT="input";publicstaticfinalStringLOGIN="login";publicStringexecute()throwsException;}4.5.4ACTIONSUPPORTAction接口中一共定義了五個(gè)常量,每個(gè)常量都有特定的意義,這些常量被execute()方法返回,并最終被Result處理,<action>的子標(biāo)簽<result>的name屬性可以是這些常量中的任何一個(gè)。SUCCESS是name屬性的缺省值。其中,SUCCESS表示請(qǐng)求處理成功,ERROR表示請(qǐng)求處理失敗,NONE表示請(qǐng)求處理完成后不跳轉(zhuǎn)到任何頁面,INPUT表示輸入時(shí)如果驗(yàn)證失敗應(yīng)該跳轉(zhuǎn)到什么地方,LOGIN表示登陸失敗后跳轉(zhuǎn)的目標(biāo)。接口的實(shí)現(xiàn)類com.opensymphony.xwork2.ValidationAwareSupport定義了三個(gè)集合成員,這些集合用于存儲(chǔ)錯(cuò)誤或消息。ValidationAware的眾多方法主要完成對(duì)這些成員的存儲(chǔ)操作和判斷集合中是否有元素的操作,ActionSupport僅僅實(shí)現(xiàn)對(duì)這些方法的簡(jiǎn)單調(diào)用。4.6知識(shí)點(diǎn):STRUTS2:OGNL表達(dá)式4.6.1Struts2的OGNL表達(dá)式OGNL是ObjectGraphicNavigationLanguage(對(duì)象圖導(dǎo)航語言)的縮寫,OGNL是一個(gè)開源項(xiàng)目。OGNL是一種功能強(qiáng)大的EL(ExpressionLanguage,表達(dá)式語言),可以通過簡(jiǎn)單的表達(dá)式來訪問Java對(duì)象中的屬性。OGNL先在WebWork項(xiàng)目中得到應(yīng)用,也是Struts2框架視圖默認(rèn)的表達(dá)式語言,可以說,OGNL表達(dá)式是Struts2框架的特點(diǎn)之一。標(biāo)準(zhǔn)的OGNL會(huì)設(shè)定一個(gè)根對(duì)象(root對(duì)象)。假設(shè)使用標(biāo)準(zhǔn)OGNL表達(dá)式來求值(不是Struts2OGNL),如果OGNL上下文有兩個(gè)對(duì)象:foo對(duì)象,bar對(duì)象。同時(shí)foo對(duì)象被設(shè)置為根對(duì)象(root)。則利用下面的OGNL表達(dá)式求值#foo.blah //返回fo.getBlah()#bar.blah //返回bar.getBlah()blah //返回foo.getBlah(),因?yàn)閒oo為根對(duì)象使用ONGL非常簡(jiǎn)單,如果要訪問的對(duì)象不是根對(duì)象,如示例中的bar對(duì)象,則需要使用命名空間,用“#”來表示,如“#bar”;如果訪問一個(gè)根對(duì)象,則不用指定命名空間,可以直接訪問根對(duì)象的屬性。4.6.1STRUTS2的OGNL表達(dá)式
在Struts2框架中,值棧(ValueStack)就是OGNL的根對(duì)象,假設(shè)值棧中存在兩個(gè)對(duì)象實(shí)例:Man和Animal,這兩個(gè)對(duì)象實(shí)例都有一個(gè)name屬性,Animal有一個(gè)species屬性,Man有一個(gè)salary屬性,假設(shè)Animal在值棧的頂部,Man在Animal后面,如圖4-16所示。下面的代碼片段能更好地理解OGNL表達(dá)式。值棧AnimalnamespeciesMannamesalaryTop圖4-16一個(gè)包含了Animal和Man的值棧4.6.1STRUTS2的OGNL表達(dá)式species //調(diào)用animal.getSpecies()salary //調(diào)用man.getSalry()name //調(diào)用animal.getName(),因?yàn)锳nimal位于值棧的頂部最后一行實(shí)例代碼中,返回的是animal。getName()返回值,即返回了Animal的name屬性,因?yàn)锳nimal是值棧的頂部元素,OGNL將從頂部元素搜索,所以會(huì)返回Animal的name屬性值。如果要獲得Man的name值,則需要如下代碼:Struts2允許在值棧中使用索引,實(shí)例代碼如下所示:[0].name//調(diào)用animal.getName()[1].name//調(diào)用man.getName()Struts2中的OGNLContext是ActionContext,如圖4-17所示4.6.1STRUTS2的OGNL表達(dá)式圖4-17Struts2的OGNLContext結(jié)構(gòu)示意圖4.6.1STRUTS2的OGNL表達(dá)式由于值棧是Struts2中OGNL的根對(duì)象,如果用戶需要訪問值棧中的對(duì)象,則可以通過如下代碼訪問值棧中的屬性:${foo}//獲得值棧中的foo屬性如果訪問其他Context中的對(duì)象,由于不是根對(duì)象,在訪問時(shí),需要加#前綴●
application對(duì)象,用于訪問ServletContext,例如#application.userName或者#application["username"],相當(dāng)于調(diào)用Servlet的getAttribute("username");●
session對(duì)象,用來訪問HttpSession,例如#session.userName或者#session["userName"],相當(dāng)于調(diào)用session.getAttribute("userName")?!?/p>
request對(duì)象用來訪問HttpServletRequest屬性的Map,例如#request.userName或者#request["userName"],相當(dāng)于調(diào)用request.getAttribute("userName")。4.6.2OGNL的集合操作
如果需要一個(gè)集合元素的時(shí)候(例如List對(duì)象或者M(jìn)ap對(duì)象),可以使用OGNL中同集合相關(guān)的表達(dá)式??梢允褂萌缦麓a直接生成一個(gè)List對(duì)象:{e1,e2,e3…}該OGNL表達(dá)式中,直接生成了一個(gè)List對(duì)象,該List對(duì)軒昂中包含3個(gè)元素:e1,e2和e3。如果需要更多的元素,可以按照這樣的格式定義多個(gè)元素,多個(gè)元素之間使用逗號(hào)隔開。如下代碼可以直接生成一個(gè)Map對(duì)象#{key:value1,key2:value2,…}Map類型的集合對(duì)對(duì)象,使用key-value格式定義,每個(gè)key-value元素使用冒號(hào)表示,多個(gè)元素之間使用逗號(hào)隔開。對(duì)于集合類型,OGNL表達(dá)式可以使用in和notin兩個(gè)元素符號(hào)。其中,in表達(dá)式用來判斷某個(gè)元素是否在指定的集合對(duì)象中;notin判斷某個(gè)元素是否不在指定的集合對(duì)象中,代碼如下所示:<s:iftest="'foo'in{'foo','bar'}">…</s:if>4.6.2OGNL的集合操作除了in和notin之外,OGNL還允許使用某個(gè)規(guī)則獲得集合對(duì)象的子集,常用的有以下3個(gè)相關(guān)操作符●
?獲得所有符合邏輯的元素●
^獲得符合邏輯的第一個(gè)元素●
$獲得符合邏輯的最后一個(gè)元素例如代碼:Person.relatives.
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024生鮮乳電商平臺(tái)定制購(gòu)銷及品牌推廣合同3篇
- 二手店鋪過戶協(xié)議模板版B版
- 二零二五年度豪華酒店建筑工程施工總承包合同2篇
- 二零二五年度安置房項(xiàng)目環(huán)保驗(yàn)收合同6篇
- 二零二五年海洋平臺(tái)用鋼板租賃服務(wù)協(xié)議3篇
- 二零二五年度高等教育機(jī)構(gòu)教師聘期管理勞動(dòng)合同范本3篇
- 二零二五年食品安全生產(chǎn)責(zé)任賠償合同3篇
- 武漢工貿(mào)職業(yè)學(xué)院《珠寶商務(wù)》2023-2024學(xué)年第一學(xué)期期末試卷
- 二零二五年度智能安防產(chǎn)品集成與調(diào)試合同3篇
- 2024銅門制安工程物流服務(wù)合同
- 小學(xué)四年級(jí)數(shù)學(xué)知識(shí)點(diǎn)總結(jié)(必備8篇)
- GB/T 893-2017孔用彈性擋圈
- GB/T 11072-1989銻化銦多晶、單晶及切割片
- GB 15831-2006鋼管腳手架扣件
- 醫(yī)學(xué)會(huì)自律規(guī)范
- 商務(wù)溝通第二版第4章書面溝通
- 950項(xiàng)機(jī)電安裝施工工藝標(biāo)準(zhǔn)合集(含管線套管、支吊架、風(fēng)口安裝)
- 微生物學(xué)與免疫學(xué)-11免疫分子課件
- 《動(dòng)物遺傳育種學(xué)》動(dòng)物醫(yī)學(xué)全套教學(xué)課件
- 弱電工程自檢報(bào)告
- 民法案例分析教程(第五版)完整版課件全套ppt教學(xué)教程最全電子教案
評(píng)論
0/150
提交評(píng)論