集成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文件如下:


  4.0.0

  com.myteay
  webinst
  0.0.1
  war

  webinst
  http://maven.apache.org

  
	
        org.apache.geronimo.specs
        geronimo-servlet_2.4_spec
        1.1.1
        provwided
    
		
		    org.slf4j
		    slf4j-nop
		    1.7.25
		
    	
		
			com.google.zxing
			core
			3.0.0
		
    	
		
			org.mysql
			mysql-connector-java-commercial
			5.1.33
		
		
			commons-dbcp
			commons-dbcp
			1.2.1
		
		
			org.mybatis
			mybatis
			3.4.2
		
    	
		
		    org.mybatis
		    mybatis-spring
		    1.3.1
		
		
		
			org.springframework
			spring-aop
			4.0.0.RELEASE
		
		
			org.springframework
			spring-beans
			4.0.0.RELEASE
		
		
			org.springframework
			spring-context
			4.0.0.RELEASE
		
		
			org.springframework
			spring-context-support
			4.0.0.RELEASE
		
		
			org.springframework
			spring-core
			4.0.0.RELEASE
		
		
			org.springframework
			spring-expression
			4.0.0.RELEASE
		
		
			org.springframework
			spring-jdbc
			4.0.0.RELEASE
		
		
			org.springframework
			spring-oxm
			4.0.0.RELEASE
		
		
			org.springframework
			spring-tx
			4.0.0.RELEASE
		
		
			org.springframework
			spring-web
			4.0.0.RELEASE
		
		
			org.springframework
			spring-webmvc
			4.0.0.RELEASE
		
		
			org.springframework
			spring-orm
			4.0.0.RELEASE
		
		
			org.springframework
			spring-test
			4.0.0.RELEASE
		
		

		
		
			jmock
			jmock
			1.2.0
		
		
			jmock
			jmock-cglib
			1.2.0
		
		
	      junit
	      junit
	      3.8.1
	      test
	    
		

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

  
  
    webinst
    
		
			org.mortbay.jetty
			maven-jetty-plugin
			6.1.26
			
				3
				
					
						80
					
				
				
					
						src/main/webapp/WEB-INF
						
							**/*.jsp
						
						
							**/*.properties
							**/*.xml
						
					
				
			
		
    
  

 

 说明:

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

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

		
			org.mybatis
			mybatis
			3.4.2
		
		
		    org.mybatis
		    mybatis-spring
		    1.3.1
		

 

对spring的关键依赖如下:


	org.springframework
	spring-aop
	4.0.0.RELEASE


	org.springframework
	spring-beans
	4.0.0.RELEASE


	org.springframework
	spring-context
	4.0.0.RELEASE


	org.springframework
	spring-context-support
	4.0.0.RELEASE


	org.springframework
	spring-core
	4.0.0.RELEASE


	org.springframework
	spring-expression
	4.0.0.RELEASE


	org.springframework
	spring-jdbc
	4.0.0.RELEASE


	org.springframework
	spring-oxm
	4.0.0.RELEASE


	org.springframework
	spring-tx
	4.0.0.RELEASE


	org.springframework
	spring-web
	4.0.0.RELEASE


	org.springframework
	spring-webmvc
	4.0.0.RELEASE


	org.springframework
	spring-orm
	4.0.0.RELEASE


	org.springframework
	spring-test
	4.0.0.RELEASE

 

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

 

下面开始进行工程完善:

 

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 id.
     * 
     * @return property value of id
     */
    public String getId() {
        return id;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    /**
     * Setter method for property gmtModified.
     * 
     * @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 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 findAll() {
        return this.getSqlSession()
            .selectList("com.myteay.common.dal.dinner.dao.GoodsInfoDAO.findAll");
    }

}
 

 

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





    

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

 

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




    
        
    

 

 

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



    
	
	
	
	
		
			org.gjt.mm.mysql.Driver
		
		
			jdbc:mysql://192.168.56.102:3306/dinner?useUnicode=true&characterEncoding=gbk
		
		
			dinner
		
		
			ali88
		
	
	

    
    
        
        
    

    
    
        
    

    
    


 

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




	
	

 

 

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

 完整配置如下:



	Spring MVC Configuration
	
	
	
	

	
	

	
	
	
	

	
	

	
	    
	    
	    
	    
	
	
    
        
        
           
               loopCounter
               0
               UTF-8
               UTF-8
           
       
    
    
    
        
        
        
        
        
        
        
        
        
        
    
    
	
	    
	        5242880
	    
	
	

 

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




	
    
        30
    
    Welcome to Tomcat
    Welcome to Tomcat
    
	
	    log4jConfigLocation
	    /WEB-INF/log4j.xml
	
	
	    org.springframework.web.util.Log4jConfigListener
	
	
		org.springframework.web.context.ContextLoaderListener
	
	
    
        springmvc
        org.springframework.web.servlet.DispatcherServlet
        
            contextConfigLocation
            classpath*:/WEB-INF/applicationContext.xml
        
        1
    
	
    
        characterEncodingFilter
        org.springframework.web.filter.CharacterEncodingFilter
        
            encoding
            UTF-8
        
        
            forceEncoding
            true
        
    
    
    
        /index.html
    

        
        characterEncodingFilter    
        /*  
    
      
        springmvc  
        /  
    
	
	    default
	    *.jpg
	
	
	    default
	    *.gif
	
	
	    default
	    *.png
	
	
	    default
	    *.js
	
	
	    default
	    *.css
	

 

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 {

    /** 日志 */
    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 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 goodsInfoDAO.
     * 
     * @param goodsInfoDAO value to be assigned to property goodsInfoDAO
     */
    public void setGoodsInfoDAO(GoodsInfoDAO goodsInfoDAO) {
        this.goodsInfoDAO = goodsInfoDAO;
    }
}

注:

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

 

 

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

	
	

 

 

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=,picAddr=,goodsTitle=,price=12.98,summary= 的飞洒的发,gmtCreated=,gmtModified=]
2017-04-03 20:39:15,614 - WARN  - GoodsInfoDO[id=2,shopId=,picAddr=,goodsTitle=,price=23,summary= wewqeqwdedwqdwq,gmtCreated=,gmtModified=]
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头信息配置如下:

 
  

 

 

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




	
		
	

 

 

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

 

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

 

 

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

集成ibatis的spring工程升级到spring4.0实操手册_第1张图片

 

参考资料:

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

 

你可能感兴趣的:(spring+ibatis,spring+mybatis,架构升级,spring4)