`
clxy
  • 浏览: 80092 次
社区版块
存档分类
最新评论

基于Spring,MyBatis的Interface及Class混用

阅读更多

  这篇是在玩Spring-MyBatis时遇到的问题,比较闹心,还算有趣,记下经历,以备他日不时之需。

  问题是这样:想做个共通的机制来处理大量重复的“基本的增删改查”。

  网上做了些调查,通常都是需要准备一个Class,在里面用反射来拼SQL文,然后再调用MyBatis的底层Class的SqlRunner来执行。这种方案本身倒也没什么问题,但是MyBatis现在是纯Interface的风格。所以会导致MyBatis的Dao/Mapper既有Interface又有Class同时存在。于是事情变得麻烦些。


  最初打算简单些,只写一个类,不再搞接口什么的。代码如下:

public class CommonDao extends SqlSessionDaoSupport {

	public int insert(Object object) {
		...
	}
	...
}

 
  由于使用了Spring-MyBatis的自动配置——所有Dao/Mapper的Interface会被自动注册,于是首当其冲的问题就是该类无法自动注册。这时有两个选择,一是手动注册,二是加Interface。


  手动注册最简单,于是先尝试了这个方案。添加的配置如下:

	<bean id="commonDao" class="mypackage.common.dao.CommonDao">
		<property name="sqlSessionFactory" ref="sqlSessionFactory" />
	</bean>

 

  启动时直接抛了异常,如下

org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'commonDao' must be of type [mypackage.common.dao.CommonDao], but was actually of type [com.sun.proxy.$Proxy22]

 

  一通折腾后找到了原因。由于我对所有Dao都有加了拦截器,又没有提供CGLIB,于是Spring自顾自的上了JDK的代理。可是我不明白的是,Spring你明知道那玩意儿不好用,还折腾个啥。

 

  加上CGLIB包,并强制Spring使用它,配置如下。

	<aop:aspectj-autoproxy proxy-target-class="true">
		<aop:include name="daoInterceptor" />
	</aop:aspectj-autoproxy>

 

  启动时仍然报错,这回是其他的Dao/Mapper类。报错如下:

 java.lang.IllegalArgumentException: Cannot subclass final class class com.sun.proxy.$Proxy20

 

  查下来,似乎问题出在MyBatis上。MyBatis里面写死固定使用JDK代理,导致CGLIB再企图继承JDK代理时抛的异常。参考MyBatis 3.2.2代码如下

package org.apache.ibatis.binding;
	...
public class MapperProxyFactory {

	...

  @SuppressWarnings("unchecked")
  protected T newInstance(MapperProxy mapperProxy) {
    return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
  }

  public T newInstance(SqlSession sqlSession) {
    final MapperProxy mapperProxy = new MapperProxy(sqlSession, mapperInterface, methodCache);
    return newInstance(mapperProxy);
  }
}

 

  网上搜索了下,找到这个Issue,已经被关闭,且回答是“MyBatis使用CGLIB”!啥?是我哪里理解错了吗?!


  到这里,虽然咱又是加CGLIB,又是改配置,还是死胡同一条啊!


  于是改走Interface路线。顺便改了名字CommonDao -> UtilDao。代码如下:

// 接口
public interface UtilDao {
	...
	public int insert(Object object);
	..
}

// 实现类
public class UtilDaoImpl extends SqlSessionDaoSupport implements UtilDao {
	...
	public int insert(Object object) {
		...
	}
	...
}


  CGLIB也暂时去掉,手动注册和aop:aspectj的proxy-target-class也去掉。


  再启动,这回不报错了。耶~!试着执行下,直接抛了异常。!艹!(我TYYD是在拯救世界还是什么?!不就写个共通,至于吗?!)异常如下:

org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): mypackage.common.dao.UtilDao.insert


  查下来,是被Spring-MyBatis注册在前,看来前面的手动注册还得加上去才行。配置如下:

	<bean id="utilDao" class="mypackage.common.dao.db.UtilDaoImpl">
		<property name="sqlSessionFactory" ref="sqlSessionFactory" />
	</bean>


  这样就彻底OK了。基于MyBatis的Dao/Mapper,以Interface和class的混合方式一同工作。


  结论是即需要加Interface又需要手动注册。


  累稀忒了...

 

  以下内容已经属于完善加强的部分,开始偏离主题了。哈。


  还没完,查看启动时日志,注意下面这句有些碍眼。

2013-06-16 16:11:38,744 WARN  ClassPathMapperScanner - Skipping MapperFactoryBean with name 'utilDao' and 'mypackage.common.dao.UtilDao' mapperInterface. Bean already defined with the same name! checkCandidate


  这个应该是Spring在调用MyBatis的注册时,发现已经有相同的bean时发出的警告。对这种细节稍稍比较在意,于是开始琢磨怎么完善它。


  简单说就是屏蔽掉MyBatis的注册。调查后发现Spring-MyBatis提供的MapperScannerConfigurer不提供excludeFilters!可是Spring类似的东东都是有excludeFilters和includeFilters的,您这只有个支持通配符——还不是正则表达式——的basePackage哪里够用啊?!于是自己基于MapperScannerConfigurer做个自己的DaoScanner,最终配置如下:

	<bean class="mypackage.common.dao.DaoScanner">
		<property name="basePackage" value="mypackage.*.dao" />
		<property name="excludeFilters">
			<list>
				<value><![CDATA[.*(?<!Dao)$]]></value>
				<value><![CDATA[.*UtilDao$]]></value>
			</list>
		</property>
	</bean>
	<bean id="utilDao" class="mypackage.common.dao.db.UtilDaoImpl">
		<property name="sqlSessionFactory" ref="sqlSessionFactory" />
	</bean>


  关于MapperScannerConfigurer的excludeFilters,我有去mybatis-user提过建议,得到的回答是“有些过度设计”!唔......也罢。

分享到:
评论
4 楼 ghoslin 2017-01-03  
  三年后的我在踩同一个坑
3 楼 clxy 2013-11-29  
关于那个DaoScanner,请参考

https://github.com/clxy/SSM/blob/master/src/main/java/cn/clxy/ssm/common/dao/DaoScanner.java

其他的代码也都在github上。

好久没维护了...凑合着看吧...
2 楼 想做黑客 2013-11-22  
就是呀,能提供一下daoscanner的代码吗?学习一下
1 楼 songp1314 2013-11-16  
能提供下DaoScanner不?

相关推荐

    后端基于springmybatis的微信小程序商城

    后端基于springmybatis的微信小程序商城后端基于springmybatis的微信小程序商城后端基于springmybatis的微信小程序商城后端基于springmybatis的微信小程序商城后端基于springmybatis的微信小程序商城后端基于spring...

    毕设项目:基于spring+mybatis实现高并发秒杀系统,包含详细笔记.zip

    毕设项目:基于spring+mybatis实现高并发秒杀系统,包含详细笔记 毕设项目:基于spring+mybatis实现高并发秒杀系统,包含详细笔记 毕设项目:基于spring+mybatis实现高并发秒杀系统,包含详细笔记 毕设项目:基于...

    基于Spring MVC + Spring + MyBatis的【医院就诊挂号系统】

    使用环境: MyEclipse/Eclipse + Tomcat + MySQL。...使用技术: Spring MVC + Spring + MyBatis 或 JSP + Servlet + JavaBean + JDBC。 效果:https://ymjin.blog.csdn.net/article/details/119986708

    基于Spring MVC + Spring + MyBatis的【学生管理管理系统】.zip.zip

    使用环境:MyEclipse/Eclipse + Tomcat + MySQL。 使用技术:Spring MVC + Spring + MyBatis / JSP + Servlet + JavaBean + JDBC。

    Spring MyBatis企业应用实战pdf书籍

    此外,书中还会涉及Spring MVC的集成,展示如何构建基于Spring的Web应用,并利用MyBatis作为后端数据处理引擎。 除此之外,书中可能还涵盖了实战案例,如常见的业务场景模拟,例如用户登录注册、商品管理、订单处理...

    springmybatis所有jar包

    在Java开发领域,Spring和MyBatis是两个非常重要的框架,它们被广泛用于构建企业级应用。Spring是一个全面的后端开发框架,提供了依赖注入、AOP(面向切面编程)、事务管理等功能;而MyBatis则是一个轻量级的持久层...

    基于SpringMVC+Spring+MyBatis+Maven项目案例.zip

    基于SpringMVC+Spring+MyBatis+Maven项目案例 基于SpringMVC+Spring+MyBatis+Maven项目案例 基于SpringMVC+Spring+MyBatis+Maven项目案例 基于SpringMVC+Spring+MyBatis+Maven项目案例 基于SpringMVC+Spring+MyBatis...

    Java基于Spring+SpringMVC+MyBatis实现的学生信息管理系统源码.zip

    Java基于Spring+SpringMVC+MyBatis实现的学生信息管理系统源码,SSM+Vue的学生管理系统。 Java基于Spring+SpringMVC+MyBatis实现的学生信息管理系统源码,SSM+Vue的学生管理系统。 Java基于Spring+SpringMVC+...

    springmybatis(含有mybatis-generator示例)

    在本项目"springmybatis(含有mybatis-generator示例)"中,主要展示了如何将Spring、Spring Web MVC和MyBatis框架进行集成,并且利用MyBatis Generator自动化工具生成数据库操作的代码,使得开发过程更为高效。...

    基于Spring和Mybatis和servlet的人员信息管理系统源码+数据库.zip

    基于Spring和Mybatis和servlet的人员信息管理系统源码+数据库.zip基于Spring和Mybatis和servlet的人员信息管理系统源码+数据库.zip基于Spring和Mybatis和servlet的人员信息管理系统源码+数据库.zip基于Spring和...

    spring_mybatis 整合jar包

    例如,Spring的`spring-context`、`spring-beans`、`spring-jdbc`和`spring-tx`,以及MyBatis的`mybatis`和`mybatis-spring`等。这些库分别提供了Spring的上下文、bean管理、数据库事务控制以及与MyBatis的集成接口...

    Spring Mybatis Ext整合

    《Spring Mybatis Ext整合》 在Java开发领域,Spring框架以其强大的依赖注入和管理能力,以及灵活的事务处理,成为了企业级应用开发的首选。Mybatis作为轻量级的持久层框架,以其简单易用、灵活高效的特点,深受...

    基于spring+springMvc+mybatis 开发的企业门户网站

    基于spring+springMvc+mybatis 开发的企业门户网站基于spring+springMvc+mybatis 开发的企业门户网站基于spring+springMvc+mybatis 开发的企业门户网站基于spring+springMvc+mybatis 开发的企业门户网站基于spring+...

    springMybatis+redis三级缓存框架

    "springMybatis+redis三级缓存框架"是一个高效且灵活的解决方案,它将MyBatis的二级缓存与Redis相结合,形成一个三级缓存体系,以优化数据读取速度并减轻数据库压力。 首先,MyBatis作为一款轻量级的持久层框架,其...

    spring mybatis shiro 共6天 8部分 第2部分

    spring mybatis shiro 共6天 8部分 第2部分 spring mybatis shiro 共6天 8部分 第2部分

    Spring+Mybatis+Springboot面试试题及答案.zip

    在IT行业中,Spring、Mybatis和Springboot是Java开发领域广泛应用的三大框架,它们各自承担着不同的职责并共同构建高效的企业级应用。本压缩包文件提供了这三个技术的面试试题及答案,帮助求职者或开发者更好地理解...

    《spring+mybatis 企业应用实战》源码、类库全资料

    在企业级应用开发中,Spring 和 MyBatis 是两个非常重要的框架。Spring 作为一个全面的后端开发框架,提供依赖注入、AOP(面向切面编程)、MVC(模型-视图-控制器)等核心功能,极大地提高了开发效率和代码的可维护...

    maven spring mybatis项目整合

    这是用maven,spring,mybatis整合的一个项目,只是在下边spring,mybatis项目整合的基础上加入了maven,如果你有需要可以下下来看看,在我百度空间里有关于这个的介绍 地址:...

    JavaEE Spring MyBatis框架(登录).rar

    JavaEE Spring MyBatis框架(登录)JavaEE Spring MyBatis框架(登录)JavaEE Spring MyBatis框架(登录)JavaEE Spring MyBatis框架(登录)JavaEE Spring MyBatis框架(登录)JavaEE Spring MyBatis框架(登录)JavaEE Spring ...

    spring整合Mybatis

    在IT行业中,Spring框架与Mybatis的整合是常见的企业级应用开发模式,它结合了Spring的强大功能和Mybatis的灵活性,使得数据访问更加高效。本文将深入探讨如何进行"Spring整合Mybatis"的基础搭建,以及涉及到的相关...

Global site tag (gtag.js) - Google Analytics