核心摘要表
这是一个快速参考表,涵盖了最常见的类型映射。

| MySQL 字段类型 | 常用 Java 类型 (JDBC) | 其他 Java 类型 (JPA/Hibernate) | 备注 |
|---|---|---|---|
| 数值类型 | |||
TINYINT |
java.lang.Byte |
Byte, Integer |
1字节,常用于布尔值 (BOOLEAN 是 TINYINT(1) 的别名) |
SMALLINT |
java.lang.Short |
Short, Integer |
2字节 |
INT, INTEGER |
java.lang.Integer |
Integer, Long |
最常用,4字节 |
BIGINT |
java.lang.Long |
Long, BigInteger |
8字节,用于ID、时间戳等大数 |
FLOAT |
java.lang.Float |
Float, Double |
单精度浮点数 |
DOUBLE |
java.lang.Double |
Double, BigDecimal |
双精度浮点数,最常用 |
DECIMAL, NUMERIC |
java.math.BigDecimal |
BigDecimal |
精确的 decimal 数值,用于财务、货币 |
| 字符串类型 | |||
CHAR |
java.lang.String |
String |
定长字符串 |
VARCHAR |
java.lang.String |
String |
最常用,变长字符串 |
TEXT |
java.lang.String |
String, Lob |
长文本 |
ENUM |
java.lang.String |
String, Integer (存储索引) |
通常映射为 String |
| 日期时间类型 | |||
DATE |
java.sql.Date |
java.time.LocalDate |
仅存储日期 |
TIME |
java.sql.Time |
java.time.LocalTime |
仅存储时间 |
DATETIME |
java.sql.Timestamp |
java.time.LocalDateTime |
日期和时间,精度到秒 |
TIMESTAMP |
java.sql.Timestamp |
java.time.LocalDateTime |
日期和时间,带时区信息,常用于 UPDATE 时间戳 |
| 二进制类型 | |||
BINARY |
byte[] |
byte[] |
定长二进制数据 |
VARBINARY |
byte[] |
byte[] |
变长二进制数据 |
BLOB |
java.sql.Blob 或 byte[] |
byte[], Lob |
二进制大对象,如图片、文件 |
| 布尔类型 | |||
BOOLEAN, TINYINT(1) |
java.lang.Boolean |
Boolean |
JDBC 中通常用 getBoolean() 或 getInt() |
详细说明与最佳实践
数值类型
这是最容易混淆的地方,关键在于理解“精度”和“范围”。
-
整数
INT是 JavaInteger的天然搭档,它们都是 4 字节,范围匹配。BIGINT和Long的关系也是如此。- 陷阱:不要用一个
BIGINT类型的数据库 ID 去映射一个 JavaInteger,如果数据超过了Integer的最大值 (约 21 亿),会导致数据溢出和错误。
-
浮点数
DOUBLE和Double是最常见的组合。- 财务计算警告:绝对不要使用
Float或Double来处理货币或需要高精度的计算! 因为它们是“浮点”类型,在计算机中无法精确表示所有小数。 - 正确做法:对于财务数据,必须使用 MySQL 的
DECIMAL或NUMERIC类型,并映射为 Java 的java.math.BigDecimal类型。BigDecimal提供了精确的十进制运算。
字符串类型
VARCHAR和String是最经典、最无脑的映射组合。TEXT通常也映射为String,如果文本非常大(比如超过几万字符),在 ORM 框架(如 JPA)中,你可能需要使用@Lob注解来明确告诉框架这是一个大对象。ENUM:JDBC 驱动通常会将ENUM当作String来处理,但在 JPA 中,你可以选择将其映射为String(存储枚举值)或Integer(存储枚举的索引),推荐使用String,更具可读性。
日期时间类型
这是另一个容易出错的地方,主要是因为 Java 8 之前的日期时间 API 设计不佳。

-
*传统 JDBC 类型 (`java.sql.`)**
java.sql.Date: 对应 MySQLDATE。java.sql.Time: 对应 MySQLTIME。java.sql.Timestamp: 对应 MySQLDATETIME和TIMESTAMP,它比java.sql.Date更精确,包含纳秒信息。- 缺点:这些类是
java.util.Date的子类,但设计上很笨重,且线程不安全。
-
*现代 Java 8+ 时间 API (`java.time.`) - 强烈推荐**
LocalDate: 对应 MySQLDATE,只包含年月日。LocalTime: 对应 MySQLTIME,只包含时分秒。LocalDateTime: 对应 MySQLDATETIME和TIMESTAMP,包含年月日时分秒。- 优点:不可变、线程安全、API 设计优秀。
- 如何使用:现代的 JDBC 驱动(如 Connector/J 8.0+)和 JPA/Hibernate 版本都原生支持这些类型,你可以在实体类中直接使用
LocalDate,JPA 会自动处理与数据库的转换。
-
DATETIMEvsTIMESTAMPTIMESTAMP的范围更小('1970-01-01 00:00:01' 到 '2038-01-19 03:14:07' UTC),但它会根据时区自动转换。DATETIME的范围更大('1000-01-01 00:00:00' 到 '9999-12-31 23:59:59'),它不存储时区信息。- 实践建议:
- 用于记录事件发生的时间(如创建时间、更新时间),使用
TIMESTAMP,因为它能保证在不同时区的服务器上显示正确的时间。 - 用于表示一个固定的日期时间(如生日、节日),使用
DATETIME。
- 用于记录事件发生的时间(如创建时间、更新时间),使用
二进制类型
BLOB和VARBINARY通常直接映射为byte[]数组。- 在 JDBC 中,你可以使用
PreparedStatement.setBytes()和ResultSet.getBytes()来读写。 - 对于非常大的
BLOB,为了避免内存溢出,可以使用java.sql.Blob接口,通过流式(getBinaryStream())来处理数据。
JPA / Hibernate 中的映射示例
使用 JPA 时,你通常不需要直接处理 JDBC 类型,而是通过注解来声明 Java 类型。

import javax.persistence.*;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.LocalDate;
@Entity
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id; // BIGINT -> Long
private String name; // VARCHAR -> String
private BigDecimal price; // DECIMAL -> BigDecimal (财务数据)
private Integer stock; // INT -> Integer
private LocalDateTime createdAt; // DATETIME/TIMESTAMP -> LocalDateTime
private LocalDate releaseDate; // DATE -> LocalDate
@Lob // 表示这是一个大对象
private byte[] imageData; // BLOB -> byte[]
// Getters and Setters...
}
总结与关键要点
- 精确性优先:处理金钱或需要精确计算时,务必使用
DECIMAL->BigDecimal。 - 拥抱现代 API:新项目尽量使用 Java 8 的
java.time.*包(LocalDate,LocalDateTime)来处理日期时间,它们比旧的java.sql.Date和java.util.Date好用得多。 - 范围匹配:确保 Java 类型的范围足够容纳数据库类型的值。
BIGINT不要用Integer。 - 了解你的工具:如果你使用 JPA/Hibernate 这样的 ORM 框架,它们会自动处理大部分类型转换,你只需要在 Java 实体类中声明正确的 Java 类型即可,框架会根据数据库方言自动映射到对应的 SQL 类型。
- 查阅官方文档:当遇到不确定的类型时,最好的方法是查阅你所使用的 MySQL Connector/J JDBC 驱动的官方文档,其中会有最权威的类型映射说明。
