Could not open JDBC Connection for transaction; nested exception is java.sql.SQLException: url not s
2023-04-18 16:13:19 时间
org.springframework.transaction.CannotCreateTransactionException: Could not open JDBC Connection for transaction; nested exception is java.sql.SQLException: url not set
- 该问题是出现在使用spring将数据源配置文件引入到配置类里面的时候
spring将数据源配置文件引入到配置类的两种方式
方式一
- 方式一:创建一个数据源配置类,引入spring的配置类(不会出现数据无法注入的问题)
方式二
- 方式二:在spring的配置类里面,直接引入外部的数据源配置文件,如果在成员变量上进行注入,会出现无法注入的情况。
错误的原因分析
方式一
- import方式导入数据源配置类DataSourceConfig2,spring容器在初始化会创建DataSourceConfig2对象,也会初始化DataSourceConfig2类里面成员变量,就会通过spel表达式注入数据源文件的key对应的值。同时将配置了@Bean注解的返回对象存到容器里面
@PropertySource("classpath:db.properties") public class DataSourceConfig2 { @Value("${jdbc.driverClassName}") private String driverClassName; @Value("${jdbc.url}") private String url; @Value("${jdbc.username}") private String username; @Value("${jdbc.password}") private String password; @Bean("dataSource") public DataSource getDruidDataSource(){ DruidDataSource ds = new DruidDataSource(); ds.setDriverClassName(driverClassName); ds.setUrl(url); ds.setUsername(username); ds.setPassword(password); return ds; } } @Import({DataSourceConfig2.class}) @Configuration //spring的配置类里面引入DataSourceConfig2.class public class SpringConfigHand2 { }
方式二
- 原因:SpringConfigHand是一个配置类,spring容器不会创建SpringConfigHand对象,也就意味着不会对类中的成员变量进行赋值
- 解决方案:将通过@Value注入的数据配置到带@Bean注解的方法里面。
- 原因: spring容器会管理@Bean注解的方法的返回对象.
@Configuration @ComponentScan("com.hand.service") //导入外部配置文件 @Import(DataSourceConfig.class) public class SpringConfigHand2 { @Value("${jdbc.driver}") * String driver; @Value("${jdbc.url}") String url; @Value("${jdbc.username}") String username; @Value("${jdbc.password}") String password; /** * 通过@Bean将第三方的类初始化到容器中 * 通过@Value从外部配置文件中通过key获取的值赋值给属性 * @return 连接池对象 */ @Bean public DataSource getDataSource(){ //创建连接池对象 DruidDataSource dataSource = new DruidDataSource(); //给连接池对象的四个基本参数赋值 dataSource.setDriverClassName(driver); dataSource.setUsername(username); dataSource.setUrl(url); dataSource.setPassword(password); return dataSource; } @Bean public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource){ SqlSessionFactoryBean ssfb = new SqlSessionFactoryBean(); //设置模型类的别名扫描 ssfb.setTypeAliasesPackage("com.hand.entity"); //设置数据源:mybatis框架使用第三方的数据库连接池 ssfb.setDataSource(dataSource); return ssfb; } @Bean public MapperScannerConfigurer mapperScannerConfigurer(){ MapperScannerConfigurer msc = new MapperScannerConfigurer(); msc.setBasePackage("com.hand.dao"); return msc; } @Bean public PlatformTransactionManager createTransactionManager(DataSource dataSource){ DataSourceTransactionManager pt = new DataSourceTransactionManager(); pt.setDataSource(dataSource);//事务管理依赖底层的Connection. 从数据库连接池去connection return pt; } }
- 上述代码存在的问题就是在加载配置类的时候不会对成员变量进行赋值,所以就会出现url not set的错误。事实上,driver、url、username、password都没有set
- 解决办法:将通过@Value注入的数据配置到带@Bean注解的方法里面。即将代码上述代码的成员变量通过参数传递的方式传递给方法。
@Configuration @ComponentScan("com.hand.service") //导入外部配置文件 @Import(DataSourceConfig.class) public class SpringConfigHand2 { /** * 通过@Bean将第三方的类初始化到容器中 * 通过@Value从外部配置文件中通过key获取的值赋值给属性 * @return 连接池对象 */ @Bean public DataSource getDataSource(@Value("${jdbc.driver}") String driver, @Value("${jdbc.url}") String url, @Value("${jdbc.username}") String username, @Value("${jdbc.password}") String password){ //创建连接池对象 DruidDataSource dataSource = new DruidDataSource(); //给连接池对象的四个基本参数赋值 dataSource.setDriverClassName(driver); dataSource.setUsername(username); dataSource.setUrl(url); dataSource.setPassword(password); return dataSource; } @Bean public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource){ SqlSessionFactoryBean ssfb = new SqlSessionFactoryBean(); //设置模型类的别名扫描 ssfb.setTypeAliasesPackage("com.hand.entity"); //设置数据源:mybatis框架使用第三方的数据库连接池 ssfb.setDataSource(dataSource); return ssfb; } @Bean public MapperScannerConfigurer mapperScannerConfigurer(){ MapperScannerConfigurer msc = new MapperScannerConfigurer(); msc.setBasePackage("com.hand.dao"); return msc; } @Bean public PlatformTransactionManager createTransactionManager(DataSource dataSource){ DataSourceTransactionManager pt = new DataSourceTransactionManager(); pt.setDataSource(dataSource);//事务管理依赖底层的Connection. 从数据库连接池去connection return pt; } }
相关文章
- SpringBoot2(一)SpringBoot入门程序
- dubbo实战篇:dubbo超时设置
- 解决本地浏览器运行项目时的跨域问题Access to XMLHttpRequest at ‘file:///C:/Users/Len/Desktop/%E5%8F%AF%E4%BF%AE%E6%94%
- Chromedriver安装教程【无需翻墙】
- Web服务器配置管理
- 学习笔记——Spring中组件扫描(包含扫描、排除扫描)、Spring中完全注解开发;Spring整合Junit4步骤
- 【Windows Server 2019】Web服务 IIS 配置与管理—— IIS 的安装与基本配置 Ⅲ
- 如何在uniapp中优雅地使用WebView
- Element UI 及 Element Plus框架
- StringBuilder类
- 对象 和 json 互转 四种方式 json-lib、Gson、FastJson、Jackson
- 前端应该懂的HTTP和HTTPS知识
- CAP特性与Base理论
- Spring Boot 项目打包 .exe 可执行程序,实战来了!
- 面向对象编程(OOP)
- 【前端】浏览器的渲染流程(完整)
- 分享 6 个 Vue3 开发必备的 VSCode 插件
- aBiu的笔记汇总
- 1024程序员节带你玩转图片Exif信息获取之JavaScript
- 如何构建基于 DDD 领域驱动的微服务?