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();
}