MySQL 连接器/C++ 1.1 开发人员指南  /  第 9 章连接器/C++ 使用说明

第 9 章连接器/C++ 使用说明

Connector/C++ 与 JDBC 4.0 API 兼容。有关 JDBC 4.0 的信息,请参阅 JDBC 概述。另请检查examples下载包的目录。

  • Connector/C++sql::DataType类定义了以下 JDBC 标准数据类型 : UNKNOWN, BIT, TINYINT, SMALLINT, MEDIUMINT, INTEGER, BIGINT, REAL, DOUBLE, DECIMAL, NUMERIC, CHAR, BINARY, VARCHAR, VARBINARY, LONGVARCHAR, LONGVARBINARY, TIMESTAMP, DATE, TIME, GEOMETRY, ENUM, SETSQLNULL

    Connector/C++ 不支持以下 JDBC 标准数据类型:ARRAY, BLOB, CLOB, DISTINCT, FLOAT, OTHER, REF, STRUCT

  • DatabaseMetaData::supportsBatchUpdates() 返回true,因为 MySQL 通常支持批量更新。但是,Connector/C++ API 不提供用于批量更新的 API 调用。

  • 两个非 JDBC 方法允许您获取和设置无符号整数: getUInt64()getUInt()。这些可用于 ResultSetPrepared_Statement

    • ResultSet::getUInt64()

    • ResultSet::getUInt()

    • Prepared_Statement::setUInt64()

    • Prepared_Statement::setUInt()

  • DatabaseMetaData::getColumns()方法在其结果集中有 23 列,而不是 JDBC 定义的 22 列。前 22 列如 JDBC 文档中所述,但第 23 列是新的:

    23. IS_AUTOINCREMENT: 一个字符串, 如果该列是自增列 则为YES ” ,否则为NO

  • Connector/C++ 可能会为同一列返回不同的元数据,具体取决于您调用的方法。

    假设您有一个列在其规范中接受字符集和排序规则,并且您指定了二进制排序规则,例如:

    VARCHAR(20) CHARACTER SET utf8 COLLATE utf8_bin

    服务器BINARY在该列的结果集元数据中设置标志。由于标志,该 ResultSetMetaData::getColumnTypeName() 方法使用元数据和报告, BINARY列类型名称为 BINARY,如下所示:

    mysql> CREATE TABLE varbin (a VARCHAR(20) CHARACTER SET utf8 COLLATE utf8_bin);
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> select * from varbin;
    Field   1:  `a`
    Catalog:    `def`
    Database:   `test`
    Table:      `varbin`
    Org_table:  `varbin`
    Type:       VAR_STRING
    Collation:  latin1_swedish_ci (8)
    Length:     20
    Max_length: 0
    Decimals:   0
    Flags:      BINARY
    
    0 rows in set (0.00 sec)
    
    mysql> SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='varbin'\G
    *************************** 1. row ***************************
               TABLE_CATALOG: NULL
                TABLE_SCHEMA: test
                  TABLE_NAME: varbin
                 COLUMN_NAME: a
            ORDINAL_POSITION: 1
              COLUMN_DEFAULT: NULL
                 IS_NULLABLE: YES
                   DATA_TYPE: varchar
    CHARACTER_MAXIMUM_LENGTH: 20
      CHARACTER_OCTET_LENGTH: 60
           NUMERIC_PRECISION: NULL
               NUMERIC_SCALE: NULL
          CHARACTER_SET_NAME: utf8
              COLLATION_NAME: utf8_bin
                 COLUMN_TYPE: varchar(20)
                  COLUMN_KEY:
                       EXTRA:
                  PRIVILEGES: select,insert,update,references
              COLUMN_COMMENT:
    1 row in set (0.01 sec)

    但是,INFORMATION_SCHEMA在其COLUMNS表中没有暗示元数据将包含该BINARY标志。 DatabaseMetaData::getColumns()使用 INFORMATION_SCHEMA并将报告VARCHAR同一列的类型名称。它还返回不同的类型代码。

  • 在插入或更新BLOBTEXT列时,建议 Connector/C++ 开发人员不要使用setString(). 相反,使用专用的setBlob()API 函数。

    使用setString()会导致 Packet too large错误消息。setString()如果传递给使用的连接器的字符串长度超过 max_allowed_packet(减去协议中为控制目的保留的几个字节),则会发生错误。这种情况在 Connector/C++ 中没有得到处理,因为它可能会导致安全问题,例如由于恶意的长字符串而导致的非常大的内存分配请求。

    如果setBlob()使用,则不会出现此问题,因为setBlob()采用了基于std::istream. max_allowed_packet将数据从流发送到 MySQL 服务器时,Connector/C++ 使用当前设置 将流拆分为适合服务器的块 。

    警告

    使用 时setString(),无法在 max_allowed_packet将字符串传递给 Connector/C++ 之前将其设置为足够大的值。该配置选项不能在会话中更改。

    这种与 JDBC 规范的差异确保了 Connector/C++ 不易受到内存溢出攻击。

  • 一般而言,Connector/C++ 可与 MySQL 5.0 配合使用,但并不完全支持。连接 MySQL 5.0 时,某些方法可能不可用。这是因为 Information Schema 用于获取请求的信息。没有计划改进对 5.0 的支持,因为当前 MySQL 的 GA 版本是 5.6。Connector/C++ 主要针对发布时可用的 MySQL GA 版本。

    sql::MethodNotImplemented当您连接到低于 5.1 的 MySQL 服务器时 ,以下方法会抛出 异常:

    • DatabaseMetaData::getCrossReference()

    • DatabaseMetaData::getExportedKeys()

  • Connector/C++ 包含 Connection::getClientOption()JDBC API 规范中未包含的方法。原型是:

    void getClientOption(const std::string & optionName, void * optionValue)

    该方法可用于在建立数据库连接时检查连接属性设置的值。这些值通过optionValue 传递给方法的参数返回,类型为void *

    目前,getClientOption()支持获取optionValue以下选项:

    • metadataUseInfoSchema

    • defaultStatementResultType

    • defaultPreparedStatementResultType

    metadataUseInfoSchemaconnection 选项控制是否使用 Information_Schematafor 返回SHOW语句 的元数据:

    • 对于metadataUseInfoSchema,返回时将参数解释optionValue为布尔值。

    • 对于defaultStatementResultTypeand defaultPreparedStatementResultType,返回时将参数解释optionValue为整数。

    连接属性可以在通过连接属性映射建立连接时设置,也可以使用 void Connection::setClientOption(const std::string & optionName, const void * optionValue)where optionName赋值 metadataUseInfoSchema

    一些例子:

    bool isInfoSchemaUsed;
    conn->getClientOption("metadataUseInfoSchema", (void *) &isInfoSchemaUsed);
    
    int defaultStmtResType;
    int defaultPStmtResType;
    conn->getClientOption("defaultStatementResultType", (void *) &defaultStmtResType);
    conn->getClientOption("defaultPreparedStatementResultType", (void *) &defaultPStmtResType);
  • 为了获取和设置 MySQL 会话变量,Connector/C++ 支持以下MySQL_ConnectionJDBC API 标准中没有的方法:

    std::string MySQL_Connection::getSessionVariable(const std::string & varname)
    void MySQL_Connection::setSessionVariable(const std::string & varname, const std::string & value)

    getSessionVariable()等同于执行以下并获取第一个返回值:

    SHOW SESSION VARIABLES LIKE 'var_name'

    您可以在 中使用%_ SQL 模式字符var_name

    setSessionVariable()相当于执行:

    SET SESSION var_name = value
  • 获取列的值有时会返回不同的值,具体取决于调用是从 Statement 还是 Prepared Statement 进行的。这是因为用于与服务器通信的协议根据使用的是 Statement 还是 Prepared Statement 而不同。

    为了说明这一点,请考虑列已定义为 type 的情况BIGINT。然后将最负值 BIGINT插入列中。如果创建执行getUInt64()调用的 Statement 和 Prepared Statement,则每种情况下的结果都会不同。该语句返回 的最大正值BIGINT。准备好的语句返回 0。

    不同之处在于 Statements 使用文本协议,而 Prepared Statements 使用二进制协议。在这种情况下使用二进制协议,从服务器返回一个二进制值,可以将其解释为 int64. 在前面的场景中,使用 获取一个非常大的负值 getUInt64(),它获取无符号整数。由于较大的负值无法合理地转换为无符号值,因此返回 0。

    对于使用文本协议的语句,值作为字符串从服务器返回,然后根据需要进行转换。当在前面的场景中从服务器返回一个字符串值时,大的负值必须由调用的运行时库函数 strtoul()转换 getUInt64()。的行为 strtoul()取决于特定的运行时和主机操作系统,因此结果可能取决于平台。在这种情况下,实际上返回了一个很大的正值。

    虽然这种情况非常罕见,但在某些情况下,Statements 和 Prepared Statements 可能会意外地返回不同的值,但这通常只会发生在极端情况下,例如上述情况。

  • JDBC 文档 列出了 该类的许多字段。DatabaseMetaDataJDBC 似乎也 为这些字段定义了某些值。但是,Connector/C++ 没有为这些字段定义某些值。在内部使用枚举,编译器确定分配给字段的值。

    要将值与字段进行比较,请使用如下代码,而不是对属性的特定值进行假设:

    // dbmeta is an instance of DatabaseMetaData
    if (myvalue == dbmeta->attributeNoNulls) {
        ...
    }

    通常myvalue是保存元数据信息的结果集中的一列。Connector/C++ 不保证attributeNoNulls为 0。它可以是任何值。

  • 在编写存储过程时,JDBC 提供了一个额外的类,一个用于可调用语句的额外抽象层,CallableStatement类。由于此类在 Connector/C++ 中不存在,因此使用 StatementPreparedStatement类中的方法来执行使用CALL.