本人不才,刚接触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与数据库交互,在这将系统的流程用一根绳子串了起来,刚好与系统的设计的方向是反过来的。