Mybatis Configuration.xml中properties属性定义
数据源配置取不到配置文件属性值
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><!--数据库配置,default表示默认采用哪一个数据库环境--><environments default="development"><!--生产环境数据库--><environment id="product"><!--使用JDBC事务管理,事务控制由mybatis--><transactionManager type="JDBC"/><!--连接池配置,type为POOLED采用连接池--><dataSource type="POOLED"><property name="driver" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/test?useSSL=TRUE"/><property name="username" value="root"/><property name="password" value="admin"/></dataSource></environment><!--开发环境数据库--><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="${driver}"/><property name="url" value="${url}"/><property name="username" value="${username}"/><property name="password" value="${password}"/></dataSource></environment></environments><!--加载映射文件--><mappers><mapper resource="mapper/hotel.mapper.xml"/></mappers>
</configuration>
此时,启动会报异常
org.apache.ibatis.exceptions.PersistenceException:
### Error querying database. Cause: java.sql.SQLException: Error setting driver on UnpooledDataSource. Cause: java.lang.ClassNotFoundException: Cannot find class: ${driver}
### The error may exist in mapper/hotel.mapper.xml
### The error may involve com.kmyang.project.hotel.beans.TbHotelMapper.queryHotelInfoById
### The error occurred while executing a query
### Cause: java.sql.SQLException: Error setting driver on UnpooledDataSource. Cause: java.lang.ClassNotFoundException: Cannot find class: ${driver}at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:150)at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:141)at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:77)at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:71)at com.kmyang.project.mybatis.MybatisTest.testCaseOne(MybatisTest.java:25)at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)at java.lang.reflect.Method.invoke(Method.java:498)at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)at org.junit.runners.ParentRunner.run(ParentRunner.java:363)at org.junit.runner.JUnitCore.run(JUnitCore.java:137)at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
Caused by: java.sql.SQLException: Error setting driver on UnpooledDataSource. Cause: java.lang.ClassNotFoundException: Cannot find class: ${driver}at org.apache.ibatis.datasource.unpooled.UnpooledDataSource.initializeDriver(UnpooledDataSource.java:221)at org.apache.ibatis.datasource.unpooled.UnpooledDataSource.doGetConnection(UnpooledDataSource.java:200)at org.apache.ibatis.datasource.unpooled.UnpooledDataSource.doGetConnection(UnpooledDataSource.java:196)at org.apache.ibatis.datasource.unpooled.UnpooledDataSource.getConnection(UnpooledDataSource.java:93)at org.apache.ibatis.datasource.pooled.PooledDataSource.popConnection(PooledDataSource.java:404)at org.apache.ibatis.datasource.pooled.PooledDataSource.getConnection(PooledDataSource.java:90)at org.apache.ibatis.transaction.jdbc.JdbcTransaction.openConnection(JdbcTransaction.java:139)at org.apache.ibatis.transaction.jdbc.JdbcTransaction.getConnection(JdbcTransaction.java:61)at org.apache.ibatis.executor.BaseExecutor.getConnection(BaseExecutor.java:338)at org.apache.ibatis.executor.SimpleExecutor.prepareStatement(SimpleExecutor.java:84)at org.apache.ibatis.executor.SimpleExecutor.doQuery(SimpleExecutor.java:62)at org.apache.ibatis.executor.BaseExecutor.queryFromDatabase(BaseExecutor.java:326)at org.apache.ibatis.executor.BaseExecutor.query(BaseExecutor.java:156)at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:109)at org.apache.ibatis.executor.CachingExecutor.query(CachingExecutor.java:83)at org.apache.ibatis.session.defaults.DefaultSqlSession.selectList(DefaultSqlSession.java:148)... 26 moreProcess finished with exit code -1
${jdbc.driver}这样的表达式获取不到properties里面的值,因为MapperScannerConigurer实际是在解析加载bean定义阶段的,这个时候要是设置sqlSessionFactory的话,会导致提前初始化一些类,这个时候,PropertyPlaceholderConfigurer还没来得及替换定义中的变量,导致把表达式当作字符串复制了,解决的办法如下:
修改为
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><!--加载属性文件--><properties resource="jdbc.properties"/><!--数据库配置,default表示默认采用哪一个数据库环境--><environments default="development"><!--生产环境数据库--><environment id="product"><!--使用JDBC事务管理,事务控制由mybatis--><transactionManager type="JDBC"/><!--连接池配置,type为POOLED采用连接池--><dataSource type="POOLED"><property name="driver" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/test?useSSL=TRUE"/><property name="username" value="root"/><property name="password" value="admin"/></dataSource></environment><!--开发环境数据库--><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver" value="${driver}"/><property name="url" value="${url}"/><property name="username" value="${username}"/><property name="password" value="${password}"/></dataSource></environment></environments><!--加载映射文件--><mappers><mapper resource="mapper/hotel.mapper.xml"/></mappers>
</configuration>
将数据库连接参数单独配置在 jdbc.properties
文件中,只需要在 Configuration.xml
(mybatis
全局配置文件)加载 jdbc.properties
的属性值。
在 Configuration.xml
中就不需要对数据库连接参数硬编码。
将数据库连接参数只配置在 jdbc.properties
中,原因:方便对参数进行统一管理,其他 xml 可以引用该 jdbc.properties
文件 。
代码实现
- 在xml 文件同级目录新建
jdbc.properties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test?useSSL=TRUE
username=root
password=admin
注意:属性值不用加引号,因为我们 Configuration.xml 里已经添加了引号,属性相关的只能换行不能空格
properties 补充
注意:Mybatis 将按以下顺序加载属性:
在 properties 元素体内定义的属性首先被读取。
然后读取 properties 元素中的 resource 或 url 加载的属性。它会覆盖已读取的同名属性
然后读取读取 parameterType 传递的属性。它会覆盖已读取的同名属性。
因此,通过 parameterType 传递的属性具有最高优先级,resource 或 url 加载的属性次之,最低优先级是 properties 元素体内定义的属性。
建议:
不要在 properties 元素体内添加任何属性值,只将属性值定义在 properties 文件中。
在 properties 文件中定义的属性值要有一定的特殊性,如 xxx.xxx.xxx , jdbc.url 等,防止与 其他属性名冲突
请点击这里本文借鉴于此