【原创】项目中Spring MVC + Ibatis的一点理解

本人不才,刚接触Ibatis不久,然后需要整和到项目中,下面是和Spring+Ibatis的实现,欢迎拍砖,撒花。。。

Web.xml中  

#片段1:
<servlet>
    <servlet-name>AcubeFramework</servlet-name>

        <servlet-class>

        com.sds.acube.framework.core.servlet.AcubeDispatcherServlet

        </servlet-class>

        <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>

    <servlet-name>AcubeFramework</servlet-name>

    <url-pattern>*.do</url-pattern>
</servlet-mapping>

那么必须有个AcubeFramework-servlet.xml文件,这是spring实现MVC的主配置文件(包含请求拦截[View],bean的管理[Control],与数据库之间的交互[Model]等等)
因为在这个项目中AcubeDispatcherServlet 继承了 DispatcherServlet 并且重写了init()方法,在init()web容器启动即调用,中做了一些与ContextLoaderListener相似的工作,与下面的代码片段达到的功能一致

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">

<display-name>Spring Annotation MVC Sample</display-name>
<!--  Spring 服务层的配置文件 ContextLoaderListener监听器先对contextConfigLocation进行检查,有并且有多个用分隔符分开(逗号,空格),如果没有设置该参数,将从/web-info/applicationContext.xml作为默认值-->
<context-param>
<param-name>contextConfigLocation</param-name>        
    <param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!--  Spring 容器启动监听器 初始化Spring的一些配置信息,web容器启动即加载-->
<listener>        
    <listener-class>
org.springframework.web.context.ContextLoaderListener 
    </listener-class>
</listener>
<!--  Spring MVC 的Servlet,它将加载WEB-INF/annomvc-servlet.xml 的配置文件,以启动Spring MVC模块,下面的代码块被上面得“#片段1”代码块代替-->
<servlet>
<servlet-name>annomvc</servlet-name>
    <servlet-class>
        org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <load-on-startup>2</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>annomvc</servlet-name>
    <url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>


AcubeFramework-servlet.xml  部分片断

<!-- Other ViewResolvers Added -->
<bean id="defaultViewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property
        name="viewClass"
        value="org.springframework.web.servlet.view.JstlView"/>
    <property name="prefix" value=""/>
    <property name="suffix" value=""/>
</bean>
<import resource="/classes/config/pkm/pkm-context.xml"/>


在下面Pkm-context.xml中 (引入view.property,pkm-sqlmap.xml 和  pkm-blog-spring.xml)

<!--ViewResolvers  - configuration : /WEB-INF/classes/config/views.properties   -->

<bean id="otherViewResolver"
class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
    <property name="order" value="1" />

    <property name="basename" value="config.views" /><!--用来绑定/WEB-INF/classes/config/views.properties 资源文件view层-->

    <property name="defaultParentView" value="defaultViewResolver" />

</bean>
 

<bean id="pkmSqlMapClient"

    class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
    <property name="dataSource"><ref local="pkmDataSource" />
    </property>
    <property name="configLocation">

      <value>/WEB-INF/classes/config/pkm/pkm-sqlmap.xml</value>

    </property>
    <!-- SqlMap Config for iBATIS  Spring中整合了Ibatis通过SqlMapClientFactoryBean来解析pkm-sqlmap.xml读取其中的信息-->
</bean>

<!--连接池-->  
<bean id="pkmDataSource"    
class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" lazy-init="false">  
    <property name="driverClassName" value="${pkm.jdbc.driverClassName}"/>  
    <property name="url" value="${pkm.jdbc.url}"/>  
    <property name="username" value="${pkm.jdbc.username}"/>  
    <property name="password" value="${pkm.jdbc.password}"/>  
    <property name="initialSize" value="5"/>  
    <property name="maxActive" value="10"/>  
    <property name="maxWait" value="60000"/>  
    <property name="poolPreparedStatements" value="true"/>     
</bean>

<bean id="propertyConfigurer"    
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">  
<!--PropertyPlaceholderConfigurer类来读取xxx.properties配置文件信息,以key和value的形式-->  
<property name="locations">  
    <list>  
        <value>  
          /WEB-INF/classes/config/pkm/environment/jdbc.properties   
        </value>  
        <value>  
          <!--多个xxx.properties文件-->  
        </value>  
    </list>  
</property>  
</bean> 

<import resource="/blog/pkm-blog-spring.xml" />


