问题前景
有时候在数据库中我们需要将数据以JSON的形式存储,例如:图片地址数组列表。在Java项目中可能是以这种形式来存储的:List< String > ,在数据库中是以JSON形式例如:[“http://地址1”,“http://地址2”,…]。现在需要在将Java实体对象存储到数据库中时能够将对应的List< String >数据自动转换为JSON数组,同时在查询出对象时能够将JSON数组自动转换为List< String >。
处理器实现
我们需要继承 BaseTypeHandler< T > 类,实现我们的转换逻辑
import com.alibaba.fastjson.JSON;
import lombok.SneakyThrows;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
@MappedTypes(value = { List.class })
@MappedJdbcTypes(value = JdbcType.VARCHAR)
public class JsonStringArrayTypeHandler extends BaseTypeHandler<List<String>> {
@Override
public void setNonNullParameter(PreparedStatement ps, int i, List<String> parameter, JdbcType jdbcType)
throws SQLException {
ps.setString(i, JSON.toJSONString(parameter));
}
@Override
@SneakyThrows
public List<String> getNullableResult(ResultSet rs, String columnName) {
String reString = rs.getString(columnName);
return JSON.parseArray(reString,String.class);
}
@Override
@SneakyThrows
public List<String> getNullableResult(ResultSet rs, int columnIndex) {
String reString = rs.getString(columnIndex);
return JSON.parseArray(reString,String.class);
}
@Override
@SneakyThrows
public List<String> getNullableResult(CallableStatement cs, int columnIndex) {
String reString = cs.getString(columnIndex);
return JSON.parseArray(reString,String.class);
}
}
Java实体类
在需要进行转换的字段的 @TableId注解中设置typeHandler属性,同时在类的 @TableName注解中设置 autoResultMap属性为True(不设置autoResultMap属性的话存入没问题,但是取出的时候该字段是null)
/**
* 测试实体
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Accessors(chain = true)
@TableName(value = "test",autoResultMap = true)
public class Test implements Serializable {
/**
* 数据库主键
*/
@TableId(value = "id", type = IdType.ASSIGN_ID)
@Schema(description="数据库主键")
private Long id;
/**
* 工作情况图片列表,json数组
*/
@TableField(value = "img_list",typeHandler = JsonStringArrayTypeHandler.class)
@Schema(description="工作情况图片列表,json数组")
@Size(max = 255,message = "工作情况图片列表,json数组最大长度要小于 255")
private List<String> imgList;
/**
* 创建时间
* */
@TableField(value = "create_time")
@Schema(description="创建时间")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date createTime;
}
扩展
其他类型的也是一样的方式,如果你的实体类中还嵌套其他实体的对象,并且需要在存入数据库时将其他实体的字段转换为JSON存储则只需要在新增一个处理器类继承BaseTypeHandler< T > 类并且将泛型 T 替换为具体的实体类即可。