以下是Java与MySQL数据类型的对应关系及使用建议,整理为表格形式以便参考:
一、基本数据类型对应关系
| Java 类型 | MySQL 类型 | 说明 |
|---|
int / Integer | INT | 存储整数,范围:-2^31 ~ 2^31-1 |
long / Long | BIGINT | 存储大整数,范围:-2^63 ~ 2^63-1 |
float / Float | FLOAT | 单精度浮点数(精度约6-7位) |
double / Double | DOUBLE | 双精度浮点数(精度约15位) |
boolean / Boolean | TINYINT(1) / BIT(1) | 布尔值,TINYINT(1)存储0或1,BIT(1)更规范但兼容性略差 |
String | VARCHAR(n) / TEXT | 字符串:VARCHAR(n)适合短文本(如用户名),TEXT适合长文本(如内容) |
byte[] | BLOB | 存储二进制数据(如图片、文件) |
java.util.Date | DATETIME / TIMESTAMP | 日期时间:
DATETIME(无时区,范围1000-9999年)
TIMESTAMP(带时区,范围1970-2038年) |
BigDecimal | DECIMAL(p, s) | 精确小数,如金额(p为总位数,s为小数位数) |
LocalDate | DATE | 仅日期(JDBC 4.2+支持) |
LocalTime | TIME | 仅时间(JDBC 4.2+支持) |
LocalDateTime | DATETIME | 日期时间(无时区) |
二、特殊类型与复杂场景
| Java 类型 | MySQL 类型 | 说明 |
|---|
Enum | ENUM / VARCHAR | 枚举类型:
ENUM强制值合法性但扩展性差,VARCHAR更灵活 |
UUID | CHAR(36) / BINARY(16) | UUID存储:
CHAR(36)可读性好,BINARY(16)节省空间 |
List<String> | JSON | 存储JSON数组(MySQL 5.7+支持JSON类型) |
| 自定义对象 | JSON / BLOB | 序列化为JSON字符串或二进制 |
三、使用建议
1. 数值类型
- 整数:
- 小范围整数用
INT(如年龄),大范围用BIGINT(如主键ID)。 - 避免使用
VARCHAR存储数值,否则无法高效计算。
- 浮点数:
- 非精确计算(如科学数据)用
FLOAT或DOUBLE。 - 精确计算(如金额)必须用
DECIMAL,避免浮点精度丢失。
2. 字符串与文本
- 短文本:
- 使用
VARCHAR(n)并设置合理长度(如用户名VARCHAR(50))。 - 不要过度分配长度(如
VARCHAR(255)浪费空间)。
- 长文本:
- 超过255字符用
TEXT(如文章内容),注意TEXT字段可能导致临时表磁盘存储,影响性能。
3. 日期时间
- 日期时间选择:
- 无时区需求用
DATETIME(如用户注册时间)。 - 需要自动时区转换用
TIMESTAMP(如国际化系统)。
- 仅日期或时间:
- 使用
DATE或TIME类型,而非VARCHAR,便于日期函数计算。
4. 布尔值
- 推荐
TINYINT(1):
- 兼容性好,0表示
false,1表示true。 - 避免用
CHAR(1)存储'T'/'F',增加代码复杂度。
5. 二进制数据
- 小文件:
- 大文件:
- 建议存储文件路径(如OSS链接),而非直接存数据库。
6. 枚举与JSON
- 枚举字段:
- 低变更频率用
ENUM(如性别),高频变更用VARCHAR(如状态码)。
- JSON数据:
- 动态结构数据(如配置项)用
JSON类型,支持部分查询优化(MySQL 8.0+)。
四、常见问题与避坑指南
1. 数值溢出
- 问题:Java的
Long范围大于INT,若MySQL定义为INT,插入大数值会溢出。 - 解决:主键或大数值字段使用
BIGINT。
2. 时间精度丢失
- 问题:Java的
LocalDateTime支持纳秒,MySQL的DATETIME默认精度到秒。 - 解决:MySQL 5.6+可用
DATETIME(6)定义毫秒/微秒精度。
3. 字符编码乱码
- 问题:Java的UTF-8字符串存入MySQL的
latin1字段导致乱码。 - 解决:确保MySQL表字符集为
utf8mb4,连接字符串配置useUnicode=true&characterEncoding=UTF-8。
4. 布尔值映射错误
- 问题:
Boolean类型映射到TINYINT时,非0/1值可能被误判。 - 解决:代码中显式转换(如
resultSet.getBoolean("flag"))。
五、示例代码
public class User {
private Long id;
private String name;
private Integer age;
private BigDecimal balance;
private LocalDateTime createTime;
private boolean isActive;
}
PreparedStatement stmt = connection.prepareStatement(
"INSERT INTO user (name, age, balance, create_time, is_active) VALUES (?, ?, ?, ?, ?)"
);
stmt.setString(1, user.getName());
stmt.setInt(2, user.getAge());
stmt.setBigDecimal(3, user.getBalance());
stmt.setObject(4, user.getCreateTime());
stmt.setBoolean(5, user.isActive());
总结
- 核心原则:根据业务场景选择最贴合的MySQL类型,兼顾存储效率、查询性能和扩展性。
- 推荐实践:
- 主键用
BIGINT,金额用DECIMAL,时间用DATETIME或TIMESTAMP。 - 避免过度使用
VARCHAR,优先选择专用类型(如DATE、JSON)。
- 性能优化:
- 为频繁查询的字段(如时间、状态)添加索引。
- 大字段(如
TEXT、BLOB)与核心业务表分离。