jdbc.properties文件中的配置如下
pkm.jdbc.driverClassName=oracle.jdbc.OracleDriver   
pkm.jdbc.url=jdbc\:oracle\:thin\:@109.52.20.31\:1521\:orcl<!--把符号做转译-->   
pkm.jdbc.username=pkmuser   
pkm.jdbc.password=dbl0gin   
pkm.jdbc.dataSource=pkmDataSource  


在config/view.property 文件中配置如下

RegistBlognityGrouping.class=org.springframework.web.servlet.view.JstlView

RegistBlognityGrouping.url=/jsp/pkm/blog/RegistBlognityGrouping.jsp

RegistBlognityGrouping是 在返回ModelAndView对象所定位的字符串
这样以来Spring完成了对view层分层封装


pkm-sqlmap.xml文件中 配置了与数据库交互的SQL文件通过pkmSqlMapClient来读取

<sqlMapConfig>
    <settings
        cacheModelsEnabled="false"

        enhancementEnabled="true"

        lazyLoadingEnabled="true"

        useStatementNamespaces="true"/>

    <sqlMap resource="config/pkm/blog/sqlmap/Grouping-SQL.xml"/>
    <sqlMap resource="config/pkm/blog/sqlmap/TeamWebsiteManage-SQL.xml"/> 

<!--可以配置更多的xxx   -SQL.xml文件-->

</sqlMapConfig>



pkm-blog-spring.xml文件 (配置view层面的URL mapping和bussiness功能 bean的依赖关系) 按模块可以拆分成多个配置文件

附加部分Java 代码方便理解
public class GroupingFormController extends SimpleFormController{
    
    protected ModelAndView OnSubmit(HttpServletRequest request,HttpServletResponse response, Object command, BindException errors)throws Exception {
    
    Grouping grouping = (Grouping)command;//command 所代表的 Formbean对象是可以直接强转为某个实体bean对象的,主要设置了commandClass
    
    WebApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
    
    GroupingProxyService groupingProxyService = ctx.getBean("groupingProxyService")//必须有一个groupingProxyService "<bean>...</bean>"
    
    if(...){
     
       return new ModelAndView(getSuccessView(),"list",list );
    
    }else{
        return new ModelAndView(getFormView());
    }
  }  

}


<!-- Handler Mappings -->

<bean id="blogHandlerMapping"   class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">

    <property name="order" value="2" />

    <property name="mappings">

       <props>

         <prop

key="/*/blog/RegistBlognityGrouping.go">GroupingFormController</prop>
        <!--也可以配制多个prop,一般都会按功能分成多个xml文件-->
       </props>

    </property>

</bean>

<!--
GroupingFormController  (继承)extends SimpleFormController  用于处理一些简单的表单
-->
<bean id="GroupingFormController"

class="com.sds.acube.wp.pkm.blog.controller.GroupingFormController">

    <property name="sessionForm" value="true"></property>

    <property name="commandName" value="command"></property>
    <!--Spring 绑定表单的command对象-->

    <property name="commandClass" value="com.sds.acube.wp.pkm.blog.dmo.Grouping"></property>
    <!--有默认的构造方法,可被实例化的JavaBean -->
    <!--command 所代表的 Formbean对象是可以直接强转为某个实体bean对象的,主要设置了commandClass-->

    <!--show form view -->
    <property name="formView" value="RegistBlognityGrouping"></property>
    <!--显示表单不需要任何代码,Spring自动完成,所以在提交该表单的时候,Spring通过formView的属性来获知该页面提交的action地址,不像Struts显示和提交是2个不同的地址 在GroupingFormController中调用OnSubmit(...)方法,验证失败会调用getFormView() 方法,直接返回RegistBlognityGrouping.jsp 页面-->

    <!--submit form success view-->
    <property name="successView" value="RegistBlognityGrouping.go"></property>
<!-- 在GroupingFormController中调用OnSubmit(...)方法,成功会调用getSuccessView() 方法,执行RegistBlognityGrouping.go之后的页面-->

    <property name="groupingService"><ref local="groupingProxyService" /></property><!-- service -->

</bean>

<!-----------------------两种Controller 分割线------------------------->
<!--
GroupingController 继承(extends) MultiActionController  多用于各类查询
-->
<bean id="GroupingController"

    class="com.sds.acube.wp.pkm.blog.controller.GroupingController">

    <property name="groupingService"><ref local="groupingService"/></property>

    <property name="methodNameResolver"><ref local="groupingMethodNameResolver"/></property>

