linansengling

           

          Spring JPetStore(二) JPetStore的分析

          ??Spring JPetStore總體架構(gòu)屬于三層結(jié)構(gòu). 分為業(yè)務(wù)服務(wù)層? 表現(xiàn)層? 數(shù)據(jù)訪問層
          ??
          ?????? 業(yè)務(wù)服務(wù)層使用由POJO(java類)實現(xiàn), 它們運行在輕量級的容器Spring中. 輕量級容器的功能在于,?一 管理業(yè)務(wù)對象的生命周期. 二 借助于Spring?的IOC(Inversion of Control, 控制反轉(zhuǎn))功能來完成對象之間的依賴關(guān)系, 而不用編程一顯示完成. 三 借助于Spring的AOP(Aspect-Oriented Programming, 面向方面的程序設(shè)計)?為運行在容器中的對象提供一些企業(yè)服務(wù), 比如聲明式的事務(wù)管理. 業(yè)務(wù)層放棄了EJB而使用運行在輕量級容器的服務(wù)層, 會有以下好處:
          1.? 能夠在Servlet引擎中運行. 不用EJB容器的服務(wù)器, tomcat就能搞定, 軟件的費用低, 容易管理, 負載小.
          2?. 容易在不同的應(yīng)用服務(wù)器或serverlet引擎之間移植. 要想達到高可移植性, 對于EJB容器來說要比web容器困難, 比如, 就需要確保不同的EJB容器在啟動時都會運行某一些代碼.
          3.??實現(xiàn)更為簡單.
          4. 不需要那么累贅的部署文件.
          不好的地方:
          1.? 缺乏對遠程調(diào)用的內(nèi)置支持.
          2.? 缺乏一個標(biāo)準(zhǔn)的環(huán)境, 用于容納, 管理業(yè)務(wù)對象.
          3.? 沒有清晰的業(yè)務(wù)層.
          4.? 在不同的應(yīng)用系統(tǒng)之間缺乏一致性, 第個系統(tǒng)都可能會有自己的一套做法: 怎么訪問業(yè)務(wù)對象?怎么解決事務(wù)管理 怎么訪問數(shù)據(jù)等.
          雖然如此但現(xiàn)在我們有了spring一切就有了解決之道了.

          ????? 表現(xiàn)層中, Spring JPetStore提供了兩種不同的web層實現(xiàn), 二者都要依靠同一個中間層, 一個是基于Structs的,另一個則是Spring的MVC框架. 二者都是基于JSTL的JSP視圖.

          ????? 數(shù)據(jù)訪問層,使用了J2EE模式中的"數(shù)據(jù)訪問對象"(Data Access Object, DAO),?他用一個DAO接口隱藏了持久化操作的細節(jié), 這樣使用這個模式的業(yè)務(wù)對象無需知道底層的持久化技術(shù)的細節(jié). Spring JPetStore中使用了iBATIS框架.

          下面讓我們來看一下應(yīng)用中的細節(jié)內(nèi)容吧, 先在Eclipse下把應(yīng)用加進來方便調(diào)試, 運行.

          Eclipse可到(http://www.eclipse.org/downloads/上下載)他是壓縮包解壓后就可用(可以再去下MyEclipe http://www.myeclipse.com是Eclipese的開發(fā)插件方便開發(fā), 不過要付費可以下載它的破解文件http://jinxinxin.bokee.com/inc/myeclipse_keygens.rar?MyEclipse的安裝如果不會去Google一下吧). 好了開發(fā)工具安裝后新建一工程jpetstore, 然后用..\spring-jpetstore\samples\jpetstore下的src目錄復(fù)蓋你的eclipse工作空間下的\jpetstore下的src目錄,然后再把..\spring-jpetstore\samples\jpetstore下的war目錄下的全部內(nèi)容拷到你的eclipse工作空間下的\jpetstore下的WebRoot目錄下復(fù)蓋WEB-INF.回到eclipse下刷新工程你可看到如下:

          e.jpg



          先從數(shù)據(jù)訪問層說起吧, 他使用iBATIS框架來訪問數(shù)據(jù)庫,在..\spring-jpetstore\samples\jpetstore\db目錄下有它的各種數(shù)據(jù)庫的schema有hsql, mysql, oracle, postges你使用拿一種數(shù)據(jù)庫是通過..\spring-jpetstore\samples\jpetstore\war\WEB-INF下的jdbc.properties來配置的.默認的是hsql數(shù)據(jù)庫:
          # Properties file with JDBC-related settings.
          # Applied by PropertyPlaceholderConfigurer from "dataAccessContext-local.xml".
          # Targeted at system administrators, to avoid touching the context XML files.

          jdbc.driverClassName=org.hsqldb.jdbcDriver
          jdbc.url=jdbc:hsqldb:hsql://localhost:9002
          jdbc.username=sa
          jdbc.password=
          要改為用mysql只要改為:
          #jdbc.driverClassName=org.hsqldb.jdbcDriver
          #jdbc.url=jdbc:hsqldb:hsql://localhost:9002
          #jdbc.username=sa
          #jdbc.password=

          jdbc.driverClassName=com.mysql.jdbc.Driver
          jdbc.url=jdbc:mysql://localhost:3306/jpetstore
          jdbc.username=root
          jdbc.password=

          即可.業(yè)務(wù)層能過...jpetstore.dao包下的接口來訪問....jpetstore.dao.ibatis包從而通過iBATIS框架訪問數(shù)據(jù)庫中的數(shù)據(jù)的部份代碼如下:

          package org.springframework.samples.jpetstore.dao;
          public interface AccountDao {

          ? Account getAccount(String username, String password) throws DataAccessException;

          ? ...........

          }

          package org.springframework.samples.jpetstore.dao.ibatis;
          public class SqlMapAccountDao extends SqlMapDaoSupport implements AccountDao {

          ??? public Account getAccount(String username, String password) throws DataAccessException {
          ??? Account account = new Account();
          ??? account.setUsername(username);
          ??? account.setPassword(password);
          ??? return (Account) getSqlMapTemplate().executeQueryForObject("getAccountByUsernameAndPassword", account);
          ? }
          ..............
          }

          Account.xml

          <mapped-statement name="getAccountByUsernameAndPassword" result-map="result">
          ??? select
          ????? SIGNON.USERNAME as USERID,
          ????? ACCOUNT.EMAIL,
          ????? ACCOUNT.FIRSTNAME,
          ????? ACCOUNT.LASTNAME,
          ????? ACCOUNT.STATUS,
          ????? ACCOUNT.ADDR1,
          ????? ACCOUNT.ADDR2,
          ????? ACCOUNT.CITY,
          ??????..???
          ??? from ACCOUNT, PROFILE, SIGNON, BANNERDATA
          ??? where ACCOUNT.USERID = #username#

          ????? and SIGNON.PASSWORD = #password#
          ????? and SIGNON.USERNAME = ACCOUNT.USERID
          ????? and PROFILE.USERID = ACCOUNT.USERID
          ????? and PROFILE.FAVCATEGORY = BANNERDATA.FAVCATEGORY
          ? </mapped-statement>

          然后到了業(yè)務(wù)層, 業(yè)務(wù)層為表達層提供服務(wù),操縱數(shù)據(jù)層來完成業(yè)務(wù)邏輯比如從數(shù)據(jù)庫中讀出客啟信息傳給表達層 向數(shù)據(jù)庫中插入訂單等.業(yè)務(wù)層還要完成對數(shù)據(jù)庫操作的完整性,正確性即事務(wù)管理. 此應(yīng)用是通過Spring的AOP來完成無需編程實現(xiàn)如下:

          dataAccessContex-local.xml

          <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
          ??<property name="driverClassName"><value>${jdbc.driverClassName}</value></property>
          ??<property name="url"><value>${jdbc.url}</value></property>
          ??<property name="username"><value>${jdbc.username}</value></property>
          ??<property name="password"><value>${jdbc.password}</value></property>
          ?</bean>

          ?<!-- Transaction manager for a single JDBC DataSource -->
          <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
          ? <property name="dataSource">
          ?? <ref local="dataSource" />
          ? </property>
          ? <property name="mappingResources">
          ?? <list>
          ??? <value>org/springframework/samples/jpetstore/Hibernate/Account.hbm.xml</value>
          ?? </list>
          ? </property>
          ? <property name="hibernateProperties">
          ?? <props>
          ??? <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
          ??? <prop key="hibernate.show_sql">true</prop>
          ?? </props>
          ? </property>
          ?</bean>
          ?
          ?<!-- (see dataAccessContext-jta.xml for an alternative) -->
          <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
          ? <property name="sessionFactory">
          ?? <ref local="sessionFactory" />
          ? </property>
          ?</bean>

          ?<!-- SqlMap setup for iBATIS Database Layer -->
          ?<bean id="sqlMap" class="org.springframework.orm.ibatis.SqlMapFactoryBean">
          ??<property name="configLocation"><value>WEB-INF/sql-map-config.xml</value></property>
          ?</bean>


          ?<!-- ========================= DAO DEFINITIONS: IBATIS IMPLEMENTATIONS ========================= -->

          ?<bean id="accountDao" class="org.springframework.samples.jpetstore.dao.hibdaoimp.AccountDaoImp">
          ? <property name="sessionFactory">
          ?? <ref local="sessionFactory" />
          ? </property>
          ? ?
          ?</bean>
          ................

          </beans>

          applicationContex.xml

          <bean id="petStoreTarget" class="org.springframework.samples.jpetstore.domain.logic.PetStoreImpl">
          ??<property name="accountDao"><ref bean="accountDao"/></property>
          ??<property name="categoryDao"><ref bean="categoryDao"/></property>
          ??<property name="productDao"><ref bean="productDao"/></property>
          ??<property name="itemDao"><ref bean="itemDao"/></property>
          ??<property name="orderDao"><ref bean="orderDao"/></property>
          ?</bean>

          ?<!-- Transactional proxy for the JPetStore primary business object -->
          ?<bean id="petStore" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
          ??<property name="transactionManager"><ref bean="transactionManager"/></property>
          ??<property name="target"><ref local="petStoreTarget"/></property>
          ??<property name="transactionAttributes">
          ???<props>
          ????<prop key="insert*">PROPAGATION_REQUIRED</prop>
          ????<prop key="update*">PROPAGATION_REQUIRED</prop>
          ????<prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
          ???</props>
          ??</property>
          ?
          從上面的配置代碼我們可看到通過Spring的IOC完成了org.springframework.samples.jpetstore.domain.logic.PetStoreImpl等類的注入. 通過AOP用org.springframework.transaction.interceptor.TransactionProxyFactoryBean來完成事務(wù)代理
          業(yè)務(wù)層通過一個門面(facada)PetStoreFacade.java接口來為表達層提供服務(wù):

          package org.springframework.samples.jpetstore.domain.logic;
          public interface PetStoreFacade {

          ?Account getAccount(String username);

          ?Account getAccount(String username, String password);

          ?void insertAccount(Account account);

          ?void updateAccount(Account account);

          ..........
          }
          用PetStoreImp.java來實現(xiàn):

          package org.springframework.samples.jpetstore.domain.logic;

          public class PetStoreImpl implements PetStoreFacade, OrderService {

          ? private AccountDao accountDao;

          ?.........

          ?public void setAccountDao(AccountDao accountDao) {
          ??this.accountDao = accountDao;
          ?}


          ?public Account getAccount(String username) {
          ??? return this.accountDao.getAccount(username);
          ? }

          ? public Account getAccount(String username, String password) {
          ??return this.accountDao.getAccount(username, password);
          ? }

          ? public void insertAccount(Account account) {
          ??this.accountDao.insertAccount(account);
          ? }

          ? .......
          }

          表達層這里介紹Structs,Structs中通過PetStoreFacade接口來訪問業(yè)務(wù)層:

          package org.springframework.samples.jpetstore.web.struts;

          public abstract class BaseAction extends Action {

          ? private PetStoreFacade petStore;

          ?public void setServlet(ActionServlet actionServlet) {
          ??super.setServlet(actionServlet);
          ??ServletContext servletContext = actionServlet.getServletContext();
          ??WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
          ??this.petStore = (PetStoreFacade) wac.getBean("petStore");
          ?}

          ?protected PetStoreFacade getPetStore() {
          ??return petStore;
          ?}

          }


          public class SignonAction extends BaseAction {

          ? public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
          ???????AccountActionForm acctForm = (AccountActionForm) form;
          ????? String username = acctForm.getUsername();
          ????? String password = acctForm.getPassword();
          ????? Account account = getPetStore().getAccount(username, password);
          .....
          ??????????????? return mapping.findForward("success");
          ????}
          Structs框架通過struct-config.xml文來控制相關(guān)映射轉(zhuǎn)發(fā)的:????

          struct-config.xml???????

          <action path="/signon" type="org.springframework.samples.jpetstore.web.struts.SignonAction"
          ???name="accountForm" scope="request"
          ???validate="false">
          ???<forward name="success" path="/index.jsp"/>
          ??</action>

          關(guān)于jsp就不在多說了下面再來看一下它的web.xml文件:

          ??<context-param>
          ??<param-name>contextConfigLocation</param-name>
          ??<param-value>
          ???/WEB-INF/dataAccessContext-local.xml? /WEB-INF/applicationContext.xml
          ??</param-value>
          ???</context-param>

          <servlet>
          ??<servlet-name>context</servlet-name>
          ??<servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
          ??<load-on-startup>1</load-on-startup>
          ?</servlet>

          ?<servlet>
          ??<servlet-name>action</servlet-name>
          ??<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
          ??<load-on-startup>3</load-on-startup>
          ?</servlet>

          ?? ??<servlet-mapping>
          ???<servlet-name>action</servlet-name>
          ??
          ??<url-pattern>*.do</url-pattern>
          ?</servlet-mapping>

          ? 還有關(guān)于遠程機制有Caucho的Hessian(一個借助HTTP的二進制協(xié)議) Burlap(一個基于XML的借助HTTP的傳輸協(xié)議), Apache Axis提供的JAX-RPC(基于SOAP的借助HTTP傳輸?shù)膚eb serverice), 還有基于RMI的遠程調(diào)用.
          想了解更多還是自已細看里面的代碼吧!
          請繼續(xù)關(guān)注Spring JPetStore(三) 在其上實現(xiàn)自已的Sunlight Netstore

          posted on 2006-09-17 12:16 fds 閱讀(4275) 評論(6)  編輯  收藏 所屬分類: JAVA

          評論

          # re: Spring JPetStore(二) JPetStore的分析 2006-09-19 23:24 Supergoal

          對于JPetStore,我倒也研究過一點。總感覺它的業(yè)務(wù)層設(shè)計的不是很合理,僅僅通過一個Facade來對Dao進行了封裝,稍簡陋了一些。還有就是,數(shù)據(jù)分頁的功能都是在表示層里完成了,對于一個數(shù)據(jù)量較小的系統(tǒng)來說還能接受,如果數(shù)據(jù)量大的話,像它這種將所有結(jié)果集都保存在HttpSession中的做法實現(xiàn)是不敢恭維。  回復(fù)  更多評論   

          # re: Spring JPetStore(二) JPetStore的分析 2006-09-20 08:46 逆流的魚

          你好,我希望要一份代碼,謝謝。我的msn:ywg_2008@hotmail.com
          希望共同學(xué)習(xí)(java開發(fā)一年,主要用spring+hibernate(ibatis)+struts)。
          郵箱是 ywg2008@sohu.com  回復(fù)  更多評論   

          # re: Spring JPetStore(二) JPetStore的分析 2006-09-20 23:20 周先有

          @逆流的魚
          需要源碼和發(fā)布幫助請看:
          http://www.aygfsteel.com/linansengling/archive/2006/09/16/70041.html  回復(fù)  更多評論   

          # re: Spring JPetStore(二) JPetStore的分析 2006-09-21 00:48 周先有

          @Supergoal
          我也有同感, 你的分析很對當(dāng)數(shù)據(jù)量大, 或是用戶很多時JPetstore存在這樣的問題, 我的Java分頁技術(shù)的應(yīng)用實現(xiàn), 應(yīng)該能解決這種問題
          http://www.aygfsteel.com/linansengling/archive/2006/09/21/70960.html
          要不就用jdbc來控制有點煩不知大家是怎么搞定的  回復(fù)  更多評論   

          # re: Spring JPetStore(二) JPetStore的分析 2007-01-14 14:51 qiuguang

          我想要份源程序
          qiugaungmail@yahoo.com.cn
          謝謝!  回復(fù)  更多評論   

          # re: Spring JPetStore(二) JPetStore的分析[未登錄] 2009-11-04 10:40 leon

          好啊報錯  回復(fù)  更多評論   

          導(dǎo)航

          統(tǒng)計

          常用鏈接

          留言簿(3)

          隨筆分類(12)

          隨筆檔案(13)

          文章分類(1)

          文章檔案(2)

          相冊

          收藏夾(3)

          my like

          最新隨筆

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 剑阁县| 同德县| 邯郸县| 炉霍县| 龙里县| 文昌市| 马鞍山市| 蓝山县| 广饶县| 钟祥市| 壶关县| 安宁市| 巴南区| 明光市| 桐柏县| 白银市| 双柏县| 故城县| 梅州市| 扶风县| 华容县| 呈贡县| 吕梁市| 平和县| 会泽县| 柞水县| 文安县| 白城市| 始兴县| 河池市| 石阡县| 新龙县| 南宁市| 增城市| 上犹县| 分宜县| 左云县| 得荣县| 新蔡县| 黔西| 民勤县|