Spring webwork ibatis初探(一)

本文中的示例采用的环境:
JDK版本1.5.0.09 NetBeans 版本5.5 Mysql版本5.0
Webwork版本2.2.5 Spring版本 ibatis版本2.3.6.77 Spring版本2.0

项目路径如下图
[img]http://116.img.pp.sohu.com/images/2007/4/24/23/11/112bbc79d04.GIF[/img]

开始之前先配置Log4j支持,
log4j.properties位于$源代码$/log4j.properties
[code]
log4j.rootLogger=INFO,M1,R1
log4j.appender.R1=org.apache.log4j.ConsoleAppender
log4j.appender.R1.layout=org.apache.log4j.PatternLayout
log4j.appender.R1.layout.ConversionPattern=%p %-2d{yyyy-MM-dd HH:mm:ss} %c \n %m%n
[/code]

开始步入:
第一步:整合Spring+webwork
本文中采用的整合方法是Spring的管理ObjectFactory的模式,
主要步骤
1.在webwork.properties中设置,位于$源代码$/webwork.properties
[code]
webwork.action.extension=jspa,action,do
webwork.objectFactory=spring
webwork.objectFactory.spring.autoWire = type
[/code]

2.在web.xml中添加应用上下文监听器,位于$源代码$/web.xml
[code]
<listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/applicationContext.xml</param-value>
</context-param>
[/code]
注意别忘记设置过滤器,使用webwork
[code]
<filter>
<filter-name>webwork</filter-name> <filter-class>com.opensymphony.webwork.dispatcher.FilterDispatcher</filter-class>
</filter>
<filter-mapping>
<filter-name>webwork</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
[/code]

3.在xwork中添加处理的Action,xwork.xml位于$源代码$/xwork.xml
[code]
<!DOCTYPE xwork PUBLIC "-//OpenSymphony Group//XWork 1.0//EN"
"http://www.opensymphony.com/xwork/xwork-1.1.dtd">
<xwork>
<include file="webwork-default.xml"/>
<package name="qry" extends="default" namespace="/user">
<action name="qryUser" class="com.phenix.webwork.action.qryUserAction">
<result name="success" type="dispatcher">/user/result.jsp</result>
<interceptor-ref name="params"/>
</action>
</package>
</xwork>
[/code]
以上的操作以后,基本Spring和Webwork就可以一起工作了,不过本例中涉及的应用实际不是很复杂,故没有在Spring中注册bean,仅仅把Spring作为了一个Ioc容器来使用事务以及ibatis而已。
具体细节请参考[url]http://www.opensymphony.com/webwork/wikidocs/Spring.html[/url]
更简单的Spring+webwork整合请参考:
[url]http://forum.iteye.com/viewtopic.php?t=9939&highlight=spring+autowire[/url]


第二部分:整合Spring和Ibatis
1.在Spring的应用上下文中配置数据库,事务,以及ibatis的配置文件位置,applicationContext.xml文件,位于$源代码$/applicationContext.xml
[code]
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<!--通过注册PropertyPlaceholderConfigurer,来调用外部资源文件,文件中定义了数据库信息-->
<beans >
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:com/phenix/database/jdbc.properties</value>
</list>
</property>
</bean>
<!--通过BasicDataSource使用数据源-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</bean>
<!--配置ibatis的资源文件载入-->
<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="configLocation"> <value>classpath:com/phenix/ibatis/mapping/sqlMap-config.xml</value> </property>
</bean>
<!--注册事务管理Bean-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource"><ref local="dataSource"/></property>
</bean>
<!--注册DAO-->
<bean id="userDAO" class="com.phenix.ibatis.dao.UserDAO">
<property name="dataSource"> <ref local="dataSource" /> </property>
<property name="sqlMapClient"> <ref local="sqlMapClient" /> </property>
</bean>
<--注册DAO代理-->
<bean id="userDAOProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
<property name="transactionManager"><ref bean="transactionManager" /></property>
<property name="target"><ref local="userDAO" /></property>
<!--指明事务属性-->
<property name="transactionAttributes">
<props>
<prop key="insert*">PROPAGATION_REQUIRED</prop>
<prop key="get*">PROPAGATION_REQUIRED,readOnly</prop>
</props>
</property>
</bean>
</beans>
[/code]
2.配置sqlMap-config.xml-0位于$源代码
$/com/phenix/ibatis/mapping/sqlMap-config.xml
[code]
<?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>
<sqlMap resource="com/phenix/ibatis/mapping/User.xml" />
</sqlMapConfig>
[/code]
注意,由于本例中的数据库配置在外部资源文件中,所以此时注意建立一个jdbc.properteis
位于$源代码$/com/phenix/database/jdbc.properties
[code]
jdbc.driverClassName = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://localhost:3306/usetest
jdbc.username = root
jdbc.password = 123
[/code]

基本整合就是这2个配置文件,剩下的就开始主要代码部分

User.xml ---ibatis的sql映射文件
位于$源代码$/com/phenix/ibatis/mapping/User.xml
[code]
<?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="User">

<typeAlias alias="user" type="com.phenix.ibatis.action.User" />

