spring整合 mybatis时 SqlSessionFactoryBean的一个小报错:Bean named ‘sqlSessionFactory‘ is expected to be of ty

15 篇文章 1 订阅
2 篇文章 0 订阅

标题盛不下了,把报错写到这
Bean named 'sqlSessionFactory' is expected to be of type 'org.mybatis.spring.SqlSessionFactoryBean' but was actually of type 'org.apache.ibatis.session.defaults.DefaultSqlSessionFactory'
在这里插入图片描述

代码背景

只是在做spring整合mybatis 的练习的时候出现的一个报错,技术版本

  • spiring: 5.3.1
  • mybatis: 3.5.3
  • mybatis-spring(sping整合mybtis的jar): 2.0.6
  • aspectjweaver: 1.9.4
  • junit: 4.13.1
  • c3p0: 0.9.5.5

核心代码如下:
applicationContext.xml

<!-- 加载配置文件 -->
<context:property-placeholder location="jdbcConfig.properties"/>
<!-- 配置数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="driverClass" value="${jdbc.driver}"/>
    <property name="jdbcUrl" value="${jdbc.url}"/>
    <property name="user" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
</bean>
<!-- 配置 Mybatis 的 Session 工厂 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <!-- 数据库连接池 -->
    <property name="dataSource" ref="dataSource"/>
    <!-- 文件映射器 -->
    <property name="configLocation" value="classpath:mybatis-config.xml"/>
    <!-- 自动扫描 mapper.xml 文件 -->
    <property name="mapperLocations" value="classpath:com/krlin/mybatis/dao/*.xml"/>
</bean>

按照spring 的理解,这样就是在 spring 的 IOC 容器中 存了两个JAVA对象,一个是存放数据库配置数据的 dataSource ,一个是 mybatis 的 核心对象 sqlSessionFactory

按照常理,放在IOC 容器中的对象可以获取并使用,于是测试类中:

@Test
public void dataSourceTest() {
    /** 使用 ApplicationContext 接口, 获取 spring 容器 */
    ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
    /** 根据 bean 的 id 获取对象 */
    ComboPooledDataSource dataSource = ac.getBean("dataSource", ComboPooledDataSource.class);
    System.out.println(dataSource.getJdbcUrl());
    System.out.println(dataSource.getUser());
    System.out.println(dataSource.getPassword());
}
@Test
public void SqlSessionFactoryTest() {
    ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
    SqlSessionFactoryBean sqlSessionFactory = ac.getBean("sqlSessionFactory", SqlSessionFactoryBean.class);
    System.out.println(sqlSessionFactory);

代码分析

第一个 dataSource 的测试没有问题,第二个就报错了 Bean named 'sqlSessionFactory' is expected to be of type 'org.mybatis.spring.SqlSessionFactoryBean' but was actually of type 'org.apache.ibatis.session.defaults.DefaultSqlSessionFactory'
翻译一下也很简单, sqlSessionFactory 应该是 org.mybatis.spring.SqlSessionFactoryBean类型的,但是实际上却是 org.apache.ibatis.session.defaults.DefaultSqlSessionFactory 类型的。

心想不对啊,我在配置文件中提供的类就是 SqlSessionFactoryBean 没错啊,怎么会出现一个其他的类,进入 SqlSessionfactoryBean 发现
在这里插入图片描述
他实现了 FactoryBean<T> 接口,原来是当实现了这个接口的 Bean 放到 IOC容器的时候,那么容器中实际存放的其实就是 这个泛型T 的类型,这也就不难理解,我们需要的 SqlSessionFactorySqlSessionFactoryBean 来提供的,因为 SqlSessionFactoryBean 实现的接口的泛型就是 sqlSessionFactory, 所以看似我们 放置了 SqlSessionFactoryBean, 但实际上在 IOC 中是一个 SqlSessionFactory罢了。

查看SqlSessionFactory 发现他是一个接口
在这里插入图片描述
他有两个实现类,而第一个实现类,就是放入到 IOC 里边的类型,所以我们在测试的时候,就会出现类型不匹配了。

解决办法也很简单,我们在测试类中,用 DefaultSqlSessionFactory 来接收就行了

@Test
public void SqlSessionFactoryTest() {
    ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
    DefaultSqlSessionFactory sqlSessionFactory = ac.getBean("sqlSessionFactory", DefaultSqlSessionFactory.class);
    SysUserMapper mapper = sqlSessionFactory.openSession(true).getMapper(SysUserMapper.class);
    List<SysUserEntity> userList = mapper.getUserList();
    userList.forEach(System.out::println);
}

打印数据也没有问题(虽然我们平时也不这么用,但是逻辑上是可以同的)
在这里插入图片描述

代码本身没问题,就是自己的理解没有到位,没有看透 SqlSessionFactoryBean 背后的本质。

  • 6
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值