当前位置: 首页 > news >正文

注册国外网站用什么邮箱手机网站制作软件

注册国外网站用什么邮箱,手机网站制作软件,广东网站建设有限公司,杭州住房和城乡建设委员会网站目录 一、前言 二、如何配置 三、源码解读 四、自定义 一、前言 在一次项目功能测试中,发现有个sql在其他嵌入式数据库中执行正常,但是在mysql中执行失败,发现是因为有个字段在mysql中是关键字,需要使用反引号(&…

目录

一、前言

二、如何配置

三、源码解读

四、自定义


一、前言

        在一次项目功能测试中,发现有个sql在其他嵌入式数据库中执行正常,但是在mysql中执行失败,发现是因为有个字段在mysql中是关键字,需要使用反引号(``)包起来才行,但是,反引号在嵌入式数据库(如hsql)中是不支持的,这就导致,同一条sql具有不同的写法。

        让一个项目支持不同的数据库在企业开发中是一个比较常见的需求。由于不同的数据库支持的sql语法稍有差别,所以某些功能需要根据数据库的不同书写不同的sql语句。对于这种需求,首先能够想到的解决方案就是针对不同的数据库维护不同的mapper.xml文件,但是这种方案会严重增加开发和维护的成本。因为不同数据库支持的语法大部分都是相同的,不同的毕竟是少数,我们希望只重写不同的部分而重用相同的部分。

        针对这种情况,MyBatis提供了解决方案,即databaseIdProvider和databaseId。通过MyBatis提供的这种功能,我们就只需要维护一套mapper.xml文件便可。

        下面先讲解如何配置,然后在从源码层面对这个功能进行解读,最后探讨一下如何通过自定义来定制这个功能。

二、如何配置

        配置databaseIdProvider(在mybatis的配置文件中配置,比如mybatis-config.xml)

<databaseIdProvider type="DB_VENDOR"><property name="MySQL" value="mysql" /><property name="HSQL Database Engine" value="hsql" /><property name="DM DBMS" value="dm" /><property name="Derby" value="derby" />
</databaseIdProvider>

        上述配置用于决定当前databaseId的名称。在每一个property标签中,name代表数据库的productName(DatabaseMetaData#getDatabaseProductName()),value是用户自定义的databaseId名称。mybatis在初始化的时候会根据所使用的数据源得到当前databaseId的名称,得到的databaseId的名称供mybatis选择映射文件中相应的语句。比如我们使用的是Mysql数据库,则得到的databaseId名称为“mysql”。

配置databaseId

<!-- mysql数据库生效 -->
<select id="select" resultMap="XXCResultMap" databaseId="mysql">
select name, status, passwords, `keys` from test
</select><!-- 非mysql数据库则生效 -->
<select id="select" resultMap="XXCResultMap" >
select name, status, passwords, keys from test
</select>

        官方文档对databaseId的解释为:

“如果配置了 databaseIdProvider,MyBatis 会加载所有的不带 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 type="xxx.MyDatavbaseIdProvider"><property name="DB2" value="db2" /><property name="Oracle" value="oracle" /><property name="Adaptive Server Enterprise" value="sybase" /><property name="MySQL" value="mysql" />
</databaseIdProvider>

或者直接用通过xml给VendorDatabaseIdProvider注入:

http://www.dinnco.com/news/18372.html

相关文章:

  • 类似互推商盟的推广平台重庆seo公司
  • 免费在线建站免费自助建站模板
  • 成都建筑工程设计公司seo关键词排名如何
  • 杭州 高端网站建设 推荐免费推广软件下载
  • 用php做美食网站营销推广的方法有哪些
  • 浙江省最新拟提任省管干部seo排名优化课程
  • qq邮箱怎么做网站百度地图推广怎么收费标准
  • wordpress大家都用什么主题怎样优化网站排名靠前
  • 帮非法集资公司做网站违法吗大数据智能营销
  • 西安h5网站建设南京网站设计公司大全
  • 做视频网站服务器怎么选择如何在百度上建立网站
  • 赛博网站建设四川西安关键词优化排名
  • 做产品宣传网站多少钱电话营销系统
  • 纺织网站模板线上宣传渠道
  • 网站怎做找个免费的网站
  • 什么是网站黏着度关键词优化分析工具
  • 深圳企业官网网站建设哪家好营销渠道策划方案
  • 公司支付网站建设费进什么费用线上培训机构有哪些
  • 两个b2c网站的特点樱桃bt官网
  • 福建建设监理网站石家庄网站建设就找
  • 推荐 网站空间百度一下京东
  • 网站建设与管理模拟试卷一沐浴露营销软文
  • 做网站找哪家最好黄页网站推广效果
  • 邯郸做网站的公司seo营销技巧
  • 天津 网站策划职业培训学校加盟
  • 备案期间 网站想正常百度站长平台快速收录
  • 公司管理制度完整版合肥网站seo推广
  • 海城网站建设北京口碑最好的it培训机构
  • 做seo网站要多少钱seo短视频网页入口营销
  • 口碑好的品牌网站建设排名优化网站建设