mysql2 Documentation

repository·master·Indexed 26 days ago

https://github.com/sidorares/node-mysql2

A high-performance MySQL client for Node.js that is API-compatible with the mysql package. It features native support for prepared statements, a promise wrapper, connection pooling, and SSL/compression. The library implements the core protocol in native JS and supports various authentication plugins, including caching_sha2_password and mysql_native_password.

Tokens
47.5K
Snippets
125
Records
216
Agent score
87%

What's inside mysql2

  1. Overview of mysql2 features

    master

    MySQL2 is a high-performance MySQL client for Node.js. It is mostly API compatible with the mysql (Node MySQL) package but provides several additional features:

    • Performance: Faster and better performance than the original mysql driver.
    • Prepared Statements: Native support for prepared statements.
    • Protocol Support: Supports MySQL Binary Log Protocol and MySQL Server features.
    • Connectivity: Supports SSL, Authentication Switch, and Compression.
    • Advanced API: Includes a Promise Wrapper, Custom Streams, and Connection Pooling.
    • Encoding: Extended support for various Encodings and Collations.
  2. Understand MySQL2 compatibility with Node MySQL

    master

    MySQL2 is designed to be mostly API compatible with the mysql (Node MySQL) package. However, there is a significant difference in how DECIMAL values are handled to prevent precision loss.

    In MySQL2, DECIMAL values (including results from SUM() and AVG() functions applied to INTEGER arguments) are returned as strings. In the original mysql package, these are returned as numbers. Use strings if you need to maintain exact precision for financial or high-precision calculations.

  3. Configure and use Connection Pools

    master

    Connection pools reuse existing connections to reduce latency. You can create a pool using mysql.createPool(). You can execute queries directly on the pool or manually acquire a connection using pool.getConnection().

    import mysql from 'mysql2/promise';
    
    const pool = mysql.createPool({
      host: 'localhost',
      user: 'root',
      database: 'test',
      waitForConnections: true,
      connectionLimit: 10,
      maxIdle: 10,
      idleTimeout: 60000,
      queueLimit: 0,
      enableKeepAlive: true,
      keepAliveInitialDelay: 0,
    });
    
    // Direct query (connection is automatically released)
    const [rows] = await pool.query('SELECT 1');
    
    // Manual connection acquisition
    const conn = await pool.getConnection();
    try {
      await conn.query('SELECT 1');
    } finally {
      conn.release(); // or pool.releaseConnection(conn)
    }
    
    await pool.end();
  4. Use the Promise-based API

    master

    In addition to the standard errback interface, mysql2 provides a thin wrapper to expose a Promise-based API. You can access this by importing from mysql2/promise or by using helper methods on the standard module.

    /* eslint-env es6 */
    const mysql = require('mysql2/promise');
    
    // Create a connection
    mysql
      .createConnection({
        /* same parameters as for non-promise createConnection */
      })
      .then((conn) => conn.query('select foo from bar'))
      .then(([rows, fields]) => console.log(rows[0].foo));
  5. Configure Multi-factor authentication (MFA)

    master

    If the server requires multi-factor authentication, it will issue an AuthNextFactor request. This request contains the name and initial data for the additional authentication factor plugin (up to 3 factors).

    You can provide additional passwords using the password2 and password3 connection configuration options. You should map these to the corresponding plugins in the authPlugins object.

    const conn = mysql.createConnection({
      user: 'test_user',
      password: 'secret1',
      password2: 'secret2',
      password3: 'secret3',
      database: 'test_database',
      authPlugins: {
        // password1 === password
        'auth-plugin1': function ({ password1 }) {
          return function (serverPluginData) {
            return clientPluginData(password1, serverPluginData);
          };
        },
        'auth-plugin2': function ({ password2 }) {
          return function (serverPluginData) {
            return clientPluginData(password2, serverPluginData);
          };
        },
        'auth-plugin3': function ({ password3 }) {
          return function (serverPluginData) {
            return clientPluginData(password3, serverPluginData);
          };
        },
      },
    });
  6. Handle MariaDB UUID, INET4, and INET6 types

    master

    MariaDB UUID, INET4, and INET6 values are returned as strings. To insert these values, bind them as strings; MariaDB will automatically convert them to its internal compact representation.

    // Reading values
    const [rows] = await connection.query('SELECT u, i4, i6 FROM t');
    // rows[0].u  === '123e4567-e89b-12d3-a456-426614174000'
    // rows[0].i4 === '203.0.113.7'
    // rows[0].i6 === '2001:db8::1'
    
    // Inserting values
    await connection.execute('INSERT INTO t (u, i4, i6) VALUES (?, ?, ?)', [
      '123e4567-e89b-12d3-a456-426614174000',
      '203.0.113.7',
      '2001:db8::1',
    ]);
  7. Enable multi-statements in connection configuration

    master

    To execute multiple SQL statements in a single query call, you must set the multipleStatements option to true within your ConnectionOptions object when creating a connection.

    import mysql, { ConnectionOptions } from 'mysql2/promise';
    
    const access: ConnectionOptions = {
      host: '',
      user: '',
      password: '',
      database: '',
      multipleStatements: true,
    };
    
    const conn = await mysql.createConnection(access);
  8. Handle connection errors using promises

    master

    When using the mysql2/promise wrapper, error handling is performed using standard try-catch blocks. This applies to createConnection, createPool, createPoolCluster, execute, and query methods.

    import mysql from 'mysql2/promise';
    
    // For createConnection
    try {
      const connection = await mysql.createConnection({
        host: '',
        user: '',
        database: '',
      });
    } catch (err) {
      if (err instanceof Error) {
        console.log(err);
      }
    }
    
    // For createPool
    const pool = mysql.createPool({
      host: '',
      user: '',
      database: '',
    });
    
    try {
      const connection = await pool.getConnection();
    } catch (err) {
      if (err instanceof Error) {
        console.log(err);
      }
    }
    
    // For createPoolCluster
    const poolCluster = mysql.createPoolCluster();
    poolCluster.add('NodeI', {
      host: '',
      user: '',
      database: '',
    });
    
    try {
      await poolCluster.getConnection('NodeI');
    } catch (err) {
      if (err instanceof Error) {
        console.log('createConnection error:', err);
      }
    }
    
    // For execute and query
    // Works for createConnection, createPool, and createPoolCluster
    try {
      const [rows] = await connection.execute('SELEC 1 + 1');
      console.log(rows);
    } catch (err) {
      if (err instanceof Error) {
        console.log('execute error:', err);
      }
    }
    
    try {
      const [rows] = await connection.query('SELEC 1 + 1');
      console.log(rows);
    } catch (err) {
      if (err instanceof Error) {
        console.log('query error:', err);
      }
    }
  9. Install mysql2 via npm

    master

    Install the mysql2 package as a dependency for your Node.js project. It is free from native bindings and works on Linux, Mac OS, and Windows.

    If you are using TypeScript, you must also install @types/node as a development dependency.

    npm install --save mysql2
    
    # For TypeScript users
    npm install --save-dev @types/node
  10. Manage PoolCluster resources with Explicit Resource Management

    master

    If you are using TypeScript, you can leverage the Explicit Resource Management proposal (using and await using) to ensure that poolCluster.end() and connection.release() are called automatically when the variables go out of scope. This prevents connection leaks and simplifies cleanup logic.

    import mysql from 'mysql2/promise';
    
    {
      // .end() is called automatically when leaving the scope
      await using poolCluster = mysql.createPoolCluster();
    
      poolCluster.add('clusterA', {
        host: 'localhost',
        user: 'root',
        database: 'test',
      });
    
      // .release() is called automatically when leaving the scope
      await using connection = await poolCluster.getConnection('clusterA');
    
      // ... some query
    }