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

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

标题盛不下了,把报错写到这

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 的类型,这也就不难理解,我们需要的 SqlSessionFactory 是 SqlSessionFactoryBean 来提供的,因为 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 背后的本质。

相关文章
|
13天前
|
XML 安全 Java
|
1月前
|
缓存 Java Spring
实战指南:四种调整 Spring Bean 初始化顺序的方案
本文探讨了如何调整 Spring Boot 中 Bean 的初始化顺序,以满足业务需求。文章通过四种方案进行了详细分析: 1. **方案一 (@Order)**:通过 `@Order` 注解设置 Bean 的初始化顺序,但发现 `@PostConstruct` 会影响顺序。 2. **方案二 (SmartInitializingSingleton)**:在所有单例 Bean 初始化后执行额外的初始化工作,但无法精确控制特定 Bean 的顺序。 3. **方案三 (@DependsOn)**:通过 `@DependsOn` 注解指定 Bean 之间的依赖关系,成功实现顺序控制,但耦合性较高。
实战指南:四种调整 Spring Bean 初始化顺序的方案
|
11天前
|
安全 Java 开发者
Spring容器中的bean是线程安全的吗?
Spring容器中的bean默认为单例模式,多线程环境下若操作共享成员变量,易引发线程安全问题。Spring未对单例bean做线程安全处理,需开发者自行解决。通常,Spring bean(如Controller、Service、Dao)无状态变化,故多为线程安全。若涉及线程安全问题,可通过编码或设置bean作用域为prototype解决。
23 1
|
14天前
|
缓存 Java 数据库连接
深入探讨:Spring与MyBatis中的连接池与缓存机制
Spring 与 MyBatis 提供了强大的连接池和缓存机制,通过合理配置和使用这些机制,可以显著提升应用的性能和可扩展性。连接池通过复用数据库连接减少了连接创建和销毁的开销,而 MyBatis 的一级缓存和二级缓存则通过缓存查询结果减少了数据库访问次数。在实际应用中,结合具体的业务需求和系统架构,优化连接池和缓存的配置,是提升系统性能的重要手段。
32 4
|
14天前
|
SQL Java 数据库连接
spring和Mybatis的各种查询
Spring 和 MyBatis 的结合使得数据访问层的开发变得更加简洁和高效。通过以上各种查询操作的详细讲解,我们可以看到 MyBatis 在处理简单查询、条件查询、分页查询、联合查询和动态 SQL 查询方面的强大功能。熟练掌握这些操作,可以极大提升开发效率和代码质量。
28 3
|
19天前
|
Java 数据库连接 数据库
spring和Mybatis的逆向工程
通过本文的介绍,我们了解了如何使用Spring和MyBatis进行逆向工程,包括环境配置、MyBatis Generator配置、Spring和MyBatis整合以及业务逻辑的编写。逆向工程极大地提高了开发效率,减少了重复劳动,保证了代码的一致性和可维护性。希望这篇文章能帮助你在项目中高效地使用Spring和MyBatis。
10 1
|
2月前
|
Java 测试技术 Windows
咦!Spring容器里为什么没有我需要的Bean?
【10月更文挑战第11天】项目经理给小菜分配了一个紧急需求,小菜迅速搭建了一个SpringBoot项目并完成了开发。然而,启动测试时发现接口404,原因是控制器包不在默认扫描路径下。通过配置`@ComponentScan`的`basePackages`字段,解决了问题。总结:`@SpringBootApplication`默认只扫描当前包下的组件,需要扫描其他包时需配置`@ComponentScan`。
|
2月前
|
Java 关系型数据库 MySQL
springboot学习五:springboot整合Mybatis 连接 mysql数据库
这篇文章是关于如何使用Spring Boot整合MyBatis来连接MySQL数据库,并进行基本的增删改查操作的教程。
155 0
springboot学习五:springboot整合Mybatis 连接 mysql数据库
|
2月前
|
Java 数据库连接 Maven
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和MyBatis Generator,使用逆向工程来自动生成Java代码,包括实体类、Mapper文件和Example文件,以提高开发效率。
137 2
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。
|
2月前
|
SQL JSON Java
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和PageHelper进行分页操作,并且集成Swagger2来生成API文档,同时定义了统一的数据返回格式和请求模块。
66 1
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块