集成ibatis的spring工程升级到spring4.0实操手册

Spring4及已经的版本放弃了对ibatis的集成支持,那有什么办法可以将自己的框架迁移升级到spring4呢。

我这里有2个办法可供参考:

1、改造spring-orm包:

        A、首先从spring-orm的jar包中将ibatis相关的class文件及包结构全部复制出来,以备后用。

        B、更改工程的spring版本号到spring4

        C、将已经复制出来的ibatis包结构全部拖入spring4中spring-orm包的响应位置

        D、测试一下当前的应用,是不是已经可以了呢 ^_^

2、将spring直接升级到spring4.0,同时集成新的mybatis替代老版本的ibatis。

说明:这两种办法都各有优势,同时也各有不足,实际升级过程中需要权衡考虑利弊关系。

第一中方法,在架构升级过程中,确保了最小改动量的原则,但是会造成一个隐形的私有开发包,一旦架构再次进行spring版本升级,本次的升级操作无法平滑过渡,这种潜规则式的改造方式,需要通过口传心授的方式进行知识的传递,其实在一定程度上给后来的开发人员埋了一个不大不小的坑。

第二种方法将系统的依赖变更提现在pom文件的依赖变化,虽然解决了升级产生的潜规则,但改造周期、测试周期都比较长。因此需要升级者权衡,如果工期紧张,而后续又有持续的改进升级计划,第一种方式可以作为一种临时的高效过渡方案,当有较充足的资源时,可以采用第二种方式,彻底将问题解决掉。

下面我们详细介绍下spring4.0与ibatis的集成,便于大家在升级框架的过程中进行参考:

1、为方便说明,我们新建一个工程,来演示spring与mybatis的集成,新建工程:webinst,结构如下:

D:.
└─src
    ├─main
    │  ├─java
    │  │  └─com
    │  │      └─myteay
    │  │          └─common
    │  │              └─dal
    │  │                  └─dinner
    │  │                      ├─dao
    │  │                      ├─dataobject
    │  │                      ├─exec
    │  │                      └─ibatis
    │  ├─resources
    │  │  ├─META-INF
    │  │  │  └─spring
    │  │  └─sqlmap
    │  │      └─goods
    │  └─webapp
    │      └─WEB-INF
    └─test
        └─java
            └─com
                └─myteay
                    └─myibatis

工程树说明:

  • dao路径下用于存放定义的mybatis数据库操作接口
  • dataobject路径下用于存放数据模型
  • ibatis路径下用于存放数据库操作接口的实现
  • exec用于执行相关测试验证代码
  • META-INF/spring路径下存放当前工程的spring配置
  • sqlmap路径下存放mybatis相关配置文件
  • WEB-INF路径下存放工程相关基础配置如:applicationContext.xml、log4j.xml、web.xml等

