在 PostgreSQL 中使用 JSONB 类型并结合 MyBatis-Plus 实现自动注入,主要有以下几种方案
【代码】在 PostgreSQL 中使用 JSONB 类型并结合 MyBatis-Plus 实现自动注入,主要有以下几种方案。
·
在 PostgreSQL 中使用 JSONB 类型并结合 MyBatis-Plus 实现自动注入,主要有以下几种方案:
方案一
User对象
@Data
@TableName(value = "t_user", autoResultMap = true)
public class User {
@TableId(type = IdType.AUTO)
private Long id;
//jsonb
@TableField(value = "dept", typeHandler = JsonbTypeHandler.class)
private Dept dept;
}
JsonbTypeHandler
import java.sql.PreparedStatement;
import java.sql.SQLException;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedTypes;
import org.postgresql.util.PGobject;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
@MappedTypes({Object.class})
public class JsonbTypeHandler extends JacksonTypeHandler {
public JsonbTypeHandler(Class<?> type) {
super(type);
getObjectMapper().registerModule(new JavaTimeModule());
getObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
}
@Override
public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException {
if (ps != null) {
PGobject jsonObject = new PGobject();
jsonObject.setType("jsonb");
jsonObject.setValue(toJson(parameter));
ps.setObject(i, jsonObject);
}
}
}
自定义SQL查询
public interface UserMapper extends BaseMapper<User> {
@Select("""
SELECT * FROM t_user WHERE id = #{id}
""")
@Results({
@Result(column = "dept", property = "dept",
typeHandler = JsonbTypeHandler.class)
})
EmcDidCamera getById(String id);
}
其他方案
1. 创建 JSONB TypeHandler
@MappedTypes({Map.class, List.class, Object.class})
@MappedJdbcTypes(JdbcType.OTHER)
public class JsonbTypeHandler extends BaseTypeHandler<Object> {
private static final ObjectMapper objectMapper = new ObjectMapper();
@Override
public void setNonNullParameter(PreparedStatement ps, int i,
Object parameter, JdbcType jdbcType)
throws SQLException {
try {
String json = objectMapper.writeValueAsString(parameter);
ps.setObject(i, json, Types.OTHER);
} catch (JsonProcessingException e) {
throw new SQLException("JSON转换失败", e);
}
}
@Override
public Object getNullableResult(ResultSet rs, String columnName)
throws SQLException {
String json = rs.getString(columnName);
return parseJson(json);
}
@Override
public Object getNullableResult(ResultSet rs, int columnIndex)
throws SQLException {
String json = rs.getString(columnIndex);
return parseJson(json);
}
@Override
public Object getNullableResult(CallableStatement cs, int columnIndex)
throws SQLException {
String json = cs.getString(columnIndex);
return parseJson(json);
}
private Object parseJson(String json) throws SQLException {
if (StringUtils.isBlank(json)) {
return null;
}
try {
return objectMapper.readValue(json, Object.class);
} catch (Exception e) {
throw new SQLException("JSON解析失败: " + json, e);
}
}
}
2. 实体类配置
@Data
@TableName(value = "your_table", autoResultMap = true)
public class YourEntity {
@TableId(type = IdType.AUTO)
private Long id;
private String name;
// 方式1:使用泛型
@TableField(typeHandler = JsonbTypeHandler.class)
private Map<String, Object> attributes;
// 方式2:指定具体类型
@TableField(typeHandler = JsonbTypeHandler.class)
private List<String> tags;
// 方式3:自定义对象
@TableField(typeHandler = JsonbTypeHandler.class)
private Config config;
@TableField(typeHandler = JsonbTypeHandler.class)
private List<Config> configs;
public void setConfigs(List configs) {
if(CollUtil.isEmpty(configs)){
return;
}
Object first = configs.getFirst();
if(first instanceof Map){
this.configs= JSONUtil.toList(JSONUtil.toJsonStr(configs), Config.class);
}
}
}
更多推荐
所有评论(0)