SpringBoot 集成 mybatis 错误: Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required

错误问题

Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required。

需要 sqlSessionFactory 或者 sqlSessionTemplate 配置。

详细错误日志如下:

2019-09-30 16:15:28 [main] WARN  o.s.b.w.s.c.AnnotationConfigServletWebServerApplicationContext - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'imagesController': Unsatisfied dependency expressed through field 'imageService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'imageService': Unsatisfied dependency expressed through field 'imagesMapper'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.demo.zhulong.base.dao.ImagesMapper' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
Related cause: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'imagesMapper' defined in file [E:\workspace\zhulong\target\classes\com\demo\zhulong\base\dao\ImagesMapper.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required
Related cause: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'imagesMapper' defined in file [E:\workspace\zhulong\target\classes\com\demo\zhulong\base\dao\ImagesMapper.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: Property 'sqlSessionFactory' or 'sqlSessionTemplate' are required
2019-09-30 16:15:28 [main] INFO  org.apache.catalina.core.StandardService - Stopping service [Tomcat]
2019-09-30 16:15:28 [main] ERROR o.a.c.core.ContainerBase.[Tomcat].[localhost].[/] - Failed to destroy the filter named [remoteIpFilter] of type [org.apache.catalina.filters.RemoteIpFilter]
java.lang.AbstractMethodError: null
	at org.apache.catalina.core.ApplicationFilterConfig.release(ApplicationFilterConfig.java:301)
	at org.apache.catalina.core.StandardContext.filterStop(StandardContext.java:4565)
	at org.apache.catalina.core.StandardContext.stopInternal(StandardContext.java:5388)
	at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:257)
	at org.apache.catalina.core.ContainerBase$StopChild.call(ContainerBase.java:1400)
	at org.apache.catalina.core.ContainerBase$StopChild.call(ContainerBase.java:1389)
	at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266)
	at java.util.concurrent.FutureTask.run(FutureTask.java)
	at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
	at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:134)
	at org.apache.catalina.core.ContainerBase.stopInternal(ContainerBase.java:976)
	at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:257)
	at org.apache.catalina.core.ContainerBase$StopChild.call(ContainerBase.java:1400)
	at org.apache.catalina.core.ContainerBase$StopChild.call(ContainerBase.java:1389)
	at java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:266)
	at java.util.concurrent.FutureTask.run(FutureTask.java)
	at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
	at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:134)
	at org.apache.catalina.core.ContainerBase.stopInternal(ContainerBase.java:976)
	at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:257)
	at org.apache.catalina.core.StandardService.stopInternal(StandardService.java:473)
	at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:257)
	at org.apache.catalina.core.StandardServer.stopInternal(StandardServer.java:994)
	at org.apache.catalina.util.LifecycleBase.stop(LifecycleBase.java:257)
	at org.apache.catalina.startup.Tomcat.stop(Tomcat.java:469)
	at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.stopTomcat(TomcatWebServer.java:254)
	at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.stop(TomcatWebServer.java:309)
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.stopAndReleaseWebServer(ServletWebServerApplicationContext.java:306)
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:144)
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:744)
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:391)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:312)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1204)
	at com.demo.zhulong.ZhuLongApplication.main(ZhuLongApplication.java:15)

错误原因

由于 SpringBoot 整合 mybatis 时,Mybatis3 高版本依赖的 jar 包 mybatis-spring-1.2.0.jar  这个版本以及高版本中,对SqlSessionDaoSupport 类中的 'sqlSessionFactory' 或 'sqlSessionTemplate' 调整了注入方式,可能由于解决多数据源的问题,取消了自动注入。

解决方法

为了解决多数据源问题,本文做法是添加 DataSource 数据源 DruidDBConfig,并在配置文件中添加相关配置项,可扩展至多数据源。
配置文件中相关配置如下,完整配置链接:GitHub