本例以spring4.0.0.RELEASE版本为例来说明spring与mybatis的集成,pom文件如下:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.myteay</groupId>
  <artifactId>webinst</artifactId>
  <version>0.0.1</version>
  <packaging>war</packaging>

  <name>webinst</name>
  <url>http://maven.apache.org</url>

  <dependencies>
	<dependency>
        <groupId>org.apache.geronimo.specs</groupId>
        <artifactId>geronimo-servlet_2.4_spec</artifactId>
        <version>1.1.1</version>
        <scope>provwided</scope>
    </dependency>
		<dependency>
		    <groupId>org.slf4j</groupId>
		    <artifactId>slf4j-nop</artifactId>
		    <version>1.7.25</version>
		</dependency>
    	<!-- zxing -->
		<dependency>
			<groupId>com.google.zxing</groupId>
			<artifactId>core</artifactId>
			<version>3.0.0</version>
		</dependency>
    	<!-- mysql dependency start -->
		<dependency>
			<groupId>org.mysql</groupId>
			<artifactId>mysql-connector-java-commercial</artifactId>
			<version>5.1.33</version>
		</dependency>
		<dependency>
			<groupId>commons-dbcp</groupId>
			<artifactId>commons-dbcp</artifactId>
			<version>1.2.1</version>
		</dependency>
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis</artifactId>
			<version>3.4.2</version>
		</dependency>
    	<!-- mysql dependency end -->
		<dependency>
		    <groupId>org.mybatis</groupId>
		    <artifactId>mybatis-spring</artifactId>
		    <version>1.3.1</version>
		</dependency>
		<!-- spring dependency start -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aop</artifactId>
			<version>4.0.0.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-beans</artifactId>
			<version>4.0.0.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>4.0.0.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context-support</artifactId>
			<version>4.0.0.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>4.0.0.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-expression</artifactId>
			<version>4.0.0.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-jdbc</artifactId>
			<version>4.0.0.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-oxm</artifactId>
			<version>4.0.0.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-tx</artifactId>
			<version>4.0.0.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-web</artifactId>
			<version>4.0.0.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>4.0.0.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-orm</artifactId>
			<version>4.0.0.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>4.0.0.RELEASE</version>
		</dependency>
		<!-- spring dependency end -->

		<!-- unit test start -->
		<dependency>
			<groupId>jmock</groupId>
			<artifactId>jmock</artifactId>
			<version>1.2.0</version>
		</dependency>
		<dependency>
			<groupId>jmock</groupId>
			<artifactId>jmock-cglib</artifactId>
			<version>1.2.0</version>
		</dependency>
		<dependency>
	      <groupId>junit</groupId>
	      <artifactId>junit</artifactId>
	      <version>3.8.1</version>
	      <scope>test</scope>
	    </dependency>
		<!-- unit test end -->

		<dependency>
			<groupId>org.apache.mina</groupId>
			<artifactId>mina-core</artifactId>
			<version>2.0.4</version>
		</dependency>
		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>servlet</artifactId>
			<version>1.2.0</version>
		</dependency>
		<dependency>
			<groupId>commons-lang</groupId>
			<artifactId>commons-lang</artifactId>
			<version>2.2</version>
		</dependency>
		<dependency>
			<groupId>org.apache.ibatis</groupId>
			<artifactId>ibatis-sqlmap</artifactId>
			<version>2.3.4.726</version>
		</dependency>
		<dependency>
			<groupId>commons-logging</groupId>
			<artifactId>commons-logging-api</artifactId>
			<version>1.1</version>
		</dependency>
		<dependency>
			<groupId>commons-beanutils</groupId>
			<artifactId>commons-beanutils</artifactId>
			<version>1.7.0</version>
		</dependency>
		<dependency>
			<groupId>commons-configuration</groupId>
			<artifactId>commons-configuration</artifactId>
			<version>1.5</version>
		</dependency>
		<dependency>
			<groupId>commons-jelly</groupId>
			<artifactId>commons-jelly</artifactId>
			<exclusions>
				<exclusion>
					<groupId>servletapi</groupId>
					<artifactId>servletapi</artifactId>
				</exclusion>
			</exclusions>
			<version>1.0-RC1</version>
		</dependency>
		<dependency>
			<groupId>commons-collections</groupId>
			<artifactId>commons-collections</artifactId>
			<version>3.1</version>
		</dependency>
		<dependency>
			<groupId>commons-digester</groupId>
			<artifactId>commons-digester</artifactId>
			<version>1.8</version>
		</dependency>
		<dependency>
			<groupId>commons-codec</groupId>
			<artifactId>commons-codec</artifactId>
			<version>1.3</version>
		</dependency>
		<dependency>
			<groupId>commons-io</groupId>
			<artifactId>commons-io</artifactId>
			<version>1.2</version>
		</dependency>
		<dependency>
			<groupId>commons-discovery</groupId>
			<artifactId>commons-discovery</artifactId>
			<version>0.4</version>
		</dependency>
		<dependency>
			<groupId>commons-pool</groupId>
			<artifactId>commons-pool</artifactId>
			<version>1.3</version>
		</dependency>
		<dependency>
			<groupId>commons-httpclient</groupId>
			<artifactId>commons-httpclient</artifactId>
			<version>3.0</version>
		</dependency>
		<dependency>
			<groupId>commons-jexl</groupId>
			<artifactId>commons-jexl</artifactId>
			<version>1.1</version>
		</dependency>
		<dependency>
			<groupId>nekohtml</groupId>
			<artifactId>nekohtml</artifactId>
			<version>0.9.5</version>
		</dependency>
		<dependency>
			<groupId>org.w3c.css</groupId>
			<artifactId>sac</artifactId>
			<version>1.3</version>
		</dependency>
		<dependency>
			<groupId>dom4j</groupId>
			<artifactId>dom4j</artifactId>
			<version>1.6.1</version>
		</dependency>
		<dependency>
			<groupId>jdom</groupId>
			<artifactId>jdom</artifactId>
			<version>1.0</version>
		</dependency>
		<dependency>
			<groupId>xerces</groupId>
			<artifactId>xerces</artifactId>
			<version>2.4.0</version>
		</dependency>
		<dependency>
			<groupId>xerces</groupId>
			<artifactId>xercesImpl</artifactId>
			<version>2.6.2</version>
		</dependency>
		<dependency>
			<groupId>com.thoughtworks.xstream</groupId>
			<artifactId>xstream</artifactId>
			<version>1.2.1</version>
		</dependency>
		<dependency>
			<groupId>org.codehaus.groovy</groupId>
			<artifactId>groovy-all</artifactId>
			<version>1.6.4</version>
		</dependency>
		<dependency>
			<groupId>org.antlr</groupId>
			<artifactId>antlr</artifactId>
			<version>3.1.3</version>
		</dependency>
		<dependency>
			<groupId>org.antlr</groupId>
			<artifactId>antlr-runtime</artifactId>
			<version>3.1.3</version>
		</dependency>
		<dependency>
		    <groupId>commons-fileupload</groupId>
		    <artifactId>commons-fileupload</artifactId>
		    <version>1.3</version>
		</dependency>
        <!-- fastjson -->  
        <dependency>  
            <groupId>com.alibaba</groupId>  
            <artifactId>fastjson</artifactId>  
            <version>1.1.28</version>  
        </dependency>  
  
        <!-- log4j -->  
        <dependency>  
            <groupId>log4j</groupId>  
            <artifactId>log4j</artifactId>  
            <version>1.2.16</version>  
        </dependency>  
  
        <!--javamail-->  
        <dependency>  
            <groupId>javax.mail</groupId>  
            <artifactId>mail</artifactId>  
            <version>1.4.7</version>  
        </dependency>  
  
        <!--velocity-->  
	    <dependency>  
	        <groupId>org.apache.velocity</groupId>  
	        <artifactId>velocity</artifactId>  
	        <version>1.6.2</version>  
	    </dependency>
	    <dependency>  
	        <groupId>org.apache.velocity</groupId>  
	        <artifactId>velocity-tools</artifactId>  
	        <version>2.0</version>  
	    </dependency>

  </dependencies>
  <build>
    <finalName>webinst</finalName>
    <plugins>
		<plugin>
			<groupId>org.mortbay.jetty</groupId>
			<artifactId>maven-jetty-plugin</artifactId>
			<version>6.1.26</version>
			<configuration>
				<scanIntervalSeconds>3</scanIntervalSeconds>
				<connectors>
					<connector implementation="org.mortbay.jetty.nio.SelectChannelConnector">
						<port>80</port>
					</connector>
				</connectors>
				<scanTargetPatterns>
					<scanTargetPattern>
						<directory>src/main/webapp/WEB-INF</directory>
						<excludes>
							<exclude>**/*.jsp</exclude>
						</excludes>
						<includes>
							<include>**/*.properties</include>
							<include>**/*.xml</include>
						</includes>
					</scanTargetPattern>
				</scanTargetPatterns>
			</configuration>
		</plugin>
    </plugins>
  </build>
</project>

 说明:

  • pom中增加了对jetty的依赖,这样可以方便我们后面的测试验证
  • 为方便演示,增加了数据库操作相关jar依赖
  • 本例中已mybatis3.4.2为目标集成版本

其中对mybatis的关键依赖如下:

		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis</artifactId>
			<version>3.4.2</version>
		</dependency>
		<dependency>
		    <groupId>org.mybatis</groupId>
		    <artifactId>mybatis-spring</artifactId>
		    <version>1.3.1</version>
		</dependency>

对spring的关键依赖如下:

<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-aop</artifactId>
	<version>4.0.0.RELEASE</version>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-beans</artifactId>
	<version>4.0.0.RELEASE</version>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-context</artifactId>
	<version>4.0.0.RELEASE</version>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-context-support</artifactId>
	<version>4.0.0.RELEASE</version>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-core</artifactId>
	<version>4.0.0.RELEASE</version>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-expression</artifactId>
	<version>4.0.0.RELEASE</version>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-jdbc</artifactId>
	<version>4.0.0.RELEASE</version>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-oxm</artifactId>
	<version>4.0.0.RELEASE</version>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-tx</artifactId>
	<version>4.0.0.RELEASE</version>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-web</artifactId>
	<version>4.0.0.RELEASE</version>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-webmvc</artifactId>
	<version>4.0.0.RELEASE</version>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-orm</artifactId>
	<version>4.0.0.RELEASE</version>
</dependency>
<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-test</artifactId>
	<version>4.0.0.RELEASE</version>
</dependency>

其他依赖为本人框架升级需要用到的,各位可以忽略。

下面开始进行工程完善:

1、定义数据模型(建数据库表的过程这里省略):

/**
 * Myteay.com Inc.
 * Copyright (c) 2015-2016 All Rights Reserved.
 */
