您的位置:首页 > 编程语言 > Java开发

MyBatis3整合Spring3、SpringMVC3

2011-04-15 10:06 926 查看
开发环境:

System:Windows

WebBrowser:IE6+、Firefox3+

JavaEEServer:tomcat5.0.2.8、tomcat6

IDE:eclipse、MyEclipse8

Database:MySQL

开发依赖库:

JavaEE5、Spring3.0.5、Mybatis3.0.4、myBatis-spring-1.0、junit4.8.2

Email:hoojo_@126.com

Blog:http://blog.csdn.net/IBM_hoojo

http://hoojo.cnblogs.com/

百度文库:http://wenku.baidu.com/view/34559702a6c30c2259019e4e.html

1、首先新建一个WebProject命名为MyBatisForSpring,新建项目时,使用JavaEE5的lib库。然后手动添加需要的jar包,所需jar包如下:





2、添加spring的监听及springMVC的核心Servlet,web.xml内容,内容如下:

[code]<!--加载Spring容器配置-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--设置Spring容器加载配置文件路径-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:applicationContext-*.xml</param-value>
</context-param>
<!--配置Spring核心控制器-->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/dispatcher.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<!--解决工程编码过滤器-->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
[/code]
3、在WEB-INF目录中添加dispatcher.xml,内容如下:


[code]<?xmlversion="1.0"encoding="UTF-8"?>
<beansxmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans>
'target='_blank'>http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
'target='_blank'>http://www.springframework.org/schema/context
'target='_blank'>http://www.springframework.org/schema/context/spring-context-3.0.xsd"
<!--注解探测器-->
<context:component-scanbase-package="com.hoo"/>
<!--annotation默认的方法映射适配器-->
<beanid="handlerMapping"class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>
<beanid="handlerAdapter"class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>
</beans>
[/code]
4、在src目录下添加applicationContext-common.xml,内容如下:


[code]<?xmlversion="1.0"encoding="UTF-8"?>
<beansxmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans>
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"
<!--配置DataSource数据源-->
<beanid="dataSource"class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<propertyname="driverClassName"value="com.mysql.jdbc.Driver"/>
<propertyname="url"value="jdbc:mysql://10.0.0.131:3306/ash2"/>
<propertyname="username"value="dev"/>
<propertyname="password"value="dev"/>
</bean>
<!--配置SqlSessionFactoryBean-->
<beanid="sqlSessionFactory"class="org.mybatis.spring.SqlSessionFactoryBean">
<propertyname="dataSource"ref="dataSource"/>
<propertyname="configLocation"value="classpath:mybatis.xml"/>
<!--mapper和resultmap配置路径-->
<propertyname="mapperLocations">
<list>
<!--表示在com.hoo.resultmap包或以下所有目录中,以-resultmap.xml结尾所有文件-->
<value>classpath:com/hoo/resultmap/**/*-resultmap.xml</value>
<value>classpath:com/hoo/entity/*-resultmap.xml</value>
<value>classpath:com/hoo/mapper/**/*-mapper.xml</value>
</list>
</property>
</bean>
<!--单独配置一个Mapper;这种模式就是得给每个mapper接口配置一个bean-->
<!--
<beanid="accountMapper"class="org.mybatis.spring.mapper.MapperFactoryBean">
<propertyname="mapperInterface"value="com.hoo.mapper.AccountMapper"/>
<propertyname="sqlSessionFactory"ref="sqlSessionFactory"/>
</bean>
<beanid="companyMapper"class="org.mybatis.spring.mapper.MapperFactoryBean">
<propertyname="mapperInterface"value="com.hoo.mapper.CompanyMapper"/>
<propertyname="sqlSessionFactory"ref="sqlSessionFactory"/>
</bean>
-->
<!--通过扫描的模式,扫描目录在com/hoo/mapper目录下,所有的mapper都继承SqlMapper接口的接口,这样一个bean就可以了-->
<beanclass="org.mybatis.spring.mapper.MapperScannerConfigurer">
<propertyname="basePackage"value="com.hoo.mapper"/>
<propertyname="markerInterface"value="com.hoo.mapper.SqlMapper"/>
</bean>
</beans>
[/code]
上面的配置最先配置的是DataSource,这里采用的是jdbc的DataSource;

然后是SqlSessionFactoryBean,这个配置比较关键。SqlSessionFactoryBean需要注入DataSource数据源,其次还要设置configLocation也就是mybatis的xml配置文件路径,完成一些关于mybatis的配置,如settings、mappers、plugin等;

如果使用mapperCannerConfigurer模式,需要设置扫描根路径也就是你的mybatis的mapper接口所在包路径;凡是markerInterface这个接口的子接口都参与到这个扫描,也就是说所有的mapper接口继承这个SqlMapper。