<select id="getUserByName" parameterClass="java.lang.String" resultClass="user">
<![CDATA[
SELECT *
FROM admin
WHERE name = #name# ]]>
</select>

<select id="getUserById" parameterClass="java.lang.Integer" resultClass="user">
<![CDATA[
SELECT *
FROM admin
WHERE id = #id# ]]>
</select>

<select id="getAllUser" resultClass="java.util.ArrayList">
<![CDATA[
SELECT *
FROM admin]]>
</select>
<insert id="insertUser" parameterClass="user">
INSERT INTO admin(name,password)
VALUES(#name#,#password#)
</insert>
<update id="updateUserById" parameterClass="user">
UPDATE admin
SET name=#name# ,
password=#password#
</update>
</sqlMap>
[/code]

User.java --映射对象 位于com.phenix.ibatis/action/User.java
[code]
package com.phenix.ibatis.action;
import java.io.Serializable;
public class User implements Serializable{

public User() {
}
private String password;
private String name;
private Integer Id;

public Integer getId() {
return Id;
}
public void setId(Integer Id) {
this.Id = Id;
}
public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}

public String getname() {
return name;
}
public void setname(String name) {
this.name = name;
}
}
[/code]
UserDAO.java和IUserDAO.java---DAO接口和实现类
[code]
package com.phenix.ibatis.dao;
import com.phenix.ibatis.action.User;
import java.util.ArrayList;
public interface IUserDAO {
public ArrayList getAllUser();
public User getUserById(Integer Id);
public void insertUser(User user);
public void updateUser(User user);
public User getUserByName(String name);
}
[/code]
[code]
package com.phenix.ibatis.dao;
import com.phenix.ibatis.action.User;
import java.util.ArrayList;
import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport;

public class UserDAO extends SqlMapClientDaoSupport implements IUserDAO {
public UserDAO() {
}
public ArrayList getAllUser() {
return (ArrayList)getSqlMapClientTemplate().queryForList("getAllUser","");
}
public User getUserById(Integer Id) {
return (User)getSqlMapClientTemplate().queryForObject("getUserById",Id);
}

public User getUserByName(String name)
{
return (User)getSqlMapClientTemplate().queryForObject("getUserByName",name);
}

public void insertUser(User user) {
getSqlMapClientTemplate().insert("insertUser",user);
}
public void updateUser(User user) {
getSqlMapClientTemplate().update("updateUser",user);
}

}
[/code]
QryUserAction.java---具体实现交互的Action
[code]
public class QryUserAction implements Action{
private String params;
private String qryType;
private User user;
private ArrayList userList;
/**
* Creates a new instance of QryUserAction
*/
public QryUserAction() {
}
static Logger logger = Logger.getLogger(QryUserAction.class);
public String execute() throws Exception
{
//获取应用上下文
ApplicationContext factory = (ApplicationContext)ActionContext.getContext().getApplication().get(
WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
//获取Bean
IUserDAO userDAO = (IUserDAO)factory.getBean("userDAOProxy");
//根据提交过来的参数,选择按Id还是按照Name查找

if(qryType.equals("name"))
{
user = userDAO.getUserByName(params);
}
else
{
Integer id = Integer.parseInt(params);
user = userDAO.getUserById(id);
}

return SUCCESS;
}
public void setParams(String params)
{
this.params=params;
}
public void setQryType(String qryType)
{
this.qryType=qryType;
}

public User getUser()
{
return user ;
}

}
[/code]
"这段代码似乎并没有什么特殊,但有一个细微之处:
IUserDAO userDAO = (IUserDAO)factory.getBean("userDAOProxy");
这里并没有直接用UserDAO对获得的Bean实例进行强制转型。并非完全出自设计上的考虑,这里情况有些特殊,我们可试一下用UserDAO类对bean实例进行强制转型,不过将得到一个ssCastException,程序异常中止。
为什么会出现这样的问题?原因在于Spring的AOP实现机制,前面曾经提及,Spring中的事务管理实际上是基于AOP机制实现,为了实现动态AOP,Spring在默认情况下会使用Java DynamicPoxy,但是要求其代理的对象必须实现一个接口,该接口定义了准备代理的方法。而对于没有实现任何接口的Java Class,需要采用其他方式,Spring通过CGLib 实现这一功能。
当UserDAO没有实现任何接口时,Spring通过CGLib对rDAO进行代理,此时getBean返回的是一个继承自UserDAO类的子类实例,可以通过UserDAO对其强制转型。而当UserDAO实现了IUserDAO接口之后,Spring将通过JavaDynamic Proxy机制实现代理功能,此时返回的Bean,是通过javaa.lang.reflect.Proxy.newProxyInstance方法创建的IUserDAO接口的一个代理实这个实例实现了IUserDAO接口,但与UserDAO类已经没有继承关系,因此无法通过UserrDAO强制转型。"
---引自夏昕《Spring开发指南》

下面是2个显示的页面文件
search.jsp位于$页面$/user/search.jsp
[code]
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>查询</title>
</head>
<body>

<h1>查询</h1>

<form action="qryUser.do" method="POST">
<select name="qryType">
<option value="name" selected>Name</option>
<option value="id">ID</option>
</select>
<input type="text" name="params" value="" size="12" />
<input type="submit" name="submit" value="提交" />
</form>

</body>
</html>
[/code]
result.jsp--结果显示页面
[code]
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title查询结果页面</title>
</head>
<body>
<h1>查询结果页面</h1>
<ww:if test="user==null">
<font color="red"> <ww:actionerror/></font>
</ww:if>
<ww:else>
用户ID:${user.id}
用户名:${user.name}
密码:${user.password}
</ww:else>
</body>
</html>
[/code]

本文参考:夏昕-《Spring开发指南v0.8预览版》
《Spring2.0 reference_final》
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值