package com.myteay.common.dal.dinner.dataobject;

import java.io.Serializable;
import java.util.Date;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;

/**
 * 商品信息数据模型
 * 
 * @author Administrator
 * @version $Id: GoodsInfoDO.java, v 0.1 2016年3月5日 上午12:28:53 Administrator Exp $
 */
public class GoodsInfoDO implements Serializable {

    /** serialVersionUID */
    private static final long serialVersionUID = 4624303532159349944L;

    /** ID流水号 */
    private String            id;

    /** 店铺流水号 */
    private String            shopId;

    /** 图片地址 */
    private String            picAddr;

    /** 商品标题 */
    private String            goodsTitle;

    /** 价格 */
    private String            price;

    /** 备注 */
    private String            summary;

    /** 上架时间 */
    private Date              gmtCreated;

    /** 最后修改时间 */
    private Date              gmtModified;

    /**
     * Getter method for property <tt>id</tt>.
     * 
     * @return property value of id
     */
    public String getId() {
        return id;
    }

    /**
     * Setter method for property <tt>id</tt>.
     * 
     * @param id value to be assigned to property id
     */
    public void setId(String id) {
        this.id = id;
    }

    /**
     * Getter method for property <tt>shopId</tt>.
     * 
     * @return property value of shopId
     */
    public String getShopId() {
        return shopId;
    }

