在 MyBatis 中动态修改 JDBC 属性
目录
最近在写的东西打算用 Sqlite 数据库,遇到在 MyBatis 中动态指定 JDBC 属性值的需求,比如:根据用户输入的参数来指定输出的数据库文件路径。
又花了不少时间才找到实现方法,记录如下:
-
MyBatis 的 Demo 代码可以参考这位同学的 GitHub:
-
此处基于这个 Demo 来动态修改 JDBC 属性值
-
jdbc.properties
-
1 2
jdbc.driver=org.sqlite.JDBC jdbc.url=jdbc:sqlite:D:\\test\\0131_mybatis_sqlite\\test0.db
-
-
sqliteMybatisTest.xml
-
1 2 3 4 5 6 7 8 9 10 11 12 13
<!-- ... --> <environments default="development"> <environment id="development"> <!-- 当前的事务事务管理器是 JDBC --> <transactionManager type="JDBC"/> <!-- 数据源类型 POOLED:使用mybatis的连接池 --> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> </dataSource> </environment> </environments> <!-- ... -->
-
-
MyBatisUtil.java
-
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
package monster.helloworld.utils; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import java.io.IOException; import java.io.InputStream; import java.io.Reader; import java.util.Properties; public class MyBatisUtil { private static SqlSessionFactory factory = null; // 使用 static 静态代码块,只在类加载时执行一次 static { try { // mybatis 配置文件 String resource = "sqliteMybatisTest.xml"; // // InputStream 方式 // // 加载 MyBatis 的主配置文件 // InputStream inputStream = Resources.getResourceAsStream(resource); // // 方式一:使用 jdbc.properties 配置文件中的属性 // // 通过构建器(SqlSessionFactoryBuilder)构建一个SqlSessionFactory工厂对象 // // factory = new SqlSessionFactoryBuilder().build(inputStream); // // // 方式二:指定属性值,覆盖 jdbc.properties 配置文件中的属性(可以动态指定属性值) // Properties properties1 = new Properties(); // properties1.setProperty("jdbc.url", "jdbc:sqlite:D:\\test\\0131_mybatis_sqlite\\test1.db"); // // factory = new SqlSessionFactoryBuilder().build(inputStream, properties1); // factory = new SqlSessionFactoryBuilder().build(inputStream, null, properties1); // Reader 方式 Reader reader = Resources.getResourceAsReader(resource); // 方式三: // factory = new SqlSessionFactoryBuilder().build(reader); // 方式四: Properties properties2 = new Properties(); properties2.setProperty("jdbc.url", "jdbc:sqlite:D:\\test\\0131_mybatis_sqlite\\test2.db"); // factory = new SqlSessionFactoryBuilder().build(reader, properties2); factory = new SqlSessionFactoryBuilder().build(reader, null, properties2); // 参考:https://blog.csdn.net/zht666/article/details/20220849 } catch (Exception e) { e.printStackTrace(); } } public static SqlSession getSqlSession() throws IOException { return factory.openSession(); } }
-
-
换成其他数据库也可以这样实现
-
参考:
-
-
如果一个属性在不只一个地方进行了配置,那么,MyBatis 将按照下面的顺序来加载:
- 首先读取在 properties 元素体内指定的属性。
- 然后根据 properties 元素中的 resource 属性读取类路径下属性文件,或根据 url 属性指定的路径读取属性文件,并覆盖之前读取过的同名属性。
- 最后读取作为方法参数传递的属性,并覆盖之前读取过的同名属性。
因此,通过方法参数传递的属性具有最高优先级,resource/url 属性中指定的配置文件次之,最低优先级的则是 properties 元素中指定的属性。
-
也就是
new SqlSessionFactoryBuilder().build(Reader/InputStream, Properties)
方法传进去的Properties
优先级最高,其次是独立的jdbc.properties
属性文件,最后才是 MyBatis 的核心配置文件(XML)中指定的属性。
-
-