Mysql数据类型TINYINT(1)与BOOLEAN踩坑记

简介: Mysql数据类型TINYINT(1)与BOOLEAN踩坑记 熟悉Mysql的同学应该都知道,Mysql查询的boolean结果将输出为0或者1.   比如: select 1=1;   其输出结果为1。

Mysql数据类型TINYINT(1)与BOOLEAN踩坑记

熟悉Mysql的同学应该都知道,Mysql查询的boolean结果将输出为0或者1.

  比如:

select 1=1;

  其输出结果为1。

  查阅mysql官方文档仅找到如下描述:

11.10 Using Data Types from Other Database Engines

To facilitate the use of code written for SQL implementations from other vendors, MySQL maps data types as shown in the following table. These mappings make it easier to import table definitions from other database systems into MySQL.

Other Vendor Type MySQL Type
BOOL TINYINT
BOOLEAN TINYINT
CHARACTER VARYING(M) VARCHAR(M)
FIXED DECIMAL
FLOAT4 FLOAT
FLOAT8 DOUBLE
INT1 TINYINT
INT2 SMALLINT
INT3 MEDIUMINT
INT4 INT
INT8 BIGINT
LONG VARBINARY MEDIUMBLOB
LONG VARCHAR MEDIUMTEXT
LONG MEDIUMTEXT
MIDDLEINT MEDIUMINT
NUMERIC DECIMAL
Other Vendor Type MySQL Type