    /**
     * Setter method for property <tt>shopId</tt>.
     * 
     * @param shopId value to be assigned to property shopId
     */
    public void setShopId(String shopId) {
        this.shopId = shopId;
    }

    /**
     * Getter method for property <tt>picAddr</tt>.
     * 
     * @return property value of picAddr
     */
    public String getPicAddr() {
        return picAddr;
    }

    /**
     * Setter method for property <tt>picAddr</tt>.
     * 
     * @param picAddr value to be assigned to property picAddr
     */
    public void setPicAddr(String picAddr) {
        this.picAddr = picAddr;
    }

    /**
     * Getter method for property <tt>goodsTitle</tt>.
     * 
     * @return property value of goodsTitle
     */
    public String getGoodsTitle() {
        return goodsTitle;
    }

    /**
     * Setter method for property <tt>goodsTitle</tt>.
     * 
     * @param goodsTitle value to be assigned to property goodsTitle
     */
    public void setGoodsTitle(String goodsTitle) {
        this.goodsTitle = goodsTitle;
    }

    /**
     * Getter method for property <tt>price</tt>.
     * 
     * @return property value of price
     */
    public String getPrice() {
        return price;
    }

    /**
     * Setter method for property <tt>price</tt>.
     * 
     * @param price value to be assigned to property price
     */
    public void setPrice(String price) {
        this.price = price;
    }

    /**
     * Getter method for property <tt>summary</tt>.
     * 
     * @return property value of summary
     */
    public String getSummary() {
        return summary;
    }

    /**
     * Setter method for property <tt>summary</tt>.
     * 
     * @param summary value to be assigned to property summary
     */
    public void setSummary(String summary) {
        this.summary = summary;
    }

