You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java11+PostgreSQL+JDBC:枚举类型映射读写方法问询

PostgreSQL Enum 与 Java Enum 的 JDBC 映射实现(读写操作)

1. PostgreSQL 端准备:定义枚举类型与测试表

先在数据库中创建对应枚举类型和测试表,示例以用户状态枚举为例:

-- 创建枚举类型
CREATE TYPE user_status AS ENUM ('ACTIVE', 'INACTIVE', 'SUSPENDED');

-- 创建关联表
CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    username VARCHAR(50) NOT NULL,
    status user_status NOT NULL
);

2. Java 端定义对应 Enum 类

确保 Java Enum 的名称(name()返回值)与 PostgreSQL 枚举字面量完全一致(PG 枚举大小写敏感):

public enum UserStatus {
    ACTIVE,
    INACTIVE,
    SUSPENDED
}

3. 写入操作:Java Enum → PostgreSQL Enum

使用 JDBC PreparedStatement.setObject() 直接传入 Java Enum 实例,PG 驱动会自动完成映射转换:

// 假设已获取合法的 Connection 对象 conn
String insertSql = "INSERT INTO users (username, status) VALUES (?, ?)";
try (PreparedStatement pstmt = conn.prepareStatement(insertSql)) {
    pstmt.setString(1, "jane_smith");
    // 直接传入 Java Enum,驱动自动映射为 PG 枚举值
    pstmt.setObject(2, UserStatus.INACTIVE);
    pstmt.executeUpdate();
} catch (SQLException e) {
    e.printStackTrace();
}

4. 读取操作:PostgreSQL Enum → Java Enum

从 ResultSet 中获取数据时,使用 getObject() 并指定 Java Enum 的 Class 类型,驱动会自动转换:

String selectSql = "SELECT id, username, status FROM users WHERE id = ?";
try (PreparedStatement pstmt = conn.prepareStatement(selectSql)) {
    pstmt.setInt(1, 1);
    try (ResultSet rs = pstmt.executeQuery()) {
        if (rs.next()) {
            int id = rs.getInt("id");
            String username = rs.getString("username");
            // 直接转换为目标 Java Enum
            UserStatus status = rs.getObject("status", UserStatus.class);
            System.out.printf("ID: %d, Username: %s, Status: %s%n", id, username, status);
        }
    }
} catch (SQLException e) {
    e.printStackTrace();
}

关键注意事项

  • 驱动版本要求:必须使用 PostgreSQL JDBC 驱动 42.0.0 及以上版本(Java 11 推荐 42.x 系列),旧版本不支持直接的 Enum 映射。
  • 大小写严格匹配:PG 枚举值区分大小写,Java Enum 的名称必须与 PG 枚举字面量完全一致(比如 PG 定义为'active',Java Enum 就不能写ACTIVE)。
  • 自定义映射(可选):如果需要 Java Enum 与 PG 枚举值不一致的映射,可以实现 SQLData 接口自定义转换逻辑:
public enum CustomUserStatus implements SQLData {
    ACTIVE("ACTIVE_PG"),
    INACTIVE("INACTIVE_PG"),
    SUSPENDED("SUSPENDED_PG");

    private final String pgEnumValue;
    private static final String TYPE_NAME = "user_status";

    CustomUserStatus(String pgEnumValue) {
        this.pgEnumValue = pgEnumValue;
    }

    @Override
    public String getSQLTypeName() throws SQLException {
        return TYPE_NAME;
    }

    @Override
    public void readSQL(SQLInput stream, String typeName) throws SQLException {
        String value = stream.readString();
        for (CustomUserStatus status : values()) {
            if (status.pgEnumValue.equals(value)) {
                return;
            }
        }
        throw new SQLException("Unknown enum value: " + value);
    }

    @Override
    public void writeSQL(SQLOutput stream) throws SQLException {
        stream.writeString(pgEnumValue);
    }

    // 静态方法用于PG值转Java Enum
    public static CustomUserStatus fromPgValue(String pgValue) {
        for (CustomUserStatus status : values()) {
            if (status.pgEnumValue.equals(pgValue)) {
                return status;
            }
        }
        throw new IllegalArgumentException("Unknown PG enum value: " + pgValue);
    }
}

使用自定义 Enum 时的读写调整:

// 写入
pstmt.setObject(2, CustomUserStatus.ACTIVE);

// 读取
String pgStatus = rs.getString("status");
CustomUserStatus status = CustomUserStatus.fromPgValue(pgStatus);

内容的提问来源于stack exchange,提问作者Atul

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 06:03:31