杰瑞科技汇

MySQL与Java数据类型如何对应转换?

  • MySQL (SQL):基于关系模型,数据类型是面向存储和计算的,如 INT 用于整数,VARCHAR 用于字符串。
  • Java (OOP):基于面向对象模型,数据类型是面向对象的,如 Integer 是一个对象,可以包含 null 值;int 是一个基本数据类型,不能为 null

映射的核心就是如何将 MySQL 的关系型数据转换为 Java 的对象或基本类型

MySQL与Java数据类型如何对应转换?-图1
(图片来源网络,侵删)

核心映射原则

  1. JDBC 是桥梁:Java 通过 JDBC (Java Database Connectivity) API 与 MySQL 交互,JDBC 提供了一套标准的类型转换规则,这是最权威的映射依据。
  2. ResultSet 的获取方法:在 JDBC 中,你调用的 ResultSetgetXXX() 方法(如 getInt(), getString())决定了数据如何从 MySQL 类型转换为 Java 类型。
  3. PreparedStatement 的设置方法:同样,你调用的 PreparedStatementsetXXX() 方法决定了 Java 类型如何转换为 MySQL 类型。
  4. NULL 值的处理:这是最容易出错的地方,如果你希望一个数据库字段可以为 NULL,那么在 Java 中,必须使用对应的包装类(Wrapper Class),而不是基本类型,数据库的 INT 字段可以为 NULL,Java 中就应该用 Integer 而不是 int

常用数据类型映射对照表

下面是一个详细的、按功能分类的对照表,包含了 MySQL 类型、推荐 Java 类型、JDBC 方法以及重要说明。

MySQL 类型 推荐的 Java 类型 (JDBC getXXX) JDBC getXXX 方法 JDBC setXXX 方法 重要说明
整数类型
TINYINT(1) boolean / Boolean getBoolean() setBoolean() 通常用于布尔值。0false,非 0true
TINYINT byte / Byte getByte() setByte() 8位有符号整数,范围 -128 到 127。
SMALLINT short / Short getShort() setShort() 16位有符号整数。
INT, INTEGER int / Integer getInt() setInt() 最常用,32位有符号整数,可为 NULL 时用 Integer
BIGINT long / Long getLong() setLong() 64位有符号整数,常用于自增主键、时间戳等。
精确数值类型
DECIMAL, NUMERIC java.math.BigDecimal getBigDecimal() setBigDecimal() 用于精确计算,如货币、财务数据。强烈推荐,避免使用 float/double
FLOAT float / Float getFloat() setFloat() 单精度浮点数,不精确。
DOUBLE double / Double getDouble() setDouble() 双精度浮点数,不精确,比 float 精度高,但仍不精确。
字符串类型
CHAR, VARCHAR String getString() setString() 最常用,处理文本数据。
TEXT (各种大小) String getString() / getCharacterStream() setString() / setCharacterStream() 对于大文本,getString() 可能会因内存问题失败,推荐使用流式处理 getCharacterStream()
ENUM String / enum (自定义) getString() setString() 映射为 String,最佳实践是创建一个 Java enum 类来增强类型安全。
日期和时间类型
DATE java.sql.Date getDate() setDate() 仅包含日期 (年-月-日)。java.sql.Datejava.util.Date 的子类,但已被废弃,现代应用推荐 java.time.LocalDate
TIME java.sql.Time getTime() setTime() 仅包含时间 (时:分:秒),推荐 java.time.LocalTime
DATETIME java.sql.Timestamp getTimestamp() setTimestamp() 同时包含日期和时间,包含纳秒精度,推荐 java.time.LocalDateTime
TIMESTAMP java.sql.Timestamp getTimestamp() setTimestamp() 类似 DATETIME,但受时区影响,且范围更大,推荐 java.time.Instant
二进制类型
BLOB, BINARY, VARBINARY byte[] getBytes() setBytes() 用于存储二进制数据,如图片、文件等,对于大 BLOB,推荐使用 getBinaryStream()setBinaryStream() 以避免内存问题。
布尔类型
BIT(1) boolean / Boolean getBoolean() setBoolean() TINYINT(1) 类似,但语义更明确。