    /**
     * Getter method for property <tt>gmtCreated</tt>.
     * 
     * @return property value of gmtCreated
     */
    public Date getGmtCreated() {
        return gmtCreated;
    }

    /**
     * Setter method for property <tt>gmtCreated</tt>.
     * 
     * @param gmtCreated value to be assigned to property gmtCreated
     */
    public void setGmtCreated(Date gmtCreated) {
        this.gmtCreated = gmtCreated;
    }

    /**
     * Getter method for property <tt>gmtModified</tt>.
     * 
     * @return property value of gmtModified
     */
    public Date getGmtModified() {
        return gmtModified;
    }

    /**
     * Setter method for property <tt>gmtModified</tt>.
     * 
     * @param gmtModified value to be assigned to property gmtModified
     */
    public void setGmtModified(Date gmtModified) {
        this.gmtModified = gmtModified;
    }

    /** 
     * @see java.lang.Object#toString()
     */
    public String toString() {
        return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
    }
}
 

2、定义DAO接口

/**
 * Danlley Wei (mailto://[email protected])
 * Copyright (c) 2005-2017 All Rights Reserved.
 */
package com.myteay.common.dal.dinner.dao;

import java.util.List;

import com.myteay.common.dal.dinner.dataobject.GoodsInfoDO;

/**
 * 
 * @author danlley([email protected])
 * @version $Id: GoodsInfoDAO.java, v 0.1 2017年4月3日 下午5:19:11 danlley([email protected]) Exp $
 */
public interface GoodsInfoDAO {

    public List<GoodsInfoDO> findAll();
}
   

3、撰写DAO接口实现类

/**
 * Danlley Wei (mailto://[email protected])
 * Copyright (c) 2005-2017 All Rights Reserved.
 */
package com.myteay.common.dal.dinner.ibatis;

import java.util.List;

import org.mybatis.spring.support.SqlSessionDaoSupport;

import com.myteay.common.dal.dinner.dao.GoodsInfoDAO;
import com.myteay.common.dal.dinner.dataobject.GoodsInfoDO;

/**
 * 
 * @author danlley([email protected])
 * @version $Id: IbatisGoodsInfoDAO.java, v 0.1 2017年4月3日 下午5:59:05 danlley([email protected]) Exp $
 */
public class IbatisGoodsInfoDAO extends SqlSessionDaoSupport implements GoodsInfoDAO {

    /** 
     * @see com.myteay.common.dal.dinner.dao.GoodsInfoDAO#findAll()
     */
    @Override
    public List<GoodsInfoDO> findAll() {
        return this.getSqlSession()
            .selectList("com.myteay.common.dal.dinner.dao.GoodsInfoDAO.findAll");
    }

}
 

4、在resource的sqlmap.goods路径下增加配置:goods-info.xml,内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.myteay.common.dal.dinner.dao.GoodsInfoDAO">
    <select id="findAll" resultType="com.myteay.common.dal.dinner.dataobject.GoodsInfoDO">
        select id,shop_id,pic_addr,goods_title,price,summary,gmt_created,gmt_modified from dinner.goods
    </select>
</mapper>

注:这里的id名称需要与接口的方法名称保持一致哈,这个你懂的。

5、在resource路径下的sqlmap包下增加配置文件:mybatis-config.xml,内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <mappers>
        <mapper resource="sqlmap/goods/goods-info.xml" />
    </mappers>
</configuration>

6、在META-INF/spring路径下增加配置文件:myteay-common-dal.xml,内容如下:

