spring ibatis

將Struts、Spring和ibatis的組合在一起
三者的組合方式
   
    Struts仍然是隻負責MVC這部分。也就是說,雖然項目中是使用三者相結合的方式,但實際上,Strtus的配置文件,與Spring和ibatis是獨立的。
   
    而Spring和ibatis則組合在一起負責項目中數據庫操作的部分。在ibatis中定義相關的數據庫操作和映射。而由Spring的ORM包負責製作DAO對象。並利用Spring的事務管理機制,再將DAO對象包裝進Facade對象中。
   
    所以,此文的重點是Spring和ibatis的組合。
   
    Spring和ibatis的配置文件可以放在許多地方,既可以放在Web Root下,也可以放在ClassPath下。區別就在於取得配置文件的方式不一樣。這個放到最後再說。
   
    練習項目中,Spring和ibatis的配置文件都是放在/WEB-INF/下了,而ibatis的具體數據庫操作、映射的配置文件是放在ClassPath裏的包中的。此文就以此來說明。
   
   
建立配置文件
   
applicationContext.xml
   
    建立Spring配置文件:
   
    首先,在WEB-INF/這個目錄下建立一個Spring的配置文件,名爲applicationContext.xml,內容如下
   
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
    <import resource="ibatis-config.xml"/> <!-- 這裏導入了另一個文件,如果在web.xml中聲明瞭就不用寫 -->

    <bean id="baseTransactionProxy"
        class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
        abstract="true">
        <property name="transactionManager">   <!-- 它有個屬性叫“事務經理”,下面會聲明的 -->
            <ref bean="transactionManager" />
        </property>
        <property name="transactionAttributes">    <!--這裏就聲明瞭具體的事務 -->
            <props>
                <prop key="insert*">PROPAGATION_REQUIRED</prop>
                <prop key="update*">PROPAGATION_REQUIRED</prop>
                <prop key="check*">PROPAGATION_REQUIRED</prop>
                <prop key="del*">PROPAGATION_REQUIRED</prop>
                <prop key="forbid*">PROPAGATION_REQUIRED</prop>
                <prop key="inforbid*">PROPAGATION_REQUIRED</prop>
                <prop key="change*">PROPAGATION_REQUIRED</prop>
                <prop key="process*">PROPAGATION_REQUIRED</prop>
                <prop key="finish*">PROPAGATION_REQUIRED</prop>
                <prop key="redo*">PROPAGATION_REQUIRED</prop>
                <prop key="reject*">PROPAGATION_REQUIRED</prop>
                <prop key="confirm*">PROPAGATION_REQUIRED</prop>
                <prop key="cancel*">PROPAGATION_REQUIRED</prop>
                <prop key="undel*">PROPAGATION_REQUIRED</prop>
                <prop key="modify*">PROPAGATION_REQUIRED</prop>
                <prop key="copy*">PROPAGATION_REQUIRED</prop>
                <prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
            </props>
        </property>
    </bean>

    <bean id="transactionManager"    <!-- 這位就是管理事務的經理了 -->
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>
    </beans>
   

ibatis-config.xml

    然後,寫另一個名爲ibatis-config.xml的Spring配置文件,裏面配置了數據庫的連接,以及各個DAO和包裝這些DAO的Facade。
   
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>

    <bean id="dataSource"    <!-- 這裏定義了數據源 -->
        class="org.apache.commons.dbcp.BasicDataSource"
        destroy-method="close">
        <property name="driverClassName" value="org.postgresql.Driver" />
        <property name="url"
            value="jdbc:postgresql://localhost:5432/webtest" />
        <property name="username" value="postgres" />
        <property name="password" value="postgres" />
        <property name="maxActive">
            <value>20</value><!-- -1 means no limit -->
        </property>
        <property name="maxIdle">
            <value>10</value>
        </property>
        <property name="maxWait">
            <value>5000</value>
        </property>
        <property name="initialSize">
            <value>4</value>
        </property>
        <property name="maxOpenPreparedStatements">
            <value>-1</value><!-- -1 means no limit -->
        </property>
    </bean>


    <!-- SqlMap setup for iBATIS Database Layer -->
    <bean id="sqlMapClient"
        class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
        <property name="configLocation"
            value="/WEB-INF/sqlMapConfig.xml" /> <!-- 這裏定義了ibatis的配置文件所在的位置 -->
        <property name="dataSource" ref="dataSource" />
    </bean>

    -<!-- 下面定義了DAO對象 -->
   
    <bean id="userDao" class="dao.user.UserDao">
        <property name="sqlMapClient" ref="sqlMapClient" />
    </bean>

    <bean id="orderDao" class="dao.order.OrderDao">
        <property name="sqlMapClient" ref="sqlMapClient" />
    </bean>

    <bean id="proDao" class="dao.base.ProductClassDao">
        <property name="sqlMapClient" ref="sqlMapClient" />
    </bean>

    <bean id="errDao" class="dao.base.ErrorClassDao">
        <property name="sqlMapClient" ref="sqlMapClient" />
    </bean>

<!-- 這裏就是Facade了,注意,它有個parent屬性,就是這個屬性,使它的操作受到了事物管理的限制 -->
    <bean id="baseFacade" parent="baseTransactionProxy">
        <property name="target">
            <bean class="facade.BaseFacadeImpl"><!-- 把DAO做爲屬性注入到Facade中去 -->
                <property name="proDao" ref="proDao" />
                <property name="errDao" ref="errDao" />
                <property name="userDao" ref="userDao" />
                <property name="orderDao" ref="orderDao" />
            </bean>
        </property>
    </bean>