如果你不使用自己的transaction事务,就使用MapperScannerConfigurer来完成SqlSession的打开、关闭和事务的回滚操作。在此期间,出现数据库操作的如何异常都会被转换成DataAccessException,这个异常是一个抽象的类,继承RuntimeException;

5、SqlMapper内容如下:


[code]packagecom.hoo.mapper;
/**
*<b>function:</b>所有的Mapper继承这个接口
*@authorhoojo
*@createDate2011-4-12下午04:00:31
*@fileSqlMapper.java
*@packagecom.hoo.mapper
*@projectMyBatisForSpring
*@blog
'target='_blank'>http://blog.csdn.net/IBM_hoojo
*@emailhoojo_@126.com
*@version1.0
*/
publicinterfaceSqlMapper{
}
[/code]
6、实体类和ResultMap.xml


[code]packagecom.hoo.entity;
importjava.io.Serializable;
importjavax.persistence.Entity;
@Entity
publicclassAccountimplementsSerializable{
privatestaticfinallongserialVersionUID=-7970848646314840509L;
privateIntegeraccountId;
privateIntegerstatus;
privateStringusername;
privateStringpassword;
privateStringsalt;
privateStringemail;
privateIntegerroleId;
//getter、setter
@Override
publicStringtoString(){
returnthis.accountId+"#"+this.status+"#"+this.username+"#"+
this.password+"#"+this.email+"#"+this.salt+"#"+this.roleId;
}
}
[/code]
account-resultmap.xml


[code]<?xmlversion="1.0"encoding="UTF-8"?>
<!DOCTYPEmapperPUBLIC"-//mybatis.org//DTDMapper3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mappernamespace="accountMap">
<resultMaptype="com.hoo.entity.Account"id="accountResultMap">
<idproperty="accountId"column="account_id"/>
<resultproperty="username"column="username"/>
<resultproperty="password"column="password"/>
<resultproperty="status"column="status"/>
</resultMap>
</mapper>
[/code]
7、在src目录中添加applicationContext-beans.xml内容如下:


[code]<?xmlversion="1.0"encoding="UTF-8"?>
<beansxmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans>
'target='_blank'>http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
'target='_blank'>http://www.springframework.org/schema/context
'target='_blank'>http://www.springframework.org/schema/context/spring-context-3.0.xsd"
<!--注解探测器,在JUnit测试的时候需要-->
<context:component-scanbase-package="com.hoo"/>
</beans>
[/code]
这里配置bean对象,一些不能用annotation注解的对象就可以配置在这里

8、在src目录中添加mybatis.xml,内容如下:


[code]<?xmlversion="1.0"encoding="UTF-8"?>
<!DOCTYPEconfigurationPUBLIC"-//mybatis.org//DTDConfig3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--别名-->
<typeAliases>
<typeAliastype="com.hoo.entity.Account"alias="account"/>
</typeAliases>
</configuration>
[/code]
在这个文件放置一些全局性的配置,如handler、objectFactory、plugin、以及mappers的映射路径(由于在applicationContext-common中的SqlSessionFactoryBean有配置mapper的location,这里就不需要配置)等

9、AccountMapper接口,内容如下:


[code]packagecom.hoo.mapper;
importjava.util.List;
importorg.apache.ibatis.annotations.Select;
importcom.hoo.entity.Account;
/**
*<b>function:</b>继承SqlMapper,MyBatis数据操作接口;此接口无需实现类
*@authorhoojo
*@createDate2010-12-21下午05:21:20
*@fileAccountMapper.java
*@packagecom.hoo.mapper
*@projectMyBatis
*@blog
'target='_blank'>http://blog.csdn.net/IBM_hoojo
*@emailhoojo_@126.com
*@version1.0
*/
publicinterfaceAccountMapperextendsSqlMapper{
publicList<Account>getAllAccount();
publicAccountgetAccount();
publicAccountgetAccountById(Stringid);
publicAccountgetAccountByNames(Stringspring);
@Select("select*fromaccountwhereusername=#{name}")
publicAccountgetAccountByName(Stringname);
publicvoidaddAccount(Accountaccount);
publicvoideditAccount(Accountaccount);
publicvoidremoveAccount(intid);
}
[/code]
这个接口我们不需要实现,由mybatis帮助我们实现,我们通过mapper文件配置sql语句即可完成接口的实现。然后这个接口需要继承SqlMapper接口,不然在其他地方就不能从Spring容器中拿到这个mapper接口,也就是说当我们注入这个接口的时候将会失败。

当然,你不继承这个接口也可以。那就是你需要给买个mapper配置一个bean。配置方法如下:


