MyBatis之databaseIdProvider多数据库支持
2016-05-13 16:40
465 查看
一、databaseIdProvider官方描述
MyBatis 可以根据不同的数据库厂商执行不同的语句,这种多厂商的支持是基于映射语句中的 databaseId 属性。 MyBatis 会加载不带 databaseId 属性和带有匹配当前数据库 databaseId 属性的所有语句。 如果同时找到带有 databaseId 和不带 databaseId 的相同语句,则后者会被舍弃。这里什么意思呢 ,如果你仔细看过mybatis的官方文档中关于XML映射文件章节中的 select
<select id="selectPerson" parameterType="int" parameterMap="deprecated" resultType="hashmap" resultMap="personResultMap" flushCache="false" useCache="true" timeout="10000" fetchSize="256" statementType="PREPARED" resultSetType="FORWARD_ONLY">
下面的解释中有一个databaseId属性: 如果配置了 databaseIdProvider,MyBatis 会加载所有的不带 databaseId 或匹配当前 databaseId 的语句;如果带或者不带的语句都有,则不带的会被忽略。新增,修改和删除都有这个属性。例如mysql的获取系统时间函数 NOW() 和oracle的获取系统时间to_char(sysdate,’yyyy-mm-dd hh24:mi:ss’) 是不同的。那么我们可以针对同一个修改可以写两个update语句,他们的databaseId属性不一样。
再比如数据库数据分页见MyBatis 入门(六)–分页查询(1)和MyBatis 入门(六)–分页查询(2) -插件方式他们的语句就是不一样,就可以利用这种模式获取当前数据,再做不同的处理。
为支持多厂商特性只要像下面这样在 mybatis-config.xml 文件中加入 databaseIdProvider 即可:
配置
<databaseIdProvider type="DB_VENDOR" />
这里的 DB_VENDOR 会通过 DatabaseMetaData#getDatabaseProductName() 返回的字符串进行设置 见JDBC-基础。 由于通常情况下这个字符串都非常长而且相同产品的不同版本会返回不同的值,所以最好通过设置属性别名来使其变短,如下:
<databaseIdProvider type="DB_VENDOR"> <property name="MySQL" value="mysql"/> <property name="Oracle" value="oracle" /> </databaseIdProvider>
在有 properties 时,DB_VENDOR databaseIdProvider 的将被设置为第一个能匹配数据库产品名称的属性键对应的值,如果没有匹配的属性将会设置为 “null”。 在这个例子中,如果 getDatabaseProductName() 返回“Oracle (DataDirect)”,databaseId 将被设置为“oracle”。
你可以通过实现接口 org.apache.ibatis.mapping.DatabaseIdProvider 并在 mybatis-config.xml 中注册来构建自己的 DatabaseIdProvider:
public interface DatabaseIdProvider { void setProperties(Properties p); String getDatabaseId(DataSource dataSource) throws SQLException; }
应用时可以直接通过Configuration的getDatabaseId方法来获取当前数据的供应商。
二、mysql和oracle两种数据库的应用实例
在这里我们就实现mysql的获取系统时间函数 NOW() 和oracle的获取系统时间to_char(sysdate,’yyyy-mm-dd hh24:mi:ss’) 的的执行。首先配置 mybatis-config.xml
<properties resource="jdbc.properties" /> <environments default="dev"> <environment id="dev"> <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> <databaseIdProvider type="DB_VENDOR"> <property name="MySQL" value="mysql" /> <property name="Oracle" value="oracle" /> </databaseIdProvider> <mappers> <mapper class="com.elements.user.dao.dbMapper" /> </mappers>
接口和mapperXML文件
package com.elements.user.dao; public interface dbMapper { String SelectTime(); }
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="com.elements.user.dao.dbMapper" > <select id="SelectTime" resultType="String" databaseId="mysql"> SELECT NOW() FROM dual </select> <select id="SelectTime" resultType="String" databaseId="oracle"> SELECT 'oralce'||to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') FROM dual </select> </mapper>
上面的mapper文件具有相同的id,但是他们的databaseId分别是mysql和oralce。
jdbc.properties文件
#driver=com.mysql.cj.jdbc.Driver #url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf8&useSSL=true&serverTimezone=UTC #username=mybatis #password=mybatis driver=oracle.jdbc.driver.OracleDriver url=jdbc:oracle:thin:@localhost:1521:mybatis username=mybatis password=mybatis maxActive= 50
这个配置文件以及注销了mysql的链接,启用的是oralce的链接
测试类
package com.elements.user; import java.io.IOException; import java.io.InputStream; 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 org.junit.Test; import com.elements.user.dao.dbMapper; public class TestDB { @Test public void Testdb() throws IOException { String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder() .build(inputStream); SqlSession session = sqlSessionFactory.openSession(); try { dbMapper user = (dbMapper) session .getMapper(dbMapper.class); System.out.println(user.SelectTime()); } finally { session.close(); } } }
结果说明
如果当前启用的是oracle则执行databaseId=”oracle”的语句,如果mysql值执行databaseId=”mysql”的语句
项目代码地址:http://pan.baidu.com/s/1o8rMc5s
相关文章推荐
- SQL 性能调优日常积累
- redis学习笔记(19)---事务
- 一套Oracle SQL练习题及答案
- oracle存储过程,集合对象处理
- mysql delete数据 空间占用不减少的解决办法
- 数据库SQL优化大总结之 百万级数据库优化方案
- mysql 字符集转换
- mysql Emoji表情字符集转换
- mysql Emoji表情字符集转换
- NodeJS连接MongoDB数据库时报错的快速解决方法
- SQL Server创建存储过程
- DB2 SQL0964C The transaction log for the database is full
- mysql 优化
- 使用sqlite3 创建数据库
- com.edb.util.PSQLException: FATAL: role "主机名" does not exist
- scrapy-redis基础和介绍
- Oracle 'no privileges on tablespace 表空间名称' 问题解决
- ORA-01033:ORACLE initialization or shutdown in progress
- 导入oracle数据泵导出的文件
- PowerDesigner反向工程PostgreSQL数据库