首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

将Struts、Spring跟ibatis的组合在一起

2012-08-26 
将Struts、Spring和ibatis的组合在一起三者的组合方式??? ??? Struts仍然是只负责MVC这部分。也就是说,虽然

将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"
??? ??? />
??? ??? </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"??? <!-- 这位就是管理事务的经理了 -->
??? ??? 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"??? <!-- 这里定义了数据源 -->
??? ??? 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"
??? ??? /> <!-- 这里定义了ibatis的配置文件所在的位置 -->
??? ??? <property name="dataSource" ref="dataSource" />
??? </bean>

??? -<!-- 下面定义了DAO对象 -->
???
??? <bean id="userDao" ref="sqlMapClient" />
??? </bean>

??? <bean id="orderDao" ref="sqlMapClient" />
??? </bean>

??? <bean id="proDao" ref="sqlMapClient" />
??? </bean>

??? <bean id="errDao" ref="sqlMapClient" />
??? </bean>

<!-- 这里就是Facade了,注意,它有个parent属性,就是这个属性,使它的操作受到了事物管理的限制 -->
??? <bean id="baseFacade" parent="baseTransactionProxy">
??? ??? <property name="target">
??? ??? ??? <bean 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" column="login_user_name" /><!-- Bean中的属性和查询结果的列对应 -->
??? ??? <result property="password" column="login_password" />
??? </resultMap>

??? <typeAlias alias="user" type="form.LoginUserForm" /><!-- 定义了别名,注意,不能有重复 -->
???
??? <select id="selectUser" parameterresultMap="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;
??? ??? }
??? ???
??? }

热点排行