java中preparedstatement不直接支持json类型,需以字符串方式存取,依赖数据库驱动、字段类型及序列化配合;mysql用json/text类型+setstring(),postgresql用jsonb/json+setstring(),均需格式校验与统一工具封装。

Java 中 PreparedStatement 本身不直接支持 JSON 类型,但可以通过字符串方式存取 JSON 字段,关键在于数据库驱动、字段类型和序列化/反序列化配合。不同数据库(如 MySQL 5.7+、PostgreSQL、Oracle)对 JSON 的支持程度不同,处理方式也略有差异。
MySQL:用 TEXT 或 JSON 类型 + 字符串传参
MySQL 5.7+ 支持原生 JSON 类型,但 JDBC 驱动(8.0+)仍要求以字符串形式传入。PreparedStatement 会自动校验格式(若字段为 JSON 类型且值非法,执行时抛出 SQLException)。
- 建表时定义为
json类型(推荐)或longtext - Java 端将对象转为标准 JSON 字符串(如用 Jackson 或 Gson),再通过
setString()设置参数 - 查询时用
getString()获取字符串,再反序列化为 Java 对象
// 插入
String sql = "INSERT INTO user (name, profile) VALUES (?, ?)";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, "Alice");
ps.setString(2, "{\"age\":30,\"city\":\"Beijing\"}"); // 直接传合法 JSON 字符串
ps.executeUpdate();
// 查询
String sql2 = "SELECT profile FROM user WHERE name = ?";
ps = conn.prepareStatement(sql2);
ps.setString(1, "Alice");
ResultSet rs = ps.executeQuery();
if (rs.next()) {
String jsonStr = rs.getString("profile");
UserProfile profile = objectMapper.readValue(jsonStr, UserProfile.class);
}
PostgreSQL:用 JSONB / JSON 类型 + setString 或 setObject
PostgreSQL 推荐使用 jsonb(更高效、可索引)。JDBC 驱动(42.2+)支持直接传字符串,部分版本还支持 setObject(?, jsonStr, Types.OTHER),但最稳妥仍是 setString()。
- 确保字段类型是
json或jsonb - 插入前保证 JSON 字符串格式正确(双引号、无尾逗号等)
- 查询结果仍为字符串,需手动解析
- 如需 JSON 函数操作(如
profile->>'age'),SQL 中写即可,Java 层无需特殊处理
通用建议:封装序列化逻辑,避免硬编码 JSON 字符串
不要在 SQL 拼接中手写 JSON,也不要在业务层反复调用 objectMapper.writeValueAsString()。建议统一抽象:
- 定义工具方法:
toJsonString(Object obj)和fromJson(String json, Class<t> cls)</t> - 实体类中用
@Column(columnDefinition = "json")(JPA 场景)或注解标记 JSON 字段 - 对空值/无效 JSON 做防御:插入前校验字符串是否为合法 JSON(可用 Jackson 的
readTree()尝试解析) - 注意字符集:确保数据库、连接 URL(如
useUnicode=true&characterEncoding=utf8)、JVM 编码一致,避免中文乱码
不推荐的做法
以下方式容易出错,应避免:
- 把 JSON 当普通字符串拼接到 SQL 里(SQL 注入风险)
- 用
setObject()直接传 Map/List 而不指定类型——多数驱动不识别,可能转成 toString() 结果(如{age=30},非合法 JSON) - 数据库用 VARCHAR 存 JSON 却不做长度限制,导致截断(建议至少 4000+ 字符)
- 读取后用正则或字符串截取解析 JSON——不可靠,应交由专业库处理
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