</bean>

<!--ParameterMethodNameResolver  请求需要哪一个方法做处理 例如exec=list-->
<bean id="groupingMethodNameResolver"
  class="org.springframework.web.servlet.mvc.multiaction.ParameterMethodNameResolver">

    <property name="paramName"><value>exec</value></property>

    <property name="defaultMethodName"><value>list</value></property>

</bean>

<!--将pkmSqlMapClient注入到DAO中-->
<bean id="groupingDAO"
class="com.sds.acube.wp.pkm.blog.dao.impl.GroupingSqlMapDAOImpl">

    <property name="sqlMapClient"><ref bean="pkmSqlMapClient"/></property>

</bean>

<!--这样以来Spring 与 Ibatis就整合一块了-->




DAO注意
GroupingSqlMapDAOImpl中的代码片段

import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;

/*
SqlMapClientDaoSupport 是Spring对ibatis提供的支持类,跟整和Struts提供的ActionSupport类一个意思
*/
public class GroupingSqlMapDAOImpl implements GroupingSqlMapDAO//extends SqlMapClientDaoSupport 
{
    private pkmSqlMapClient sqlMapClient;

    public void setSqlMapClient(SqlMapClient sqlMapClient) {
        this.sqlMapClient = sqlMapClient;
    }

   public List getGroupingList() {
      try {
          return sqlMapClient.queryForList("Grouping.getGroupingList");

   // Grouping 是Grouping-SQL.xml中 的namespace ,  getGroupingList 是SQL的id

   } catch (Exception e) {

           throw makeException(e);

       }

   }
}


在Grouping-SQL.xml中

<!--resultMap,resultClass,parameterClass都可以是除了JavaBean对象以外的其他类型,例如java.util.HashMap,java.lang.String等等-->

<sqlMap namespace="Grouping">

   <typeAlias type="com.sds.acube.wp.pkm.blog.dmo.Grouping" alias="Grouping" />

   <resultMap id="grouping-list" class="Grouping">
   <!--class可以写 alias-->

      <result property="id" column="ID" />

      <result property="name" column="NAME" />

      <result property="intid" column="INTID" />

      <result property="description" column="DESCRIPTION" />

   </resultMap>

  <resultMap id="grouping-list-count" class="Grouping"      extends="grouping-list">

      <result property="groupingTeamManageCount" column="GROUPINGTEAMMANAGECOUNT" />

      <result property="groupingWebSiteCount" column="GROUPINGWEBSITECOUNT" />

   </resultMap>

   <insert id="insertGrouping" parameterClass="Grouping">
   <!--parameterClass是作为参数传递的类型,可以是一个JavaBean或者java.util.HashMap等一些类型-->

      <![CDATA[

        INSERT INTO bg_websitecategory(id, name, intid, description)

        VALUES(#id#, #name#, #intid#, #description#)

      ]]>

   </insert>

   <select id="getGroupingList" resultMap="grouping-list-count">
   <!--resultMap 在上面配置的属性和字段的映射关系,通过反射将属性映射到字段上-->

      <![CDATA[

            SELECT wc.id as id,

                   wc.name as name,

                   wc.intid as intid,

                   wc.description as description,

                   ( select count(1) 

                    FROM bg_teamwebsite_manage 

                    WHERE website_category_id = wc.id

                   ) as groupingTeamManageCount,

                   ( select count(1) 

                    FROM bg_website 

                    WHERE website_category_id = wc.id

                   ) as groupingWebSiteCount

            FROM bg_websitecategory wc 

            ORDER BY CAST(wc.intid as NUMBER(4,0)) ASC

      ]]>

      <!-- <include refid="selectListQuery"/> -->

   </select> 

   <insert id="updateGrouping" parameterClass="Grouping">

   </insert>

   <insert id="deleteGrouping" parameterClass="Grouping">

   </insert>

</sqlMap>


小结:
这次的项目大体的架子 prototype + Spring + Ibatis实现,前台View层 prototype将Spring Controller返回的ModelAndView对象所返回的数据(可以是HTML,XML)用于展示,中间bussiness层,Spring Controller 拦截请求,获取参数值,在通过Spring的IOC 将Ibatis整合,并且通过持久层的Ibatis与数据库交互,在这将系统的流程用一根绳子串了起来,刚好与系统的设计的方向是反过来的。

你可能感兴趣的:(spring,xml,mvc,ibatis,项目管理)