jdbc类型映射核心是驱动在resultset和preparedstatement两端按规则双向转换:写入用setxxx()、读取用getxxx(),须严格匹配数据库字段的null约束、数值范围、精度及语义,禁用getstring()兜底,时间优先用getobject(..., localdatetime.class)。

Java JDBC 处理数据库类型与 Java 类型的映射,核心是靠 JDBC 驱动在 ResultSet 和 PreparedStatement 两端完成双向转换:写入时把 Java 值转成数据库可识别的二进制/文本格式,读取时再按字段元信息还原为合适的 Java 对象。这个过程不是自动“猜”,而是有明确规则和常见陷阱。
用对 getXXX() 和 setXXX() 方法是基本前提
JDBC 提供了类型专用的访问方法,比如 getString()、getInt()、getBigDecimal()、setLong()、setBoolean() 等。这些方法不是“兜底万能”的,它们隐含了类型契约:
- 调用
getInt("age")时,JDBC 驱动会尝试把数据库该列的实际值(比如 MySQL 的TINYINT、SMALLINT或INT)转成int;如果底层是VARCHAR存数字字符串,就会抛异常,而不是静默转 - 不要依赖
getString()读所有字段来“绕开类型问题”——它可能返回"1970-01-01"这样的字符串,但丢失了时区、精度、null 语义等关键信息 - 对时间字段,优先用
getObject("created_at", LocalDateTime.class)(JDBC 4.2+),而非getTimestamp()+ 手动转,避免java.util.Date的线程不安全和时区混乱
数据库字段是否允许 NULL 决定 Java 用基本类型还是包装类
这是最容易出逻辑错误的一环。数据库字段定义里的 NULL 约束,直接约束 Java 端变量能否为 null:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
-
NOT NULL字段(如user_id INT NOT NULL)→ Java 可用long、int、boolean - 允许
NULL的字段(如middle_name VARCHAR(50)、score DECIMAL(5,2))→ Java 必须用String、BigDecimal、Integer、Boolean等包装类 - 用
int接收可能为NULL的数据库字段,JDBC 会默认返回0;用boolean接收,会变成false——这不是空值,是错误默认值
数值范围与精度必须严格对齐,不能只看“名字像”
字节长度相同 ≠ 安全映射。MySQL 的 TINYINT(1) 默认被 JDBC 当作布尔处理,SMALLINT 常被映射为 Integer 而非 Short,都是因为驱动做了防溢出设计:
-
TINYINT→ 想用Byte?得在连接 URL 加?tinyInt1isBit=false,否则查0/1以外的值(如127)会报ClassCastException -
BIGINT↔long是安全的,两者都是 64 位有符号整数,Spring Data JPA、MyBatis 默认支持 -
DECIMAL、NUMERIC→ 必须用BigDecimal,不用double或float。后者无法表示精确小数(0.1 + 0.2 != 0.3),且不能为null - 写入大整数字面量时注意后缀:
setLong(1, 10000000000L),不是10000000000(那是int,超范围编译失败)
时间、布尔、LOB 字段有特殊语义,不能硬套基础类型
这些类型在不同数据库中语义差异大,JDBC 映射也更依赖驱动行为:
- MySQL 的
BIT(1)或TINYINT(1)常被业务当布尔用,但 JDBC 默认映射为Boolean;若实际存的是0~255整数,就必须禁用tinyInt1isBit - 时间字段推荐统一用
java.time类:LocalDateTime(无时区)、ZonedDateTime(带时区)、OffsetDateTime(带偏移)。避免java.sql.Timestamp和java.util.Date的构造陷阱与时区转换错乱 -
BLOB/CLOB不要强转成byte[]或String;应通过getBinaryStream()或getCharacterStream()流式读取,防止内存溢出
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










