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
相关产品推荐
相关产品推荐