Data type mapping occurs at table creation time, after which the original type specifications are discarded. If you create a table with types used by other vendors and then issue a DESCRIBE tbl_name statement, MySQL reports the table structure using the equivalent MySQL types. For example:

 
mysql> CREATE TABLE t (a BOOL, b FLOAT8, c LONG VARCHAR, d NUMERIC); Query OK, 0 rows affected (0.00 sec) mysql> DESCRIBE t; +-------+---------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------+---------------+------+-----+---------+-------+ | a | tinyint(1) | YES | | NULL | | | b | double | YES | | NULL | | | c | mediumtext | YES | | NULL | | | d | decimal(10,0) | YES | | NULL | | +-------+---------------+------+-----+---------+-------+ 4 rows in set (0.01 sec)

  我想说的是,今天使用一套中间件对kafka消息进行解析为mysql 语句,其中遇到如下的问题,

  1. 目标表有一字段设置类型为:tinyint(1)。
  2. 源表同步消息中接收到相同类型的数据。
  3. 其中中间件中有如下解析部分:
    复制代码
    public void setStatement(PreparedStatement statement, DatabaseType databaseType, boolean timestampChangeToLong) throws SQLException {
            if (this.value == null) {
                statement.setNull(this.index, this.sqlType);
            } else {
                switch(this.sqlType) {
                case -15:
                case -9:
                case 1:
                case 12:
                case 2005:
                    String strVal = String.valueOf(this.value);
                    statement.setString(this.index, strVal);
                    break;
                case -7:
                case 16:
                    boolean booleanVal = (Boolean)this.value; //tinyint(1) 类型的表设计字段直接进入该case,由于接收到的消息中的数据未0或者1,直接在该未知报类转换异常。
                    statement.setBoolean(this.index, booleanVal);
                    break;
                case -6:
                    int val2 = (Integer)this.value;
                    statement.setInt(this.index, val2);
                    break;
                case -5:
                    long longVal = (Long)this.value;
                    statement.setLong(this.index, longVal);
                    break;
                case 2:
                    this.setStatementDataTypeNumeric(statement);
                    break;
                case 3:
                    this.setStatementDataTypeDecimal(statement, databaseType, timestampChangeToLong);
                    break;
                case 4:
                    int val = (Integer)this.value;
                    statement.setInt(this.index, val);
                    break;
                case 5:
                    int val1 = (Integer)this.value;
                    statement.setInt(this.index, val1);
                    break;
                case 6:
                    float floatVal = (Float)this.value;
                    statement.setFloat(this.index, floatVal);
                    break;
                case 8:
                    double doubelVal = (Double)this.value;
                    statement.setDouble(this.index, doubelVal);
                    break;
                case 91:
                    this.setStatementDataTypeDate(statement, databaseType);
                    break;
                case 92:
                    Date timeVal = (Date)this.value;
                    Time sqlTime = new Time(timeVal.getTime());
                    statement.setTime(this.index, sqlTime);
                    break;
                case 93:
                    this.setStatementDataTypeTimestamp(statement, timestampChangeToLong);
                    break;
                default:
                    throw new ConsumeException("sqlType " + this.sqlType + " is not support");
                }
    
            }
        }
    复制代码

     

  4. 怎样获取的数字类型呢,代码如下:
    复制代码
    protected Database loadInternal(String database) {
            Connection connection = null;
    
            Database var28;
            try {
                connection = this.dataSource.getConnection();//获取连接
                DatabaseMetaData metaData = connection.getMetaData();//获取元数据
                String catalog = null;
                String[] tableTypes = new String[]{"TABLE"};
                String databasePattern = this.databaseSchema != null ? this.databaseSchema : database;
                ResultSet tablesResultSet = metaData.getTables((String)catalog, databasePattern, "%", tableTypes);
                Database db = new Database();
                db.setName(database);
    
                Table tablei;
                while(tablesResultSet.next()) {
                    String tableName = tablesResultSet.getString("TABLE_NAME");
                    tablei = new Table(tableName);
                    db.addTable(tablei);
                }
    
                Iterator var27 = db.getTables().iterator();
    
                while(var27.hasNext()) {
                    tablei = (Table)var27.next();
                    ResultSet columnsResultSet = metaData.getColumns((String)catalog, databasePattern, tablei.getName(), (String)null);
    
                    while(columnsResultSet.next()) {
                        String columnName = columnsResultSet.getString("COLUMN_NAME");
                        int sqlType = columnsResultSet.getInt("DATA_TYPE");//此处拿到mysql返回的字段类型
                        String typeName = columnsResultSet.getString("TYPE_NAME");
                        int size = columnsResultSet.getInt("COLUMN_SIZE");
                        boolean nullable = 1 == columnsResultSet.getInt("NULLABLE");
                        Column column = new Column();
                        column.setName(columnName);
                        column.setNullable(nullable);
                        column.setSqlType(sqlType);
                        column.setTypeName(typeName);
                        column.setSize(size);
                        tablei.addColumn(column);
                    }
                }
    
                var28 = db;
            } catch (Exception var25) {
                throw new RuntimeException("load schema exception", var25);
            } finally {
                if (connection != null) {
                    try {
                        connection.close();
                    } catch (SQLException var24) {
                        ;
                    }
                }
    
            }
    
            return var28;
        }
    复制代码

     

  5. 也就是说,字段tinyint(1)被当做boolean类型进行了返回。导致java中Integer类型无法进行强转。

  解决方法:alter talbe change `xxx` `xxx` tinyint(4) ...;即可。修改tinyint数据类型长度,mysql也就不再当做boolean类型进行返回了。

  总结:Mysql表结构设计时,要避免设计为tinyint(1)这种类型,以免与boolean类型数据结构进行混淆。引起不必要bug。当然也可以总java代码中进行修改,修改后的影响,还需另外评估。

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
相关文章
|
存储 关系型数据库 MySQL
MySQL数据库的数据类型、语法和高级查询
MySQL数据库的数据类型、语法和高级查询
281 0
|
关系型数据库 MySQL 数据库
MySQL数据库基础(数据库操作,常用数据类型,表的操作)
MySQL数据库基础(数据库操作,常用数据类型,表的操作)
281 5
|
存储 关系型数据库 MySQL
MySQL支持多种数据类型
MySQL支持多种数据类型
410 4
|
存储 关系型数据库 MySQL
MySQL数据类型
MySQL数据类型
233 3
|
存储 关系型数据库 MySQL
什么是mysql的数据类型?
什么是mysql的数据类型?
268 2
|
存储 关系型数据库 MySQL
|
关系型数据库 MySQL Linux
数据类型和运算符(MySQL服务器的安装,MySQL客户端,数据类型,运算符,MySQL的语法规范)
无论是对于初学者还是有经验的开发者,了解MySQL的安装、客户端使用、数据类型、运算符和语法规范都是至关重要的。这不仅有助于高效地管理和查询数据,而且对于设计和实现数据库解决方案来说是基础工作。通过深入学习和实践这些知识,您可以更好地发挥MySQL数据库的强大功能。
204 2
|
JavaScript 前端开发 索引
JavaScript有7个数据类型:Number, String, Boolean, Null, Undefined, Symbol(BES6)和BigInt(ES10)组成基本类型
【6月更文挑战第25天】JavaScript有7个数据类型:Number, String, Boolean, Null, Undefined, Symbol(BES6)和BigInt(ES10)组成基本类型,而Object包括Array、Function等是引用类型。Objects可以包含键值对,Array是特殊的Object。Functions也是对象。`null`和`undefined`被视为特殊的原始值。
387 1
|
SQL 存储 关系型数据库
MySQL数据库案例实战教程:数据类型、语法与高级查询详解
MySQL数据库案例实战教程:数据类型、语法与高级查询详解
437 3
|
存储 关系型数据库 MySQL
MySQL 中的 BLOB 数据类型深入解析
【8月更文挑战第31天】
3144 0

推荐镜像

更多