前言
实现基于postgresql,springboot,spring mvc和mybatis-plus,原理是将List<T>转为JSONArray类型,数据库对应字段为json类型,即可完成存储。
实现
建表如下:
create table test.image_info (
id serial PRIMARY key NOT null,
image_address text NOT NULL,
image_owner text NOT NULL,
download_times int8 default 10,
authorized_user json,
is_deleted int8 NOT null
);
创建List处理器,ArrayTypeHandler.java:
package org.sample.handler;
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.*;
import java.util.Arrays;
import java.util.List;
/**
*
*/
@MappedJdbcTypes(JdbcType.ARRAY)
@MappedTypes(Object.class)
public class ArrayTypeHandler extends BaseTypeHandler<Object> {
private static final String TYPE_NAME_VARCHAR = "varchar";
private static final String TYPE_NAME_INTEGER = "integer";
private static final String TYPE_NAME_BOOLEAN = "boolean";
private static final String TYPE_NAME_NUMERIC = "numeric";
private static final String TYPE_NAME_LONG = "bigint";
@Override
public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException {
Object[] arrayObject;
if (parameter instanceof List) {
arrayObject = ((List) parameter).toArray();
} else {
arrayObject = (Object[]) parameter;
}
Connection conn = ps.getConnection();
if (arrayObject.length > 0) {
String typeName = TYPE_NAME_VARCHAR;
if (arrayObject[0] instanceof Integer) {
typeName = TYPE_NAME_INTEGER;
} else if (arrayObject[0] instanceof String) {
typeName = TYPE_NAME_VARCHAR;
} else if (arrayObject[0] instanceof Boolean) {
typeName = TYPE_NAME_BOOLEAN;
} else if (arrayObject[0] instanceof Double) {
typeName = TYPE_NAME_NUMERIC;
} else if (arrayObject[0] instanceof Long) {
typeName = TYPE_NAME_LONG;
}
Array array = conn.createArrayOf(typeName, arrayObject);
ps.setArray(i, array);
} else {
ps.setArray(i, null);
}
}
@Override
public List<Object> getNullableResult(ResultSet resultSet, String s) throws SQLException {
return getArray(resultSet.getArray(s));
}
@Override
public List<Object> getNullableResult(ResultSet resultSet, int i) throws SQLException {
return getArray(resultSet.getArray(i));
}
@Override
public List<Object> getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
return getArray(callableStatement.getArray(i));
}
private List<Object> getArray(Array array) {
if (array == null) {
return null;
}
try {
return Arrays.asList((Object[]) array.getArray());
} catch (Exception e) {
}
return null;
}
}
有entity如下:
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = false)
@TableName(value = "test.image_info ")
public class ImageInfo implements Serializable {
/**
* ID
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
@TableField(value = "image_address")
private String imageAddress;
@TableField(value = "image_owner")
private String imageOwner;
@TableField(value = "download_times")
private int downloadTimes;
@TableField(value = "authorized_user", typeHandler = ArrayTypeHandler.class)
private JSON authorizedUser;
@TableField(value = "is_deleted")
private int isDeleted;
}
核心实现过程:
// 创建entity
List<String> finalAuthorizedUsers = authorizedUsers;
ImageInfo imageInfo = new ImageInfo();
imageInfo.setId(0L);
imageInfo.setImageOwner(username);
imageInfo.setAllowDownloadTimes(imageDownloadTimes);
imageInfo.setAuthorizedUser(finalAuthorizedUsers);
imageInfo.setIsDeleted(IsDeletedEnum.NO.getCode());
imageInfo.setCreateTime(new Timestamp(System.currentTimeMillis()));
imageInfo.setCreateUser(username);
imageInfo.setUpdateUser(username);
// 插入数据库
int insert = imageInfoServiceMapper.insert(imageInfo);