# MySQL 数据库配置
spring.datasource.primary.url=jdbc:mysql://localhost:3306/zhulong?characterEncoding=utf8&characterSetResults=utf8&autoReconnect=true&failOverReadOnly=false
spring.datasource.primary.username=root
spring.datasource.primary.password=123456789
spring.datasource.primary.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.primary.initialSize=1
spring.datasource.primary.minIdle=1
spring.datasource.primary.maxActive=100

# druid 基本配置
spring.datasource.druid.initialSize=5
spring.datasource.druid.minIdle=5
spring.datasource.druid.maxActive=30
spring.datasource.druid.WebStatFilter.exclusions=*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*
spring.datasource.druid.filter.stat.db-type=mysql
spring.datasource.druid.filter.stat.log-slow-sql=true
spring.datasource.druid.filter.stat.slow-sql-millis=200

数据源 DruidDBConfig 文件主要内容如下,相关代码注释已详细解释。完整代码见:GitHub

@Configuration
@MapperScan(basePackages = {"com.demo.zhulong.base.dao"},
        sqlSessionFactoryRef = "mysqlOneSqlSessionFactory")
public class DruidDBConfig {

    // 指定 mapping 文件地址
    private static final String MAPPER_LOCAL = "classpath*:com/demo/zhulong/base/mapping/*.xml";

    /**
     * 读取配置文件中的数据库配置
     * spring.datasource.primary.url
     * spring.datasource.primary.username=root
     * spring.datasource.primary.password=123456789
     * ...
     * 等只取公共部分 spring.datasource.primary
     * */
    @ConfigurationProperties("spring.datasource.primary")
    // 自动装配时当出现多个 Bean 时,首选含有注解 @Primary 的 Bean,否则将抛出异常
    @Primary
    // Bean 的名称与 masterSqlSessionFactory 的注解 @Qualifier 中相同
    @Bean(name = "mysqlOneDataSource")
    public DruidDataSource druidDataSource() {
        return new DruidDataSource();
    }

    @Bean(name = "mysqlOneTransactionManager")
    @Primary
    public DataSourceTransactionManager masterTransactionManager() {
        /**
         * DataSourceTransactionManager 提供了很多事务控制方法,交由 spring 管理;
         * spring 底层进行事务控制时就可以调用这个对象里面相应的方法。
         * 但是其依赖于一个数据源对象 dataSource
         * */
        return new DataSourceTransactionManager(druidDataSource());
    }

    @Bean(name = "mysqlOneSqlSessionFactory")
    @Primary
    public SqlSessionFactory masterSqlSessionFactory(@Qualifier("mysqlOneDataSource") DataSource dataSource) throws Exception {
        // 在 Spring 环境中新建 sessionFactoryBean,然后可以通过依赖注入将 SqlSessionFactory 传递给基于 MyBatis 的 DAO。
        final SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
        sessionFactoryBean.setDataSource(dataSource);
        sessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(MAPPER_LOCAL));
        // 通过设置 DataSource 与 mapping 中的 XML 文件,构建 sessionFactory 实例
        return sessionFactoryBean.getObject();
    }

}

pom 配置 druid数据源如下:

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.10</version>
        </dependency>

测试用例如下:

@RunWith(SpringRunner.class)
@SpringBootTest
public class DatasourceTest {
    @Autowired
    DataSourceProperties dataSourceProperties;

    @Autowired
    ApplicationContext applicationContext;

    @Test
    public void contextLoads() throws Exception{
        // 获取配置的数据源
        DruidDBConfig druidDBConfig = new DruidDBConfig();
        // 查看配置数据源信息
        System.out.println(druidDBConfig);
        System.out.println(druidDBConfig.getClass().getName());
        System.out.println(dataSourceProperties);
    }
}

测试用例运行结果如下:

com.demo.zhulong.config.dataSource.DruidDBConfig@34a6d9db
com.demo.zhulong.config.dataSource.DruidDBConfig
org.springframework.boot.autoconfigure.jdbc.DataSourceProperties@51ba952e

运行成功无误后,可以使用 dao 与 mapping 文件操作数据库。

参考链接

https://blog.csdn.net/u013412772/article/details/73648537

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值