mysql://root@localhost/mysql是什么?

偏向技术
/ 0 评论 / 191 阅读 / 正在检测是否收录...
温馨提示:
本文最后更新于2021年04月12日,已超过1111天没有更新,若内容或图片失效,请留言反馈。

在使用了fastify-mysql的项目开发中,发现连接数据库时是传的字符串mysql://root@localhost/mysql,和url地址类似,百思不得其解,正常的配置都是有多个选项的一个对象,那么常规理解就是字符串的位置一定对应选项中每个字段,那么,对应关系是如何的呢?源码走起……

点击直达最后的潘多拉魔盒

源码分析

fastify-mysql传的参数类型如下,连接类型有两种,连接池和普通连接,默认连接类型是 pool

ts
// node_modules/fastify-mysql/index.d.ts
export type ConnectionType = "connection" | "pool";

export interface MySQLOptions extends PoolOptions, ConnectionOptions {
  type?: ConnectionType;
  name?: string;
  promise?: boolean;
  connectionString?: string;
}
123456789

fastify-mysql底层使用的是mysql2,从fastify-mysql源码中得知,当 ConnectionTypepool 时,调用的是 mysql.createPool 方法,为 connection 时,调用的是 mysql.createConnection 方法

js
exports.createPool = function(config) {
  const PoolConfig = require('./lib/pool_config.js');
  return new Pool({ config: new PoolConfig(config) });
};
1234

再进一步是在 pool_config.js 中处理我们传过来的 connectionstring

js
=== line-highlight
data-line: 9-11
===
// node_modules/mysql2/lib/pool_config.js
const ConnectionConfig = require('./connection_config.js');

class PoolConfig {
  constructor(options) {
    if (typeof options === 'string') {
      options = ConnectionConfig.parseUrl(options);
    }
    this.connectionConfig = new ConnectionConfig(options);
    ……
  }
}

module.exports = PoolConfig;
1234567891011121314151617

接着在connection_config.js里面查找,发现了一个 parseUrl 的静态方法,mysql://root@localhost/mysql对应连接数据库配置参数的对应关系就出来了

对应关系

js
static parseUrl(url) {
    url = urlParse(url, true);
    const options = {
      host: url.hostname,
      port: url.port,
      database: url.pathname.substr(1)
    };
    if (url.auth) {
      const auth = url.auth.split(':');
      options.user = auth[0];
      options.password = auth[1];
    }
    if (url.query) {
      for (const key in url.query) {
        const value = url.query[key];
        try {
          // Try to parse this as a JSON expression first
          options[key] = JSON.parse(value);
        } catch (err) {
          // Otherwise assume it is a plain string
          options[key] = value;
        }
      }
    }
    return options;
  }
1234567891011121314151617181920212223242526

URL额外补充

url是统一资源定位符(Uniform Resource Locator)的缩写,他的格式为:

markdown
[comment]: <> (标准格式)
[协议类型]://[服务器地址]:[端口号]/[资源层级UNIX文件路径][文件名]?[查询]#[片段ID]

[comment]: <> (完整格式)
[协议类型]://[访问资源需要的凭证信息]@[服务器地址]:[端口号]/[资源层级UNIX文件路径][文件名]?[查询]#[片段ID]

[comment]: <> (其中[访问凭证信息]、[端口号]、[查询]、[片段ID]属于选填项)
1234567

统一资源定位符不但被用作网页地址,JDBC 客户端也使用统一资源定位符连接其数据库服务器。作为对比,ODBC 的连接字符串作用相同,但并不采用 URL 格式,而是分号和等号分隔的键值对。右侧是一个 Oracle 数据库的统一资源定位符:jdbc:datadirect:oracle://myserver:1521;sid=testdb

最终呈现

假设有这样一个地址:mysql://user:password@host:3306/database?charset=utf8,Node环境解析如下

注意,传统的urlObject方式(即以下方式)在v11.0.0开始弃用,新的方式为new URL(<URL>)

js
const urlParse = require('url').parse;
urlParse('mysql://user:password@host:3306/database?charset=utf8')

Url {
  protocol: 'mysql:',
  slashes: true,
  auth: 'user:password',
  host: 'host:3306',
  port: '3306',
  hostname: 'host',
  hash: null,
  search: '?charset=utf8',
  query: 'charset=utf8',
  pathname: '/database',
  path: '/database?charset=utf8',
  href: 'mysql://user:password@host:3306/database?charset=utf8'
}

// 通过上面的parseUrl解析之后得到
{
  host: 'host',
  port: '3306',
  database: 'database',
  user: 'user',
  password: 'password',
  charset: 'utf8'
}
123456789101112131415161718192021222324252627

总结

所以,我这一顿操作分析了个寂寞??????

满脸问号

0

评论 (0)

取消