[code]<beanid="accountMapper"class="org.mybatis.spring.mapper.MapperFactoryBean">
<propertyname="mapperInterface"value="com.hoo.mapper.AccountMapper"/>
<propertyname="sqlSessionFactory"ref="sqlSessionFactory"/>
</bean>
[/code]
这里的MapperFactoryBean可以帮助我们完成Session的打开、关闭等操作

10、在com.hoo.mapper也就是在AccountMapper接口的同一个包下,添加account-mapper.xml,内容如下:


[code]<?xmlversion="1.0"encoding="UTF-8"?>
<!DOCTYPEmapperPUBLIC"-//mybatis.org//DTDMapper3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace和定义的Mapper接口对应,并实现其中的方法-->
<mappernamespace="com.hoo.mapper.AccountMapper">
<!--id和mapper接口中的方法名对应,resultType使用mybatis.xml中的别名-->
<selectid="getAccount"resultType="account">
<![CDATA[
select*fromaccountlimit1
]]>
</select>
<selectid="getAllAccount"resultType="list"resultMap="accountResultMap">
<![CDATA[
select*fromaccount
]]>
</select>
<!--accountResultMap是account-resultmap.xml中定义的resultmap-->
<selectid="getAccountById"parameterType="string"resultType="com.hoo.entity.Account"resultMap="accountResultMap">
<![CDATA[
select*fromaccountwhereaccount_id=#{id}
]]>
</select>
<!--accountMap.accountResultMap是account-resultmap.xml中定义的resultmap,通过namespace.id找到-->
<selectid="getAccountByNames"parameterType="string"resultMap="accountMap.accountResultMap">
<![CDATA[
select*fromaccountwhereusername=#{name}
]]>
</select>
<sqlid="user_name_pwd">
username,password
</sql>
<!--自动生成id策略-->
<insertid="addAccount"useGeneratedKeys="true"keyProperty="account_id"parameterType="account">
insertintoaccount(account_id,status,username,password)
values(#{accountId},#{status},#{username},#{password})
</insert>
<!--根据selectKey语句生成主键-->
<insertid="addAccount4Key"parameterType="account">
<selectKeykeyProperty="account_id"order="BEFORE"resultType="int">
selectcast(random()*10000asInteger)afrom#Tab
</selectKey>
insertintoaccount(account_id,status,username,password)
values(#{accountId},#{status},#{username},#{password})
</insert>
<updateid="editAccount"parameterType="account">
updateaccountset
status=#{status},
username=#{username},
password=#{password}
whereaccount_id=#{accountId}
</update>
<deleteid="removeAccount"parameterType="int">
deletefromaccountwhereaccount_id=#{id}
</delete>
</mapper>
[/code]
上面的namespace和定义接口类路径对应,所有的sql语句,如select、insert、delete、update的id和方法名称对应。关于更多MyBatis内容的讲解,这里就不赘述的。这里只完成整合!如果你不懂可以去阅读其他关于MyBatis的资料。

11、为了测试发布,这里使用junit和spring官方提供的spring-test.jar,完成spring框架整合的测试,代码如下:


[code]packagecom.hoo.mapper;
importjava.util.List;
importjavax.inject.Inject;
importorg.springframework.test.context.ContextConfiguration;
importorg.springframework.test.context.junit38.AbstractJUnit38SpringContextTests;
importcom.hoo.entity.Account;
/**
*<b>function:</b>AccountMapperJUnit测试类
*@authorhoojo
*@createDate2011-4-12下午04:21:50
*@fileAccountMapperTest.java
*@packagecom.hoo.mapper
*@projectMyBatisForSpring
*@blog
'target='_blank'>http://blog.csdn.net/IBM_hoojo
*@emailhoojo_@126.com
*@version1.0
*/
@ContextConfiguration("classpath:applicationContext-*.xml")
publicclassAccountMapperTestextendsAbstractJUnit38SpringContextTests{
@Inject
//@Named("accountMapper")
privateAccountMappermapper;
publicvoidtestGetAccount(){
System.out.println(mapper.getAccount());
}
publicvoidtestGetAccountById(){
System.out.println(mapper.getAccountById("28"));
}
publicvoidtestGetAccountByName(){
System.out.println(mapper.getAccountByName("user"));
}
publicvoidtestGetAccountByNames(){
System.out.println(mapper.getAccountByNames("user"));
}
publicvoidtestAdd(){
Accountaccount=newAccount();
account.setEmail("temp@155.com");
account.setPassword("abc");
account.setRoleId(1);
account.setSalt("ss");
account.setStatus(0);
account.setUsername("Jack");
mapper.addAccount(account);
}
publicvoidtestEditAccount(){
Accountacc=mapper.getAccountByNames("Jack");
System.out.println(acc);
acc.setUsername("Zhangsan");
acc.setPassword("123123");
mapper.editAccount(acc);
System.out.println(mapper.getAccountById(acc.getAccountId()+""));
}
publicvoidtestRemoveAccount(){
Accountacc=mapper.getAccountByNames("Jack");
mapper.removeAccount(acc.getAccountId());
System.out.println(mapper.getAccountByNames("Jack"));
}
publicvoidtestAccountList(){
List<Account>acc=mapper.getAllAccount();
System.out.println(acc.size());
System.out.println(acc);
}
}
[/code]
这里的注入并没有使用@Autowired、@Resource、@Qualifier注入,而是使用@Inject、@Named注入方式,Inject注入是JSR330的标准注入方式;而不局限于某个产品,使用于多个产品的使用,推荐使用这种方式;运行后,没有发现问题,就可以继续后续的编码工作了。

12、定义AccountDao接口及实现代码,代码如下:


[code]packagecom.hoo.dao;
importjava.util.List;
importorg.springframework.dao.DataAccessException;
/**
*<b>function:</b>Account数据库操作dao接口
*@authorhoojo
*@createDate2011-4-13上午10:21:38
*@fileAccountDao.java
*@packagecom.hoo.dao
*@projectMyBatisForSpring
*@blog
'target='_blank'>http://blog.csdn.net/IBM_hoojo
*@emailhoojo_@126.com
*@version1.0
*/
publicinterfaceAccountDao<T>{
/**
*<b>function:</b>添加Account对象信息
*@authorhoojo
*@createDate2011-4-13上午11:50:05
*@paramentityAccount
*@returnboolean是否成功
*@throwsDataAccessException
*/
publicbooleanaddAccount(Tentity)throwsDataAccessException;
/**
*<b>function:</b>根据id对到Account信息
*@authorhoojo
*@createDate2011-4-13上午11:50:45
*@paramid编号id
*@returnAccount
*@throwsDataAccessException
*/
publicTgetAccount(Integerid)throwsDataAccessException;
/**
*<b>function:</b>查询所有Account信息
*@authorhoojo
*@createDate2011-4-13上午11:51:45
*@paramid编号id
*@returnAccount
*@throwsDataAccessException
*/
publicList<T>getList()throwsDataAccessException;
}
[/code]
接口实现


[code]packagecom.hoo.dao.impl;
importjava.util.List;
importjavax.inject.Inject;
importorg.springframework.dao.DataAccessException;
importorg.springframework.stereotype.Repository;
importcom.hoo.dao.AccountDao;
importcom.hoo.entity.Account;
importcom.hoo.mapper.AccountMapper;
/**
*<b>function:</b>Account数据库操作dao
*@authorhoojo
*@createDate2011-4-13上午10:25:02
*@fileAccountDaoImpl.java
*@packagecom.hoo.dao.impl
*@projectMyBatisForSpring
*@blog
'target='_blank'>http://blog.csdn.net/IBM_hoojo
*@emailhoojo_@126.com
*@version1.0
*/
@SuppressWarnings("unchecked")
@Repository
publicclassAccountDaoImpl<TextendsAccount>implementsAccountDao<T>{
@Inject
privateAccountMappermapper;
publicbooleanaddAccount(Tentity)throwsDataAccessException{
booleanflag=false;
try{
mapper.addAccount(entity);
flag=true;
}catch(DataAccessExceptione){
flag=false;
throwe;
}
returnflag;
}
publicTgetAccount(Integerid)throwsDataAccessException{
Tentity=null;
try{
entity=(T)mapper.getAccountById(String.valueOf(id));
}catch(DataAccessExceptione){
throwe;
}
returnentity;
}
publicList<T>getList()throwsDataAccessException{
return(List<T>)mapper.getAllAccount();
}
}
[/code]
13、服务层AccountBiz接口及实现代码

接口:


[code]packagecom.hoo.biz;
importjava.util.List;
importorg.springframework.dao.DataAccessException;
/**
*<b>function:</b>biz层Account接口
*@authorhoojo
*@createDate2011-4-13上午11:33:04
*@fileAccountBiz.java
*@packagecom.hoo.biz
*@projectMyBatisForSpring
*@blog
'target='_blank'>http://blog.csdn.net/IBM_hoojo
*@emailhoojo_@126.com
*@version1.0
*/
publicinterfaceAccountBiz<T>{
/**
*<b>function:</b>添加Account对象信息
*@authorhoojo
*@createDate2011-4-13上午11:50:05
*@paramentityAccount
*@returnboolean是否成功
*@throwsDataAccessException
*/
publicbooleanaddAccount(Tentity)throwsDataAccessException;
/**
*<b>function:</b>根据id对到Account信息
*@authorhoojo
*@createDate2011-4-13上午11:50:45
*@paramid编号id
*@returnAccount
*@throwsDataAccessException
*/
publicTgetAccount(Integerid)throwsDataAccessException;
/**
*<b>function:</b>查询所有Account信息
*@authorhoojo
*@createDate2011-4-13上午11:51:45
*@paramid编号id
*@returnAccount
*@throwsDataAccessException
*/
publicList<T>getList()throwsDataAccessException;
}
[/code]
实现代码:


[code]packagecom.hoo.biz.impl;
importjava.util.List;
importjavax.inject.Inject;
importorg.springframework.dao.DataAccessException;
importorg.springframework.stereotype.Service;
importcom.hoo.biz.AccountBiz;
importcom.hoo.dao.AccountDao;
importcom.hoo.entity.Account;
importcom.hoo.exception.BizException;
/**
*<b>function:</b>AccountBiz接口实现
*@authorhoojo
*@createDate2011-4-13上午11:34:39
*@fileAccountBizImpl.java
*@packagecom.hoo.biz.impl
*@projectMyBatisForSpring
*@blog
'target='_blank'>http://blog.csdn.net/IBM_hoojo
*@emailhoojo_@126.com
*@version1.0
*/
//@Component
@Service
publicclassAccountBizImpl<TextendsAccount>implementsAccountBiz<T>{
@Inject
privateAccountDao<T>dao;
publicbooleanaddAccount(Tentity)throwsDataAccessException{
if(entity==null){
thrownewBizException(Account.class.getName()+"对象参数信息为Empty!");
}
returndao.addAccount(entity);
}
publicTgetAccount(Integerid)throwsDataAccessException{
returndao.getAccount(id);
}
publicList<T>getList()throwsDataAccessException{
returndao.getList();
}
}
[/code]
上面用到了一个自定义的异常信息,代码如下:


[code]packagecom.hoo.exception;
importorg.springframework.dao.DataAccessException;
/**
*<b>function:</b>自定义Biz层异常信息
*@authorhoojo
*@createDate2011-4-13上午11:42:19
*@fileBizException.java
*@packagecom.hoo.exception
*@projectMyBatisForSpring
*@blog
'target='_blank'>http://blog.csdn.net/IBM_hoojo
*@emailhoojo_@126.com
*@version1.0
*/
publicclassBizExceptionextendsDataAccessException{
/**
*@authorHoojo
*/
privatestaticfinallongserialVersionUID=1L;
publicBizException(Stringmsg){
super(msg);
}
publicBizException(Stringmsg,Throwablecause){
super(msg,cause);
}
}
[/code]
这里只是简单的继承,如果还有其他的异常业务或需求可以进行具体的实现

14、springMVC的控制器,AccountController代码如下:


[code]packagecom.hoo.controller;
importjavax.inject.Inject;
importjavax.servlet.http.HttpServletRequest;
importorg.springframework.stereotype.Controller;
importorg.springframework.ui.Model;
importorg.springframework.web.bind.annotation.ExceptionHandler;
importorg.springframework.web.bind.annotation.RequestMapping;
importcom.hoo.biz.AccountBiz;
importcom.hoo.entity.Account;
/**
*<b>function:</b>Account控制器
*@authorhoojo
*@createDate2011-4-13上午10:18:02
*@fileAccountController.java
*@packagecom.hoo.controller
*@projectMyBatisForSpring
*@blog
'target='_blank'>http://blog.csdn.net/IBM_hoojo
*@emailhoojo_@126.com
*@version1.0
*/
@Controller
@RequestMapping("/account")
publicclassAccountController{
@Inject
privateAccountBiz<Account>biz;
@RequestMapping("/add")
publicStringadd(Accountacc){
System.out.println(acc);
biz.addAccount(acc);
return"redirect:/account/list.do";
}
@RequestMapping("/get")
publicStringget(Integerid,Modelmodel){
System.out.println("##ID:"+id);
model.addAttribute(biz.getAccount(id));
return"/show.jsp";
}
@RequestMapping("/list")
publicStringlist(Modelmodel){
model.addAttribute("list",biz.getList());
return"/list.jsp";
}
@ExceptionHandler(Exception.class)
publicStringexception(Exceptione,HttpServletRequestrequest){
//e.printStackTrace();
request.setAttribute("exception",e);
return"/error.jsp";
}
}
[/code]
15、基本页面代码

index.jsp


[code]<%@pagelanguage="java"import="java.util.*"pageEncoding="UTF-8"%>
<%[code]


Stringpath=request.getContextPath();


StringbasePath=request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

%>[/code]
<!DOCTYPEHTMLPUBLIC"-//W3C//DTDHTML4.01Transitional//EN">
<html>
<head>
<basehref="<%=basePath%>">
<title>MyBatis整合Spring3.0.5</title>
<metahttp-equiv="pragma"content="no-cache">
<metahttp-equiv="cache-control"content="no-cache">
<metahttp-equiv="expires"content="0">
<metahttp-equiv="keywords"content="keyword1,keyword2,keyword3">
<metahttp-equiv="description"content="Thisismypage">
</head>
<body>
<h3>MyBatis3.0.4整合Spring3.0.5</h3>
<ahref="account/list.do">查询所有</a><br/>
<ahref="account/add.do?username=abcdef&password=123132&status=2">添加</a><br/>
<ahref="account/get.do?id=25">查询</a><br/>
</body>
</html>
[/code]
List.jsp


[code]<%@pagelanguage="java"import="java.util.*"pageEncoding="UTF-8"%>
<%@tagliburi="http://java.sun.com/jsp/jstl/core"prefix="c"%>
<%[code]


Stringpath=request.getContextPath();


StringbasePath=request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

%>[/code]
<!DOCTYPEHTMLPUBLIC"-//W3C//DTDHTML4.01Transitional//EN">
<html>
<head>
<basehref="<%=basePath%>">
<title>allAccountResult</title>
<metahttp-equiv="pragma"content="no-cache">
<metahttp-equiv="cache-control"content="no-cache">
<metahttp-equiv="expires"content="0">
<metahttp-equiv="keywords"content="keyword1,keyword2,keyword3">
<metahttp-equiv="description"content="Thisismypage">
</head>
<body>
<c:forEachitems="${list}"var="data">
id:${data.accountId}---name:${data.username}---password:${data.password}<hr/>
</c:forEach>
</body>
</html>
[/code]
show.jsp


[code]<%@pagelanguage="java"import="java.util.*"pageEncoding="UTF-8"%>
<%[code]


Stringpath=request.getContextPath();


StringbasePath=request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

%>[/code]
<!DOCTYPEHTMLPUBLIC"-//W3C//DTDHTML4.01Transitional//EN">
<html>
<head>
<basehref="<%=basePath%>">
<title>showAccount</title>
<metahttp-equiv="pragma"content="no-cache">
<metahttp-equiv="cache-control"content="no-cache">
<metahttp-equiv="expires"content="0">
<metahttp-equiv="keywords"content="keyword1,keyword2,keyword3">
<metahttp-equiv="description"content="Thisismypage">
</head>
<body>
${account}<br/>
${account.username}#${account.accountId}
</body>
</html>
[/code]
error.jsp

<%@pagelanguage="java"import="java.util.*"pageEncoding="UTF-8"%>
<%
Stringpath=request.getContextPath();
StringbasePath=request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPEHTMLPUBLIC"-//W3C//DTDHTML4.01Transitional//EN">
<html>
<head>
<basehref="<%=basePath%>">

<title>ErrorPage</title>

<metahttp-equiv="pragma"content="no-cache">
<metahttp-equiv="cache-control"content="no-cache">
<metahttp-equiv="expires"content="0">
<metahttp-equiv="keywords"content="keyword1,keyword2,keyword3">
<metahttp-equiv="description"content="Thisismypage">
</head>

<body>
<H2>Exception:${exception}</H2>
<ahref="javascript:document.getElementById('show').style.display='block';void(0);">
详细信息
</a>
<divid="show"style="color:red;display:none;">
<%Exceptionex=(Exception)request.getAttribute("exception");%>

<%ex.printStackTrace(newjava.io.PrintWriter(out));%>
</div>
</body>
</html>

16、以上就基本上完成了整个Spring+SpringMVC+MyBatis的整合了。如果你想添加事务管理,得在applicationContext-common.xml中加入如下配置:


[code]<!--配置事务管理器,注意这里的dataSource和SqlSessionFactoryBean的dataSource要一致,不然事务就没有作用了-->
<beanid="transactionManager"class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<propertyname="dataSource"ref="dataSource"/>
</bean>
[/code]
同时还需要加入aspectjweaver.jar这个jar包;

注意的是:Jdbc的TransactionManager不支持事务隔离级别,我在整个地方加入其它的TransactionManager,增加对transaction的隔离级别都尝试失败!

也许可以用于jpa、jdo、jta这方面的东西。不知道大家对MyBatis的事务是怎么处理的?

17、对Dao进行扩展封装,运用SqlSessionDaoSupport进行模板的扩展或运用:

BaseDao代码如下:


[code]packagecom.hoo.dao;
importjava.util.List;
/**
*<b>function:</b>
*@authorhoojo
*@createDate2011-4-12下午04:18:09
*@fileIBaseDao.java
*@packagecom.hoo.dao
*@projectMyBatisForSpring
*@blog
'target='_blank'>http://blog.csdn.net/IBM_hoojo
*@emailhoojo_@126.com
*@version1.0
*@param<T>
*/
publicinterfaceBaseDao<T>{
publicbooleanadd(StringclassMethod,Tentity)throwsException;
publicbooleanedit(StringclassMethod,Tentity)throwsException;
publicbooleanremove(StringclassMethod,Tentity)throwsException;
publicTget(StringclassMethod,Tentity)throwsException;
publicList<T>getAll(StringclassMethod)throwsException;
}
[/code]
实现类代码:


[code]packagecom.hoo.dao.impl;
importjava.util.ArrayList;
importjava.util.List;
importjavax.inject.Inject;
importorg.apache.ibatis.session.SqlSessionFactory;
importorg.mybatis.spring.support.SqlSessionDaoSupport;
importorg.springframework.stereotype.Repository;
importcom.hoo.dao.BaseDao;
/**
*<b>function:</b>运用SqlSessionDaoSupport封装Dao常用增删改方法,可以进行扩展
*@authorhoojo
*@createDate2011-4-13下午06:33:37
*@fileBaseDaoImpl.java
*@packagecom.hoo.dao.impl
*@projectMyBatisForSpring
*@blog
'target='_blank'>http://blog.csdn.net/IBM_hoojo
*@emailhoojo_@126.com
*@version1.0
*/
@Repository
@SuppressWarnings({"unchecked","unused"})
publicclassBaseDaoImpl<TextendsObject>extendsSqlSessionDaoSupportimplementsBaseDao<T>{
@Inject
privateSqlSessionFactorysqlSessionFactory;
publicbooleanadd(StringclassMethod,Tentity)throwsException{
booleanflag=false;
try{
flag=this.getSqlSession().insert(classMethod,entity)>0?true:false;
}catch(Exceptione){
flag=false;
throwe;
}
returnflag;
}
publicbooleanedit(StringclassMethod,Tentity)throwsException{
booleanflag=false;
try{
flag=this.getSqlSession().update(classMethod,entity)>0?true:false;
}catch(Exceptione){
flag=false;
throwe;
}
returnflag;
}
publicTget(StringclassMethod,Tentity)throwsException{
Tresult=null;
try{
result=(T)this.getSqlSession().selectOne(classMethod,entity);
}catch(Exceptione){
throwe;
}
returnresult;
}
publicList<T>getAll(StringclassMethod)throwsException{
List<T>result=newArrayList<T>();
try{
result=this.getSqlSession().selectList(classMethod);
}catch(Exceptione){
throwe;
}
returnresult;
}
publicbooleanremove(StringclassMethod,Tentity)throwsException{
booleanflag=false;
try{
flag=this.getSqlSession().delete(classMethod,entity)>0?true:false;
}catch(Exceptione){
flag=false;
throwe;
}
returnflag;
}
}
[/code]
值得说明的是,这个类继承了SqlSessionDaoSupport,它需要我们帮助它注入SqlSessionFactory或是SqlSessionTemplate,如果两者都被注入将忽略SqlSessionFactory属性,使用SqlSessionTemplate模板。

继承SqlSessionDaoSupport后,可以拿到SqlSession完成数据库的操作;

18、对Dao进行扩展封装,运用SqlSessionTemplate进行模板的扩展或运用:

首先看看这个组件中运用的一个Mapper的基类接口:


[code]packagecom.hoo.mapper;
importjava.util.List;
importorg.springframework.dao.DataAccessException;
/**
*<b>function:</b>BaseSqlMapper继承SqlMapper,对Mapper进行接口封装,提供常用的增删改查组件;
*也可以对该接口进行扩展和封装
*@authorhoojo
*@createDate2011-4-14上午11:36:41
*@fileBaseSqlMapper.java
*@packagecom.hoo.mapper
*@projectMyBatisForSpring
*@blog
'target='_blank'>http://blog.csdn.net/IBM_hoojo
*@emailhoojo_@126.com
*@version1.0
*/
publicinterfaceBaseSqlMapper<T>extendsSqlMapper{
publicvoidadd(Tentity)throwsDataAccessException;
publicvoidedit(Tentity)throwsDataAccessException;
publicvoidremvoe(Tentity)throwsDataAccessException;
publicTget(Tentity)throwsDataAccessException;
publicList<T>getList(Tentity)throwsDataAccessException;
}
[/code]
该接口继承SqlMapper接口,但是该接口没有MyBatis的mapper实现。需要我们自己的业务mapper继承这个接口,完成上面的方法的实现。

看看继承SqlSessionTemplate的BaseMapperDao代码:


[code]packagecom.hoo.dao;
importjava.util.List;
importcom.hoo.mapper.BaseSqlMapper;
/**
*<b>function:</b>
*@authorhoojo
*@createDate2011-4-14上午11:30:09
*@fileBaseMapperDao.java
*@packagecom.hoo.dao
*@projectMyBatisForSpring
*@blog
'target='_blank'>http://blog.csdn.net/IBM_hoojo
*@emailhoojo_@126.com
*@version1.0
*/
publicinterfaceBaseMapperDao<T>{
@SuppressWarnings("unchecked")
publicvoidsetMapperClass(Class<?extendsBaseSqlMapper>mapperClass);
publicbooleanadd(Tentity)throwsException;
publicbooleanedit(Tentity)throwsException;
publicbooleanremove(Tentity)throwsException;
publicTget(Tentity)throwsException;
publicList<T>getAll()throwsException;
}
[/code]

[code]packagecom.hoo.dao.impl;
importjava.util.List;
importjavax.inject.Inject;
importorg.apache.ibatis.session.SqlSessionFactory;
importorg.mybatis.spring.SqlSessionTemplate;
importorg.springframework.stereotype.Repository;
importcom.hoo.dao.BaseMapperDao;
importcom.hoo.mapper.BaseSqlMapper;
/**
*<b>function:</b>运用SqlSessionTemplate封装Dao常用增删改方法,可以进行扩展
*@authorhoojo
*@createDate2011-4-14下午12:22:07
*@fileBaseMapperDaoImpl.java
*@packagecom.hoo.dao.impl
*@projectMyBatisForSpring
*@blog
'target='_blank'>http://blog.csdn.net/IBM_hoojo
*@emailhoojo_@126.com
*@version1.0
*/
@SuppressWarnings("unchecked")
@Repository
publicclassBaseMapperDaoImpl<T>extendsSqlSessionTemplateimplementsBaseMapperDao<T>{
@Inject
publicBaseMapperDaoImpl(SqlSessionFactorysqlSessionFactory){
super(sqlSessionFactory);
}
privateClass<?extendsBaseSqlMapper>mapperClass;
publicvoidsetMapperClass(Class<?extendsBaseSqlMapper>mapperClass){
this.mapperClass=mapperClass;
}
privateBaseSqlMapper<T>getMapper(){
returnthis.getMapper(mapperClass);
}
publicbooleanadd(Tentity)throwsException{
booleanflag=false;
try{
this.getMapper().add(entity);
flag=true;
}catch(Exceptione){
flag=false;
throwe;
}
returnflag;
}
publicbooleanedit(Tentity)throwsException{
booleanflag=false;
try{
this.getMapper().edit(entity);
flag=true;
}catch(Exceptione){
flag=false;
throwe;
}
returnflag;
}
publicTget(Tentity)throwsException{
returnthis.getMapper().get(entity);
}
publicList<T>getAll()throwsException{
returnthis.getMapper().getList(null);
}
publicbooleanremove(Tentity)throwsException{
booleanflag=false;
try{
this.getMapper().remvoe(entity);
flag=true;
}catch(Exceptione){
flag=false;
throwe;
}
returnflag;
}
}
[/code]
上面这个类继承了SqlSessionTemplate,这个类需要提供一个构造函数。这里提供的是SqlSessionFactory的构造函数,通过该函数注入SqlSessionFactory即可完成数据库操作;

例外的是这个类还有一个关键属性mapperClass,这个class需要是BaseSqlMapper接口或是子接口,然后通过SqlSessionTemplate模板获得当前设置的Class的Mapper对象,完成数据库操作。

该类的测试代码:

[code]@ContextConfiguration("classpath:applicationContext-*.xml")
publicclassBaseMapperDaoImplTestextendsAbstractJUnit38SpringContextTests{
@Inject
privateBaseMapperDao<Company>dao;
publicvoidinit(){
dao.setMapperClass(CompanyMapper.class);
}
publicvoidtestGet()throwsException{
init();
Companyc=newCompany();
c.setCompanyId(4);
System.out.println(dao.get(c));
}
publicvoidtestAdd()throwsException{
init();
Companyc=newCompany();
c.setAddress("北京中关村");
c.setName("beijin");
System.out.println(dao.add(c));
}
}
[/code]
一般情况下,你可以在一个Dao中注入BaseMapperDao,紧跟着需要设置MapperClass。只有设置了MapperClass后,BaseMapperDao才能获取对应mapper,完成相关的数据库操作。当然你可以在这个Dao中将SqlSessionTemplate、SqlSession暴露出来,当BaseMapperDao的方法不够用,可以进行扩展。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: