mybatis建立插入postgresql的json类型数据
一、前言
最近在开发需求时,需要将json类型的表字段插入数据库,而针对postgresql数据库,如果直接插入json字符串会报错,那么针对这种情况,在不使用xml语句使用函数CAST强转情况下,想要实现插入json类型的数据,那么就可以在java 字段上加入自定义json处理器,就可以实现了。
二、如何实现?
1.在定义的entity对象中,针对json类型字段添加注解实现自定义json处理器,例如:
@Data
public class SyncLog implements Serializable {
@TableId(type= IdType.INPUT)
private Long id;
@TableField(value = "content",typeHandler = JsonTypeHandler.class)
private Object content;
/**
* 创建时间
*/
private Date createTime;
private static final long serialVersionUID = 1L;
}
其中content在数据库中是json类型。
2.JsonTypeHandler类实现如下:
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.postgresql.util.PGobject;
import java.sql.*;
public class JsonTypeHandler extends BaseTypeHandler {
private static final ObjectMapper objectMapper = new ObjectMapper();
@Override
public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException {
String jsonString;
try {
if(parameter instanceof String){
jsonString = (String) parameter;
}else {
jsonString = objectMapper.writeValueAsString(parameter);
}
} catch (JsonProcessingException e) {
throw new SQLException("JsonTypeHandler JSON serialization error", e);
}
// 获取数据库类型
Connection connection = ps.getConnection();
DatabaseMetaData metaData = connection.getMetaData();
String databaseProductName = metaData.getDatabaseProductName().toLowerCase();
if (databaseProductName.contains("postgresql")) {
PGobject pgObject = new PGobject();
pgObject.setType("json"); // 或者 "jsonb" 根据需求
pgObject.setValue(jsonString);
ps.setObject(i, pgObject);
} else {
//其他数据库处理逻辑
ps.setString(i, jsonString);
}
}
@Override
public Object getNullableResult(ResultSet rs, String columnName) throws SQLException {
return parseJson(rs.getString(columnName));
}
@Override
public Object getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
return parseJson(rs.getString(columnIndex));
}
@Override
public Object getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
return parseJson(cs.getString(columnIndex));
}
private Object parseJson(String json) throws SQLException {
if (json == null) {
return null;
}
try {
return objectMapper.readTree(json);
} catch (Exception e) {
throw new SQLException("JsonTypeHandler JSON deserialization error", e);
}
}
}
3.接下来定义一个DAO。
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface SyncLogDao extends BaseMapper {
}
4.然后插入一条数据,如果可以插入这条json数据,表明自定义的JsonTypeHandler已生效。
@RunWith(SpringRunner.class)
@SpringBootTest(classes= AIAssetExternalApplication.class)
public class IntegrationTest {
@Autowired
SyncLogDao syncLogDao;
@Test
public void sync() throws Exception {
SyncLog syncLog = new SyncLog();
syncLog.setId(1L);
String jsonStr="{\"size\": 3474046}";
syncLog.setContent(jsonStr);
syncLogDao.insert(syncLog);
}
}
结果插入成功,自定义的JsonTypeHandler生效。
浙公网安备 33010602011771号