</beans>
   
   
sqlMapConfig.xml
   
    好,接下來,根據在上個配置文件中的定義,在WEB-INF目錄下,創建ibatis的配置文件,也就是sqlMapConfig.xml:
   
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMapConfig PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN"
    "http://www.ibatis.com/dtd/sql-map-config-2.dtd">

<sqlMapConfig>

    <settings cacheModelsEnabled="true" enhancementEnabled="true"
        lazyLoadingEnabled="true" errorTracingEnabled="true" maxRequests="32"
        maxSessions="10" maxTransactions="5" useStatementNamespaces="false" />
<!-- 這裏定義了具體的SqlMap配置文件的位置,注意看路徑,是放在ClassPath目錄下的 -->
    <sqlMap resource="dao/ibatis/maps/userMap.xml" />
   
    <sqlMap resource="dao/ibatis/maps/baseMap.xml" />

    <sqlMap resource="dao/ibatis/maps/orderMap.xml" />

</sqlMapConfig>


userMap.xml

    之後,再給出一個SqlMap文件的內容。根據上面的定義,文件放在dao.ibtis.maps這個包下,名爲userMap.xml:
   
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap PUBLIC "-//iBATIS.com//DTD SQL Map 2.0//EN" "http://www.ibatis.com/dtd/sql-map-2.dtd">

<sqlMap namespace="userMap"><!-- 定義了命名空間 -->

    <resultMap id="result" class="form.LoginUserForm"><!-- 這裏就是映射關係了 -->
        <result property="username" column="login_user_name" /><!-- Bean中的屬性和查詢結果的列對應 -->
        <result property="password" column="login_password" />
    </resultMap>

    <typeAlias alias="user" type="form.LoginUserForm" /><!-- 定義了別名,注意,不能有重複 -->
   
    <select id="selectUser" parameterClass="user" resultMap="result"><!-- 定義了參數對象和返回的對象 -->
        select * from login_user where login_user_name=#username# and login_password=#password#
    </select>
</sqlMap>
   
   
web.xml
   
    好了,現在Spring和ibatis的配置文件都搞定了。下面就是具體的使用了。但是,爲了使程序能夠順利的拿到配置文件,我們還需要在web.xml配置一個監聽器,和一個Context參數。如下:
   
    <listener>
        <listener-class>   
            org.springframework.web.context.ContextLoaderListener
        </listener-class>
        </listener>
   
    <context-param>        <!-- 這裏配置了Spring文件的位置,如果有多個,用空格或回車分開 -->
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/applicationContext.xml</param-value>
        </context-param>    <!-- 如果這裏配置了多個文件,就不需要在Spring文件中用Import了 -->
   
   
    嗯,現在纔算是全部的配置文件都搞定了。
   
具體使用方法:
   
    衆觀全部的配置文件,最核心的部分,就是在Spring的配置文件中聲明過的,名叫baseFacade的Facade了。它擁有四個Dao作爲它的成員。Spring在實例化它時,會實例化這四個DAO對象,並把它們注入到Facade中去。好Cool!
   
    那,我們應該如何拿到這個Facade對象呢?別急,先看看我在這個練習項目中,這個Facade是如何被使用的。
   
    我建立了一個名叫BaseAction的類,它繼承自Struts中的Action類。在它裏面就放了一個Facade成員。之後,所有需要訪問到數據庫的Action都繼承自這個BaseAction,就可以直接調用父類中的Facade成員來執行相關的操作了。
   
    下面,給出BaseAction類的代碼:
   
    /**
    * in package action.base
    * BaseAction.java   
    * Jun 14, 2007
    */
    package action;
   
    <!-- 省去Imports細節 -->
   
    /**
    * @author liang-zhang
    *
    */
    public class BaseAction extends Action {
   
        private IBaseFacade baseFacade;
       
        @Override <!-- 覆蓋掉父類的初始化方法 -->
        public void setServlet(ActionServlet as) {
            // TODO Auto-generated method stub
            super.setServlet(as);<!-- 執行父類的方法 -->
           
    <!-- 這裏就可以拿到這個Facade實例了 -->
            ServletContext servletContext=as.getServletContext();
            WebApplicationContext wac =             WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
            this.baseFacade = (IBaseFacade) wac.getBean("baseFacade");
   
    <!-- 這是另一種拿法,Spring文件同樣在WEB-INF目錄下 -->
    <!-- 但是,SqlMapConfig文件似乎只能放在ClassPath目錄下 -->
    //        XmlBeanFactory factory = new XmlBeanFactory(new ServletContextResource(
    //        as.getServletContext(), "WEB-INF/applicationContext.xml"));
    //        this.baseFacade = (IBaseFacade) factory.getBean("baseFacade");
           
    <!-- 這是第三種拿法了,當所有的配置文件都入在ClassPath下時可用 -->
    //        XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource(
    //                "applicationContext.xml"));
    //        this.baseFacade = (IBaseFacade) factory.getBean("baseFacade");
        }
   
        public IBaseFacade getBaseFacade() {
            return baseFacade;
        }
   
        public void setBaseFacade(IBaseFacade baseFacade) {
            this.baseFacade = baseFacade;
        }
       
    }
   

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章