杰瑞科技汇

java mysql 类型对应

Java 中处理数据库数据几乎总是使用 java.sql 包下的类型,而不是它们在 java.lang 包下的原始对应物(如 int, String

  • 你在 Java 代码中定义的实体类(POJO)可以使用基本类型或包装类型。
  • 但在与 JDBC 交互时(PreparedStatement, ResultSet),你使用的 setXxx()getXxx() 方法的参数和返回值类型,必须是 java.sql 包中的类型。

详细类型对照表

这个表格分为三列:

  1. MySQL 类型: 你在创建表时使用的 SQL 类型。
  2. JDBC 类型 (java.sql): 你在 JDBC 代码中使用的类型,用于设置和获取数据。
  3. Java 常用类型: 你在 Java 实体类(POJO)中通常使用的类型,这是业务逻辑层最常用的类型。
MySQL 类型 JDBC 类型 (java.sql.*) Java 常用类型 (POJO) 说明
数值类型
TINYINT TINYINT Byte, byte 1字节整数,常用于布尔值(0/1)。
SMALLINT SMALLINT Short, short 2字节整数。
INT, INTEGER INTEGER Integer, int 4字节整数,最常用的整数类型。
BIGINT BIGINT Long, long 8字节整数,用于大整数,如自增主键、时间戳。
FLOAT FLOAT Float, float 单精度浮点数。
DOUBLE DOUBLE Double, double 双精度浮点数。
DECIMAL, NUMERIC DECIMAL java.math.BigDecimal 精确的小数计算,推荐用于货币、财务等场景。避免使用 float/double
字符串类型
CHAR CHAR String 定长字符串。
VARCHAR VARCHAR String 变长字符串,最常用的文本类型。
TEXT (long) LONGVARCHAR String 长文本。
TINYTEXT (short) VARCHAR String 短文本。
MEDIUMTEXT (medium) LONGVARCHAR String 中等长度文本。
日期和时间类型
DATE DATE java.sql.Date 仅存储日期(年-月-日)。
TIME TIME java.sql.Time 仅存储时间(时:分:秒)。
DATETIME TIMESTAMP java.sql.Timestamp 存储日期和时间(年-月-日 时:分:秒),范围到 9999-12-31 23:59:59
TIMESTAMP TIMESTAMP java.sql.Timestamp 存储日期和时间,但范围较小(1970-01-012038-01-19),会根据时区变化。
二进制类型
BINARY BINARY byte[] 定长二进制数据。
VARBINARY VARBINARY byte[] 变长二进制数据。
BLOB (large) BLOB byte[], java.sql.Blob 二进制大对象,用于存储图片、文件等。
TINYBLOB (short) VARBINARY byte[] 小二进制对象。
其他类型
BIT BIT Boolean, boolean 位字段,可以存储多个位。
JSON VARCHAR, LONGVARCHAR 或特定类型 String, JSONObject (e.g., from org.json or com.fasterxml.jackson.databind) MySQL 5.7+ 支持,JDBC 驱动通常将其作为字符串处理,也可以使用特定库解析为 JSON 对象。

关键点与最佳实践

java.sql.Date, Time, Timestamp

这是最容易混淆的地方,它们都继承自 java.util.Date,但用途不同。

  • java.sql.Date: 只包含日期信息(没有时间部分)。

    • 从数据库获取 DATE 字段时,使用 resultSet.getDate()
    • 向数据库设置 DATE 字段时,使用 preparedStatement.setDate()
    • 注意: java.sql.Date 的构造函数需要一个毫秒值,这个毫秒值会被截断,只保留日期部分。
  • java.sql.Time: 只包含时间信息(没有日期部分)。

    • 用于 TIME 字段。
  • java.sql.Timestamp: 同时包含日期和时间信息,精度到纳秒。

    • 这是 MySQL 的 DATETIMETIMESTAMP 字段在 Java 中的最佳映射。
    • Timestampjava.util.Date 的子类,但增加了一些额外的方法。

如何转换?

// 从 java.util.Date 转换
java.util.Date utilDate = new java.util.Date();
// 转换为 java.sql.Date (只保留日期)
java.sql.Date sqlDate = new java.sql.Date(utilDate.getTime());
// 转换为 java.sql.Timestamp (保留日期和时间)
java.sql.Timestamp timestamp = new java.sql.Timestamp(utilDate.getTime());
// 反向转换
java.util.Date dateFromTimestamp = timestamp; // Timestamp 可以直接赋值给 util.Date

BigDecimal 与浮点数

对于涉及金钱、财务、科学计算等需要高精度的场景,必须使用 BigDecimal

  • 为什么? floatdouble 是基于二进制的浮点数,无法精确表示所有十进制小数。1 + 0.2double 中结果不等于 3
  • 如何使用?
    • 从数据库读取 DECIMAL 字段时,使用 resultSet.getBigDecimal()
    • 向数据库写入时,使用 preparedStatement.setBigDecimal()
// 正确的做法
BigDecimal price = resultSet.getBigDecimal("price");
preparedStatement.setBigDecimal("price", new BigDecimal("123.45"));
// 错误的做法(可能导致精度丢失)
double price = resultSet.getDouble("price"); 
preparedStatement.setDouble("price", 123.45);

NULL

  • 当数据库字段为 NULL 时,调用 getXxx() 方法(如 getString(), getInt())会返回 null(对于对象类型)或抛出 NullPointerException(对于基本类型 int, double 等)。
  • 在设置参数时,可以使用 preparedStatement.setNull(columnIndex, Types.VARCHAR) 来显式地设置一个 NULL 值。

使用 ResultSetMetaData 获取类型

如果你在编写通用的数据库操作工具(如 ORM 框架),你可能不知道查询结果的具体列类型,这时可以使用 ResultSetMetaData 来动态获取信息。

ResultSetMetaData metaData = resultSet.getMetaData();
int columnCount = metaData.getColumnCount();
for (int i = 1; i <= columnCount; i++) {
    String columnName = metaData.getColumnName(i);
    int columnType = metaData.getColumnType(i); // 返回 java.sql.Types 中的常量
    String columnTypeName = metaData.getColumnTypeName(i); // 返回数据库类型名,如 "VARCHAR", "INT"
    // 根据columnType决定调用哪个getXxx()方法
    switch (columnType) {
        case Types.VARCHAR:
            String value = resultSet.getString(i);
            break;
        case Types.INTEGER:
            int intValue = resultSet.getInt(i);
            break;
        // ... 其他类型
    }
}
场景 推荐做法
定义数据库表 根据业务需求选择合适的 MySQL 类型。
JDBC 交互 严格使用 java.sql 包下的类型(java.sql.Date, java.sql.Timestamp, java.sql.Blob 等)。
Java 实体类 (POJO) 使用 Java 基本类型及其包装类、StringBigDecimal 等。
日期时间 MySQL DATETIME -> Java java.sql.Timestamp,MySQL DATE -> Java java.sql.Date
精确小数 MySQL DECIMAL -> Java java.math.BigDecimal
处理 NULL 始终检查 resultSet.getObject() 的返回值是否为 null

遵循这些原则,可以避免绝大多数因类型不匹配而导致的错误,并写出更健壮、更可靠的数据库应用程序。

分享:
扫描分享到社交APP
上一篇
下一篇