MySQL JDBC 中 tinyint 处理为Boolean 的代码逻辑

Posted isea533

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MySQL JDBC 中 tinyint 处理为Boolean 的代码逻辑相关的知识,希望对你有一定的参考价值。

mysql JDBC 中 tinyint(1) 类型,在查询时默认会被处理为 Boolean 类型。

参数配置

官方文档中提供了参数配置

上图标记的两个参数可以控制如何处理 tinyint(1) 类型和 BIT 类型。

tinyInt1isBit 默认 true,因此会把 tinyint(1) 类型转换为 BIT 类型。

转换的逻辑在 com.mysql.jdbc.Field 类中的构造方法,相关的部分代码如下:

if (this.sqlType == Types.TINYINT && this.length == 1 
    && this.connection.getTinyInt1isBit()) 
    // Adjust for pseudo-boolean
    if (conn.getTinyInt1isBit()) 
        if (conn.getTransformedBitIsBoolean()) 
            this.sqlType = Types.BOOLEAN;
         else 
            this.sqlType = Types.BIT;
        
    

这里可以看到最后的 sqlType 属性会变成 Types.BIT 类型。

取值时为什么会变成 Boolean 类型呢?

类型对应关系

先看官方文档中SQL类型和Java类型的对应关系

这里可以看到 BIT 类型转换为了 Boolean 类型。这个转换规则和取值调用的具体方法有关。

通过 ResultSet.getInt(int columnIndex) 方法调用时,tinyint(1) 可以返回正常的 0~9 的值,通过 ResultSet.getBoolean(int columnIndex) 时,会按照一定的规则转换为 Boolean 类型。

只有当通过调用 ResultSet.getObject(int columnIndex) 方法时,才会按照前面 Field 中的 sqlType 类型去调用对应的 getXX类型(int columnIndex) 方法,在 com.mysql.jdbc.ResultSetImpl 中的 getObject 方法的部分代码如下:

switch (field.getSQLType()) 
   case Types.BIT:
        if (field.getMysqlType() == MysqlDefs.FIELD_TYPE_BIT && !field.isSingleBit()) 
            return getObjectDeserializingIfNeeded(columnIndex);
        
        return Boolean.valueOf(getBoolean(columnIndex));

    case Types.BOOLEAN:
        return Boolean.valueOf(getBoolean(columnIndex));

这里会通过 getBoolean(columnIndex) 取值,结果是 Boolean 类型。

MySQL 参数中的 transformedBitIsBoolean 只是觉得是否直接把 sqlType 从 BIT 转换为 Boolean 类型,不管是否转换,在 Java 中都是 Boolean 类型。

如果不想让 tinyint(1) 类型处理为 Boolean 类型,设置 tinyInt1isBit=false参数即可。

测试代码

下面是可以用来测试的代码,创建数据库,添加下面的测试表:

CREATE TABLE `test_bit` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `test` tinyint(1) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

INSERT INTO `test_bit`(`test`) VALUES (0), (1), (2);

纯JDBC测试代码(注意添加mysql驱动):

public static void main(String[] args) throws SQLException 
	//注意修改数据库test和账号密码
    //添加或去掉&tinyInt1isBit=false参数查看差异
    Connection connection = DriverManager.getConnection(
            "jdbc:mysql://127.0.0.1:3306/test?useSSL=false&tinyInt1isBit=false", "root", "root");
    PreparedStatement preparedStatement = connection.prepareStatement("select test from test_bit");
    ResultSet resultSet = preparedStatement.executeQuery();
    while (resultSet.next()) 
        Object object = resultSet.getObject(1);
        System.out.println("test: " + object + ", class: " + object.getClass());
    
    resultSet.close();
    preparedStatement.close();
    connection.close();

以上是关于MySQL JDBC 中 tinyint 处理为Boolean 的代码逻辑的主要内容,如果未能解决你的问题,请参考以下文章

MySQL "tinyInt1isBit or tinyint" 相关问题解析

tinyint用java转化为int的坑

处理将 MySQL 布尔类型从 tinyint 更改为 bit 的 liquibase 升级

MySQL 中 的 bit 类型,tinyint;

MySQL 转换为 TINYINT

Mybatis中tinyint数据自动转化为boolean处理