Java 8+ java.time API 的现代映射

从 Java 8 开始,官方推荐使用 java.time 包中的类来替代旧的 java.sql.Datejava.util.Date,这些类更清晰、更不可变,并且线程安全。

MySQL 类型 推荐的现代 Java 类型 转换方式
DATE java.time.LocalDate LocalDate date = resultSet.getObject("date_column", LocalDate.class);
TIME java.time.LocalTime LocalTime time = resultSet.getObject("time_column", LocalTime.class);
DATETIME java.time.LocalDateTime LocalDateTime dateTime = resultSet.getObject("datetime_column", LocalDateTime.class);
TIMESTAMP java.time.Instant Instant instant = resultSet.getObject("timestamp_column", Instant.class);

注意:要使用这种现代方式,你的 JDBC 驱动版本需要较新(MySQL Connector/J 8.0+ 支持),并且可能需要在连接字符串中添加 &useLegacyDatetimeCode=false&serverTimezone=时区


ORM 框架(如 MyBatis, JPA)中的映射

在使用 ORM (Object-Relational Mapping) 框架时,你通常不会直接操作 JDBC 方法,而是通过注解或 XML 配置来定义映射关系。

MySQL与Java数据类型如何对应转换?-图2
(图片来源网络,侵删)

MyBatis 示例

MyBatis 会自动进行类型转换,但你也可以显式指定。

<!-- UserMapper.xml -->
<select id="selectUserById" resultType="com.example.User">
  SELECT id, name, create_time FROM users WHERE id = #{id}
</select>
// User.java (POJO)
public class User {
    private Integer id;
    private String name;
    // 使用 java.time.LocalDateTime
    private LocalDateTime createTime;
    // getters and setters...
}

MyBatis 会自动将 create_time (DATETIME) 列的值映射到 User 对象的 createTime (LocalDateTime) 字段上。

JPA / Hibernate 示例

JPA 使用注解来定义映射。

// User.java (Entity)
import javax.persistence.*;
import java.time.LocalDateTime;
@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String name;
    @Column(name = "create_time")
    private LocalDateTime createTime; // JPA/Hibernate 会自动处理转换
    // getters and setters...
}

JPA 提供供了 @Temporal 注解来处理旧版的日期时间类型,但对于 java.time,通常直接使用即可。


最佳实践总结

  1. 优先考虑可为 NULL 的字段:如果数据库列允许 NULL,在 Java 中务必使用包装类 (Integer, Double, Boolean, String),而不是基本类型 (int, double, boolean),这是避免 NullPointerException 的关键。
  2. 财务数据用 BigDecimal:所有涉及金钱、价格、金额的计算,都必须使用 java.math.BigDecimal,绝对不要使用 floatdouble,因为它们会引入精度误差。
  3. 拥抱 java.time:对于新的 Java 项目,强烈推荐使用 java.time 包中的 LocalDate, LocalTime, LocalDateTime, Instant 等类来处理日期和时间,它们比旧的 API 更好用。
  4. 大对象用流:对于 TEXTBLOB 等大字段,优先使用 getCharacterStream() / setCharacterStream()getBinaryStream() / setBinaryStream(),以避免一次性将大量数据加载到内存中。
  5. 明确映射,避免隐式转换:虽然 JDBC 和 ORM 框架能进行隐式类型转换,但最好在代码或配置中显式地指定类型,这样代码更清晰,也更容易排查问题,明确调用 getInt() 而不是 getObject() 再强制转换。

掌握这些映射关系,能让你在开发数据库应用时更加得心应手,减少因类型不匹配导致的奇怪错误。

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