jdbc时间类型映射核心是:优先用java 8的java.time类(如localdatetime)配合jdbc 4.2+的getobject()获取,避免旧式java.util.date及java.sql子类的缺陷;数据库字段是否允许null决定java用基本类型或包装类,数值范围与精度须严格匹配,getter方法应选类型安全的专用方法而非getstring()兜底。

核心原则是:数据库字段类型决定Java端选基本类型还是包装类,而取值范围和null容忍度决定具体用哪个类型。映射错一个,轻则数据失真,重则运行时异常。
按数据库字段是否允许NULL选Java类型
数据库字段定义为 NOT NULL 时,Java端可用基本类型(int、long、boolean);若允许 NULL,必须用对应包装类(Integer、Long、Boolean)。因为基本类型无法表示 null——int 读到数据库 null 会变成 0,boolean 变成 false,造成逻辑错误。
- 比如用户年龄字段允许为空,Java 用 int 接收,查出 null 就变成 0,系统可能误判为“刚出生”
- 订单金额字段为 DECIMAL,即使业务上不为零,只要数据库允许 NULL,就该用 BigDecimal 而非 double ——后者不仅不能表 null,还会因浮点精度丢失金额(如 19.99 存成 19.990000000000002)
按数值范围和精度匹配数据库类型
别只看“都是整数”就随便配。tinyint(1字节) 映射 byte 最省空间;smallint(2字节) 对应 short;int(4字节) 对应 int;bigint(8字节) 必须用 long。float 和 double 同理,但要注意:float 在 Java 中只有约 6~7 位有效数字,存货币或科学计数易丢精度,优先选 double 或 BigDecimal。
- 传感器采样值范围在 -128~127,用 byte 比用 int 节省内存,尤其在百万级记录的 List
中差异明显 - 主键 ID 是 bigint,Java 端若误用 int,超出 21 亿就会溢出回绕(如 2147483647 + 1 = -2147483648),导致 ID 冲突或查询错乱
字符与布尔类型的常见坑点
char 类型在 Java 中是单个 Unicode 字符(2 字节),对应数据库 char(1) 或 varchar(1);但千万别把 varchar(50) 映射成 char——它只能存一个字符。boolean 更需谨慎:数据库没有原生 boolean 类型,常见用 tinyint(0/1)、bit 或 boolean 字段模拟。Java 端统一用 Boolean 包装类接收,再通过 ResultSet.getBoolean() 或 getObject("flag", Boolean.class) 获取,避免手动解析 0/1 的歧义。
- MySQL 的 TINYINT(1) 常被当 boolean 用,但 ResultSet.getBoolean() 能正确识别 0→false、1→true;而 getString() 返回 "0" 或 "1",需额外转换
- PostgreSQL 的 BOOLEAN 字段,直接用 getBoolean() 安全;但若用 getString() 再 equals("true"),遇到大小写或空格就失败
映射操作中的关键方法选择
别依赖 getString() 万能兜底。JDBC 提供了类型安全的 getter 方法,应优先使用:getInt()、getLong()、getBigDecimal()、getDate()、getBytes()。它们在类型不匹配时抛 SQLException,比静默转错更早暴露问题。对于可能为 null 的字段,用 getObject(列名, 类.class) 方式(如 getObject("price", BigDecimal.class)),它既保持 null 语义,又避免空指针。
- DECIMAL 字段用 getBigDecimal() → 返回 null 或精确值;用 getDouble() → null 变 0.0,且精度丢失
- BLOB 字段必须用 getBytes() 或 getBinaryStream(),绝不用 getString()——二进制数据转字符串会乱码或截断
- DATE/TIME/TIMESTAMP 统一用 getObject(列名, LocalDateTime.class),比 java.sql.Date 兼容性更好,也避免时区陷阱
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