<?xml version="1.0" encoding="GBK"?>

    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
        xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
        xsi:schemaLocation="
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-4.0.xsd
            http://www.springframework.org/schema/tx
            http://www.springframework.org/schema/tx/spring-tx-4.0.xsd"
	default-autowire="byName">
	<!-- ============================================================================ -->
	<!-- ============================  DataSource配置   =============================== -->
	<!-- ============================================================================ -->
	<bean id="myteayDinnerDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
		<property name="driverClassName">
			<value>org.gjt.mm.mysql.Driver</value>
		</property>
		<property name="url">
			<value>jdbc:mysql://192.168.56.102:3306/dinner?useUnicode=true&amp;characterEncoding=gbk</value>
		</property>
		<property name="username">
			<value>dinner</value>
		</property>
		<property name="password">
			<value>ali88</value>
		</property>
	</bean>
	<!-- ============================================================================ -->

    <!-- sqlSessionFactory -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="myteayDinnerDataSource"></property>
        <property name="configLocation" value="classpath:sqlmap/mybatis-config.xml" />
    </bean>

    <!-- transactionManager -->
    <bean id="transactionManager"
        class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="myteayDinnerDataSource"></property>
    </bean>

    <!-- 使用声明式事务 -->
    <tx:annotation-driven transaction-manager="transactionManager" />

</beans>

 7、在META-INF/spring路径下增加另外一个配置文件:myteay-common-dao.xml,将当前写到的DAO加入到spring,内容如下:

<?xml version="1.0" encoding="GBK"?>

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:webflow="http://www.springframework.org/schema/webflow-config"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
         http://www.springframework.org/schema/webflow-config http://www.springframework.org/schema/webflow-config/spring-webflow-config-2.4.xsd"
	default-autowire="byName">
	<!-- goodsInfoDAO -->
	<bean id="goodsInfoDAO" class="com.myteay.common.dal.dinner.ibatis.IbatisGoodsInfoDAO"/>

</beans>

8、在spring总配置中增加spring配置的加载策略:

<import resource="classpath*:/META-INF/spring/myteay-*.xml"/>

 完整配置如下:

<?xml version="1.0" encoding="GBK"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd
        http://www.springframework.org/schema/beans
                http://www.springframework.org/schema/beans/spring-beans-4.1.xsd
        http://www.springframework.org/schema/context
                http://www.springframework.org/schema/context/spring-context-4.1.xsd"
	default-autowire="byName">
	<description>Spring MVC Configuration</description>
	<import resource="classpath*:/META-INF/spring/myteay-*.xml"/>
	<mvc:default-servlet-handler/>
	<!-- 对静态资源文件的访问,交给default servlet handler处理 -->
	<mvc:default-servlet-handler/>

	<!-- 启用spring mvc 注解 -->
	<context:annotation-config/>

	<!-- 默认的注解映射的支持 -->
	<mvc:annotation-driven/>
	<!-- 设置使用注解的类所在的jar包 -->
	<context:component-scan base-package="com.myteay.biz.service" use-default-filters="true"></context:component-scan>

	<!-- 完成请求和注解POJO的映射 -->
	<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>

	<bean class="org.springframework.web.servlet.view.UrlBasedViewResolver">
	    <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
	    <property name="prefix" value="/WEB-INF/templates/"/>
	    <property name="suffix" value=".vm"/>
	    <property name="order" value="2"/>
	</bean>
	<!-- 配置velocity引擎 -->
    <bean id="velocityConfigurer" class="org.springframework.web.servlet.view.velocity.VelocityConfigurer">
        <property name="resourceLoaderPath" value="/WEB-INF/templates/" /><!-- 模板存放的路径 -->
        <property name="velocityProperties">
           <props>
               <prop key="directive.foreach.counter.name">loopCounter</prop>
               <prop key="directive.foreach.counter.initial.value">0</prop>
               <prop key="input.encoding">UTF-8</prop><!-- 指定模板引擎进行模板处理的编码 -->
               <prop key="output.encoding">UTF-8</prop><!-- 指定输出流的编码 -->
           </props>
       </property>
    </bean>
    <!-- 配置视图的显示 -->
    <bean id="ViewResolver" class="org.springframework.web.servlet.view.velocity.VelocityLayoutViewResolver">
        <property name="prefix" value="/WEB-INF/templates/" /><!-- 视图文件的前缀,即存放的路径 -->
        <property name="suffix" value=".vm" /><!-- 视图文件的后缀名 -->
        <!-- <property name="toolboxConfigLocation" value="classpath:tools.xml" /> --><!--toolbox配置文件路径-->
        <property name="dateToolAttribute" value="date" /><!--日期函数名称-->
        <property name="numberToolAttribute" value="number" /><!--数字函数名称-->
        <property name="contentType" value="text/html;charset=UTF-8" />
        <property name="exposeSpringMacroHelpers" value="true" /><!--是否使用spring对宏定义的支持-->
        <property name="exposeRequestAttributes" value="true" /><!--是否开放request属性-->
        <property name="requestContextAttribute" value="rc"/><!--request属性引用名称-->
        <property name="layoutUrl" value="layout/default.vm"/><!--指定layout文件-->
    </bean>
    <!-- 上传文件拦截,设置最大上传文件大小 10M=10*1024*1024(B)=10485760 bytes -->
	<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
	    <property name="maxUploadSize">
	        <value>5242880</value>
	    </property>
	</bean>
	
