杰瑞科技汇

Java中如何对应数据库的bigint类型?

Java中的 long 类型直接对应数据库中的 BIGINT 类型

Java中如何对应数据库的bigint类型?-图1
(图片来源网络,侵删)

下面我将从多个维度详细解释这个映射关系,包括核心对应、JDBC规范、ORM框架(如MyBatis、JPA)中的处理,以及一些最佳实践。


核心对应关系

数据库类型 Java 类型 说明
BIGINT long 标准对应BIGINT 是一个64位有符号整数,范围是 -2^632^63-1,Java的 long 同样是一个64位有符号整数,两者在数值范围上完全匹配。
BIGINT java.lang.Long 包装类型对应,在Java中,基本类型 long 的包装类型是 LongLong 是一个对象,可以为 null,这在处理数据库中可能为 NULL 的值时非常有用。

为什么有两种选择?

  • long (基本类型): 当你确定数据库中的列永远不会为 NULL 时,使用 long 可以避免空指针异常,代码也更简洁。
  • Long (包装类型): 当数据库中的列可能为 NULL 时,必须使用 Long,因为 long 基本类型不能为 null,如果尝试将数据库的 NULL 值赋给一个 long 类型的变量,JDBC驱动会抛出 NullPointerException

JDBC 规范中的映射

JDBC (Java Database Connectivity) 是Java连接数据库的标准API,在 java.sqljava.math 包中定义了与数据库数据类型对应的Java类。

对于 BIGINT,JDBC规范明确指出它应该被映射为 java.lang.Long 类型。

Java中如何对应数据库的bigint类型?-图2
(图片来源网络,侵删)
  • 获取数据: 当你通过 ResultSet 对象获取一个 BIGINT 类型的列时,应该使用 getLong() 方法。

    // 假设 rs 是一个 ResultSet 对象
    long id = rs.getLong("id"); // 如果id列是BIGINT且不为NULL
    // 为了安全地处理可能为NULL的情况
    Long nullableId = rs.getLong("id");
    if (rs.wasNull()) {
        // 说明id列在数据库中是NULL值
        nullableId = null;
    }
  • 设置数据: 当你通过 PreparedStatement 对象向数据库设置一个 BIGINT 类型的参数时,也应该使用 setLong() 方法。

    // 假设 ps 是一个 PreparedStatement 对象
    long newId = 12345L;
    ps.setLong(1, newId); // 设置第一个参数为BIGINT类型

注意: 虽然JDBC规范和API使用 Long 类型,但在实际的业务逻辑层,你通常会选择 longLong,这取决于你的业务需求(是否允许为空)。


ORM 框架中的映射

现代开发中,我们很少直接使用JDBC API,而是使用ORM(Object-Relational Mapping)框架,如MyBatis、JPA/Hibernate等,这些框架简化了数据类型的映射。

Java中如何对应数据库的bigint类型?-图3
(图片来源网络,侵删)

MyBatis

在MyBatis中,映射通常在XML文件或注解中完成,MyBatis会自动处理 BIGINT 和Java类型之间的转换。

  • XML映射示例:

    <select id="selectUserById" resultType="com.example.User">
        SELECT id, name, create_time
        FROM users
        WHERE id = #{id}
    </select>

    MyBatis会根据 resultType 指定的Java类(如 User)的属性类型,自动将数据库的 BIGINT 类型转换为 longLongUser 类的 id 属性是 long 类型,MyBatis会期望一个非 NULL 的值。

  • 注解示例:

    @Select("SELECT id FROM users WHERE name = #{name}")
    long selectIdByName(@Param("name") String name);

JPA / Hibernate

在JPA(Java Persistence API)规范中,通过在实体类的属性上使用注解来定义映射关系。

  • 使用 @Column 注解:

    import javax.persistence.*;
    @Entity
    public class User {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "id") // 对应数据库的 id 列
        private Long id; // 通常使用包装类型以允许为NULL,即使主键一般不为NULL,这也是一种常见实践
        // ... 其他属性和方法
    }
    • private Long id;: 这是最常见的写法,即使 BIGINT 列在数据库中是 NOT NULL 的,使用 Long 也是一种安全的做法,因为它可以处理数据库模式变更或未来可能出现的 NULL 值。
    • private long id;: 如果你100%确定这个列永远不会为 NULL,并且你想强制非空,可以使用 long,但JPA规范推荐使用包装类型。
  • JPA类型映射: JPA规范定义了标准的类型映射。java.lang.Long 被明确映射到数据库的 BIGINT 类型。


最佳实践和注意事项

  1. 优先使用包装类型 Long:

    • 可空性: 数据库模式可能会变化。NOT NULL 的列,明天可能就变成了 NULLABLE,使用 Long 可以让你的代码更具弹性,避免因数据库模式变更而导致的代码修改。
    • 一致性: 在Java集合(如 List<Long>)和Map中,只能使用对象类型,不能使用基本类型,统一使用包装类型可以保持代码风格的一致性。
  2. 注意数值范围:

    • BIGINT 的范围是 -9,223,372,036,854,775,8089,223,372,036,854,775,807
    • long 的范围也是这个,如果你的业务逻辑可能超过这个范围(雪花算法生成的ID在某些极端情况下可能接近这个上限),你需要考虑使用 VARCHARDECIMAL 类型来存储,但这属于特殊情况。
  3. 与前端交互:

    • 在与前端(JavaScript)交互时,JavaScript的 Number 类型是双精度浮点数,可以精确表示 BIGINT 范围内的所有整数,当数字超过 Number.MAX_SAFE_INTEGER (即 2^53 - 19,007,199,254,740,991) 时,会丢失精度。
    • 如果你的 BIGINT 值可能超过这个安全范围(雪花ID),在与前端交互时,强烈建议将 BIGINT 作为字符串(String)类型传输,以避免精度丢失。
场景 推荐的Java类型 原因
JDBC ResultSet.getLong() longLong API直接提供,需手动处理 NULL (wasNull())。
JDBC PreparedStatement.setLong() long 设置参数,通常为非空值。
MyBatis 结果映射 longLong 根据JavaBean的属性类型自动转换。
JPA/Hibernate 实体属性 Long 推荐,安全、灵活,符合JPA规范,便于处理潜在 NULL 值。
业务逻辑层 Long 推荐,与数据库层和集合类型保持一致,提高代码健壮性。
前端交互 (大数值) String 避免 JavaScript Number 类型的精度丢失问题。

BIGINT 在Java世界中最直接、最标准的对应就是 long,但在实际的企业级应用开发中,出于对空值和代码健壮性的考虑,Long 是更常用和更安全的选择。

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