SQL建表语句:
CREATE TABLE ts_data (
device_sn varchar(300) NOT NULL,
ts TIMESTAMPTZ NOT NULL,
da JSONB NOT NULL,
CONSTRAINT ts_data_pkey PRIMARY KEY (device_sn, ts, da)
);
数据库表Entity,这里字段da定义为String:
java
@Data
@TableName("ts_data")
public class TsData {
private String deviceSn;
@TableField(value = "da", typeHandler = JsonbTypeHandler.class)
private String da;
@TableField("ts") // 映射数据库中的TIMESTAMPTZ列
private OffsetDateTime ts;
}
mybatis的自定义json处理器:
java
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedTypes;
import org.postgresql.util.PGobject;
import java.lang.reflect.Field;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
@Slf4j
@MappedTypes({Object.class})
public class JsonbTypeHandler extends JacksonTypeHandler {
public JsonbTypeHandler(Class<?> type) {
super(type);
}
// 自3.5.6版本开始支持泛型.
public JsonbTypeHandler(Class<?> type, Field field) {
super(type, field);
}
@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);
}
}
@Override
public Object getNullableResult(ResultSet rs, String columnName) throws SQLException {
String json = rs.getString(columnName);
if (json == null || json.trim().isEmpty()) {
return null;
}
try {
// 调用父类的反序列化方法
return super.getNullableResult(rs, columnName);
} catch (Exception e) {
log.warn("反序列化JSON字段 {} 失败,原始内容: {}", columnName, json, e);
// 可选:返回原始字符串而非抛出异常
return json;
}
}
}
mybatis的xml文件中配置部分,需要指定自定义处理器:
XML
<resultMap id="ResultTsMap" type="com.demo.entity.TsData">
<result column="sn" property="sn" />
<result column="ts" property="ts" />
<result column="da" property="da" javaType="java.lang.String" typeHandler="com.demo.config.handler.JsonbTypeHandler" />
</resultMap>
Mapper类中的新增方法,需要指定为jsonb:
java
@Mapper
public interface TsDataMapper extends BaseMapper<TsData> {
@Insert("insert into ts_data(device_sn,da,ts)values(#{sn},#{da}::jsonb,#{ts})")
int insert(String sn, String da, OffsetDateTime ts);
}
如上所示,在新增数据时,就可以将String格式的json字段插入到表中列格式为jsonb的字段。
查询时,将从数据库中查询到的字符串显示转换成json即可。