</beans>

9、为确保本例的相对完整,我们贴出本例的web.xml配置,便于进行后面的验证:

<?xml version="1.0" encoding="ISO-8859-1"?>
<!--
 Licensed to the Apache Software Foundation (ASF) under one or more
  contributor license agreements.  See the NOTICE file distributed with
  this work for additional information regarding copyright ownership.
  The ASF licenses this file to You under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with
  the License.  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
-->
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                      http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
  version="3.1"
  metadata-complete="true">
	<!-- Session Configuration -->
    <session-config>
        <session-timeout>30</session-timeout><!-- Session overdue times(prefix: min) -->
    </session-config>
    <display-name>Welcome to Tomcat</display-name>
    <description>Welcome to Tomcat</description>
    <!-- log4j configuration -->
	<context-param>
	    <param-name>log4jConfigLocation</param-name>
	    <param-value>/WEB-INF/log4j.xml</param-value>
	</context-param>
	<listener>
	    <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
	</listener>
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
	<!-- spring mvc dispatcher -->
    <servlet>
        <servlet-name>springmvc</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath*:/WEB-INF/applicationContext.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
	<!-- char-set configuration -->
    <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>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    <!-- welcome page configuration -->
    <welcome-file-list>
        <welcome-file>/index.html</welcome-file>
    </welcome-file-list>

    <filter-mapping>    
        <filter-name>characterEncodingFilter</filter-name>    
        <url-pattern>/*</url-pattern>  
    </filter-mapping>
    <servlet-mapping>  
        <servlet-name>springmvc</servlet-name>  
        <url-pattern>/</url-pattern>  
    </servlet-mapping>
	<servlet-mapping>
	    <servlet-name>default</servlet-name>
	    <url-pattern>*.jpg</url-pattern>
	</servlet-mapping>
	<servlet-mapping>
	    <servlet-name>default</servlet-name>
	    <url-pattern>*.gif</url-pattern>
	</servlet-mapping>
	<servlet-mapping>
	    <servlet-name>default</servlet-name>
	    <url-pattern>*.png</url-pattern>
	</servlet-mapping>
	<servlet-mapping>
	    <servlet-name>default</servlet-name>
	    <url-pattern>*.js</url-pattern>
	</servlet-mapping>
	<servlet-mapping>
	    <servlet-name>default</servlet-name>
	    <url-pattern>*.css</url-pattern>
	</servlet-mapping>
</web-app>

10、对于工程常用的log4j.xml配置这里不再贴出。

 11、开始编写验证类:

/**
 * Danlley Wei (mailto://[email protected])
 * Copyright (c) 2005-2017 All Rights Reserved.
 */
package com.myteay.common.dal.dinner.exec;

import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.util.CollectionUtils;

import com.myteay.common.dal.dinner.dao.GoodsInfoDAO;
import com.myteay.common.dal.dinner.dataobject.GoodsInfoDO;

/**
 * 测试类,验证spring与mybatis集成
 * 
 * @author danlley([email protected])
 * @version $Id: TextComponentsImpl.java, v 0.1 2017年4月3日 下午5:50:05 danlley([email protected]) Exp $
 */
