技术文章
>
MySQL
>
MySQL JDBC 中 tinyint(1) 处理为Boolean 的代码逻辑
MySQL JDBC 中 tinyint(1)
类型,在查询时默认会被处理为 Boolean
类型。
参数配置
官方文档中提供了参数配置:
上图标记的两个参数可以控制如何处理 tinyint(1)
类型和 BIT 类型。
tinyInt1isBit
默认 true
,因此会把 tinyint(1)
类型转换为 BIT 类型。
转换的逻辑在 com.mysql.jdbc.Field
类中的构造方法,相关的部分代码如下:
1 2 3 4 5 6 7 8 9 10 11
| if (this.sqlType == Types.TINYINT && this.length == 1 && this.connection.getTinyInt1isBit()) { 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
方法的部分代码如下:
1 2 3 4 5 6 7 8 9
| 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
参数即可。
测试代码
下面是可以用来测试的代码,创建数据库,添加下面的测试表:
1 2 3 4 5 6 7
| 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驱动):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public static void main(String[] args) throws SQLException { 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(); }
|