网站排名查询莱芜金点子广告电子版最新一期
- 作者: 五速梦信息网
- 时间: 2026年03月21日 07:30
当前位置: 首页 > news >正文
网站排名查询,莱芜金点子广告电子版最新一期,湖南省网站建设,公司网站的后台目录 一、前言 二、如何配置 三、源码解读 四、自定义 一、前言 在一次项目功能测试中#xff0c;发现有个sql在其他嵌入式数据库中执行正常#xff0c;但是在mysql中执行失败#xff0c;发现是因为有个字段在mysql中是关键字#xff0c;需要使用反引号#xff08;发现有个sql在其他嵌入式数据库中执行正常但是在mysql中执行失败发现是因为有个字段在mysql中是关键字需要使用反引号包起来才行但是反引号在嵌入式数据库如hsql中是不支持的这就导致同一条sql具有不同的写法。 让一个项目支持不同的数据库在企业开发中是一个比较常见的需求。由于不同的数据库支持的sql语法稍有差别所以某些功能需要根据数据库的不同书写不同的sql语句。对于这种需求首先能够想到的解决方案就是针对不同的数据库维护不同的mapper.xml文件但是这种方案会严重增加开发和维护的成本。因为不同数据库支持的语法大部分都是相同的不同的毕竟是少数我们希望只重写不同的部分而重用相同的部分。 针对这种情况MyBatis提供了解决方案即databaseIdProvider和databaseId。通过MyBatis提供的这种功能我们就只需要维护一套mapper.xml文件便可。 下面先讲解如何配置然后在从源码层面对这个功能进行解读最后探讨一下如何通过自定义来定制这个功能。 二、如何配置 配置databaseIdProvider在mybatis的配置文件中配置比如mybatis-config.xml databaseIdProvider typeDB_VENDORproperty nameMySQL valuemysql /property nameHSQL Database Engine valuehsql /property nameDM DBMS valuedm /property nameDerby valuederby / /databaseIdProvider 上述配置用于决定当前databaseId的名称。在每一个property标签中name代表数据库的productNameDatabaseMetaData#getDatabaseProductName()value是用户自定义的databaseId名称。mybatis在初始化的时候会根据所使用的数据源得到当前databaseId的名称得到的databaseId的名称供mybatis选择映射文件中相应的语句。比如我们使用的是Mysql数据库则得到的databaseId名称为“mysql”。 配置databaseId !– mysql数据库生效 – select idselect resultMapXXCResultMap databaseIdmysql select name, status, passwords, keys from test /select!– 非mysql数据库则生效 – select idselect resultMapXXCResultMap select name, status, passwords, keys from test /select 官方文档对databaseId的解释为 “如果配置了 databaseIdProviderMyBatis 会加载所有的不带 databaseId 或匹配当前 databaseId 的语句如果带或者不带的语句都有则不带的会被忽略”。 也就是说如果在mybatis的配置文件中没有配置 databaseIdProvider则在映射文件中配置的databaseId不会生效。 由于我们使用的是Mysql数据库得到的databaseId为“mysql”所以上述的映射片段会在生效。 三、源码解读 上面我们讲解了如何配置下面我们从源码的角度来剖析一下mybatis是如何实现这个功能的。 databaseIdprovider的默认实现是VendorDatabaseIdProvider接口为DatabaseIdProvider。 先看DatabaseIdProvider的定义 public interface DatabaseIdProvider {default void setProperties(Properties p) {}String getDatabaseId(DataSource var1) throws SQLException; } 接口很简单就两个方法。 void setProperties(Properties p) 该方法会把databaseIdprovider标签中配置的属性传递进来。 String getDatabaseId(DataSource dataSource) 该方法会将返回一个databaseId。 再看一下默认实现类VendorDatabaseIdProvider的源码 package org.apache.ibatis.mapping;import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.SQLException; import java.util.Iterator; import java.util.Properties; import java.util.Map.Entry; import javax.sql.DataSource; import org.apache.ibatis.logging.Log; import org.apache.ibatis.logging.LogFactory;public class VendorDatabaseIdProvider implements DatabaseIdProvider {private Properties properties;public VendorDatabaseIdProvider() {}public String getDatabaseId(DataSource dataSource) {if (dataSource null) {throw new NullPointerException(dataSource cannot be null);} else {try {return this.getDatabaseName(dataSource);} catch (Exception var3) {VendorDatabaseIdProvider.LogHolder.log.error(Could not get a databaseId from dataSource, var3);return null;}}}public void setProperties(Properties p) {this.properties p;}private String getDatabaseName(DataSource dataSource) throws SQLException {String productName this.getDatabaseProductName(dataSource);if (this.properties ! null) {Iterator var3 this.properties.entrySet().iterator();Entry property;do {if (!var3.hasNext()) {return null;}property (Entry)var3.next();} while(!productName.contains((String)property.getKey()));return (String)property.getValue();} else {return productName;}}private String getDatabaseProductName(DataSource dataSource) throws SQLException {Connection con dataSource.getConnection();Throwable var3 null;String var5;try {DatabaseMetaData metaData con.getMetaData();var5 metaData.getDatabaseProductName();} catch (Throwable var14) {var3 var14;throw var14;} finally {if (con ! null) {if (var3 ! null) {try {con.close();} catch (Throwable var13) {var3.addSuppressed(var13);}} else {con.close();}}}return var5;}private static class LogHolder {private static final Log log LogFactory.getLog(VendorDatabaseIdProvider.class);private LogHolder() {}} }看下不同数据库的驱动getDatabaseProductName()返回什么 默认实现就是根据数据库的getDatabaseProductName去匹配在mybatis配置文件中配置的属性然后选出databaseId。 至此我们分析完了databaseIdprovider的源码下面接着看一下databaseId是如何发挥作用的。mybatis在解析映射文件的时候首先会根据mybatis的配置文件解析出当前数据库对应的databaseId然后根据mybatis的映射文件判断配置了databaseId属性的语句是否和接卸出的databaseId匹配核心代码如下 // XMLStatementBuilder类中 private boolean databaseIdMatchesCurrent(String id, String databaseId, String requiredDatabaseId) {if (requiredDatabaseId ! null) {return requiredDatabaseId.equals(databaseId);} else if (databaseId ! null) {return false;} else {id this.builderAssistant.applyCurrentNamespace(id, false);if (!this.configuration.hasStatement(id, false)) {return true;} else {MappedStatement previous this.configuration.getMappedStatement(id, false);return previous.getDatabaseId() null;}}} 四、自定义 这里的自定义只是针对databaseIdProvider的自定义对映射文件中的databaseId不能自定义也没自定义的必要。 通过上述的分析可以看出如果要自定义databaseIdProvider只要实现接口DatabaseIdProvider便可。然后在mybatis的配置文件中将databaseIdProvider的type置为自定义的实现便可。 自定义的databaseIdProvider为 public class MyDatavbaseIdProvider implements DatabaseIdProvider {Properties props null;Overridepublic void setProperties(Properties p) {//p代表mybatis中针对databaseIdProvider配置的属性props p;}Overridepublic String getDatabaseId(DataSource dataSource) throws SQLException {//根据使用的数据源返回不同的databaseId。这里没有给出具体实现return null;} } 使用自定义的databaseIdProvider则mybatis配置文件中的配置需要做相应的调整。 databaseIdProvider typexxx.MyDatavbaseIdProviderproperty nameDB2 valuedb2 /property nameOracle valueoracle /property nameAdaptive Server Enterprise valuesybase /property nameMySQL valuemysql / /databaseIdProvider 或者直接用通过xml给VendorDatabaseIdProvider注入
- 上一篇: 网站排名seo软件杭州专业网站设计制作
- 下一篇: 网站排名方案挑号网站后台怎么更新
相关文章
-
网站排名seo软件杭州专业网站设计制作
网站排名seo软件杭州专业网站设计制作
- 技术栈
- 2026年03月21日
-
网站排版代码国外网站顶部菜单设计
网站排版代码国外网站顶部菜单设计
- 技术栈
- 2026年03月21日
-
网站你懂我意思正能量免费怎么做一个软件
网站你懂我意思正能量免费怎么做一个软件
- 技术栈
- 2026年03月21日
-
网站排名方案挑号网站后台怎么更新
网站排名方案挑号网站后台怎么更新
- 技术栈
- 2026年03月21日
-
网站排名搜索html 购物网站
网站排名搜索html 购物网站
- 技术栈
- 2026年03月21日
-
网站排名推广的优点是什么wordpress优酷无广告
网站排名推广的优点是什么wordpress优酷无广告
- 技术栈
- 2026年03月21日