public class TextComponentsImpl implements TextComponents,
                                ApplicationListener<ContextRefreshedEvent> {

    /** 日志 */
    public static final Logger logger = Logger.getLogger(TextComponentsImpl.class);

    /** goodsInfoDAO */
    private GoodsInfoDAO       goodsInfoDAO;

    /** 
     * @see org.springframework.context.ApplicationListener#onApplicationEvent(org.springframework.context.ApplicationEvent)
     */
    @Override
    public void onApplicationEvent(ContextRefreshedEvent arg0) {

        if (logger.isInfoEnabled()) {
            logger.info("进入mybatis测试类");
        }

        List<GoodsInfoDO> users = goodsInfoDAO.findAll();
        if (CollectionUtils.isEmpty(users)) {
            if (logger.isInfoEnabled()) {
                logger.info("未找到相应的数据!");
            }
            return;
        }

        for (GoodsInfoDO goodsInfoDO : users) {
            logger.warn(goodsInfoDO);
        }

        if (logger.isInfoEnabled()) {
            logger.info("测试结束!");
        }
    }

    /**
     * Setter method for property <tt>goodsInfoDAO</tt>.
     * 
     * @param goodsInfoDAO value to be assigned to property goodsInfoDAO
     */
    public void setGoodsInfoDAO(GoodsInfoDAO goodsInfoDAO) {
        this.goodsInfoDAO = goodsInfoDAO;
    }
}

注:

  • 本实现类的接口定义中没有声明任何接口方法,因此这里不再给出。
  • 这里我们借用了spring的启动加载机制来进行集成验证

在myteay-common-dao.xml文件中增加配置如下:

	<!-- textComponents -->
	<bean id="textComponents" class="com.myteay.common.dal.dinner.exec.TextComponentsImpl"></bean>

12、执行“mvn jetty:run”,查看日志执行结果如下:

2017-04-03 20:39:15,608 - INFO  - 进入mybatis测试类
2017-04-03 20:39:15,613 - WARN  - GoodsInfoDO[id=1,shopId=<null>,picAddr=<null>,goodsTitle=<null>,price=12.98,summary= 的飞洒的发,gmtCreated=<null>,gmtModified=<null>]
2017-04-03 20:39:15,614 - WARN  - GoodsInfoDO[id=2,shopId=<null>,picAddr=<null>,goodsTitle=<null>,price=23,summary= wewqeqwdedwqdwq,gmtCreated=<null>,gmtModified=<null>]
2017-04-03 20:39:15,614 - INFO  - 测试结束!

 至此,spring与mybatis的集成验证工作结束。

因为MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。所以mybatis相对于之前较早版本的ibatis,仍然保持了很好的延续性,相关配置文件的理念和之前并没有太大差异,因此整体的spring依赖版本升级工作其实相对工作量是可控的,升级过程中,大多数配置信息无需进行太多调整,而改造的重点也大多都集中在了对DAO接口实现类接口的改造。

其他需要注意的问题:

  • 注意xml配置信息中引入的dtd信息是否已经从ibatis切换到了mybatis
  • SQL语句的配置中sqlMap根路径需要切换到mapper根路径
  • 对入参的标识不再使用“双井号:#value#“,需要切换为格式:#{value}
  • 原来ibatis中用来指定返回值的属性:resultMap需要变更到resultType
  • 对原来ibatis中的insert节点,需要指明parameterType类型
  • 原来ibatis的sqlmap配置sqlMapConfig需要切换到configuration,另外原来sqlMapConfig节点下的sqlMap配置需要切换到mapper下,并将其放置在mappers节点下

切换到mybatis后,xml配置的dtd头信息配置如下:

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

sqlmap配置信息示例可以参加下面的代码:

<?xml version="1.0" encoding="GB2312"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"  "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	<mappers>
		<mapper resource="sqlmap/*********************-mapping.xml"/>
	</mappers>
</configuration>

另外需要说明的是,mybatis对同一个工程中管理多个异构数据库实例的能力比较弱,需要进行补充,我将在下一个话题中进行分享。

需要进行spring框架升级改造兄弟们,还等什么,开搞吧 O(∩_∩)O哈哈~

各位看官,原创不易啊,转载请注明出处: http://danlley.iteye.com 看在打字不易的份上,打赏一个吧

参考资料:

 http://baike.baidu.com/link?url=lcoOaiTE9l4IPSjogELFVcgQpBdhqBKmx4KoFNOvSVhnT-wjxEwHIi48ewKeg_9ZH1OjpDbH2xFrs7LWOQ-agq

猜你喜欢

转载自danlley.iteye.com/blog/2367234