在后端处理数据时难免会遇到类型为
List
的字段,为了方便(优雅)地处理这个列表类型字段的存储与读取,我们可以自定义Mybatis-Plus提供的BaseTypeHandler类,从而对任意类型的列表数据进行数据库相关处理
List
表示任意对象的列表类型,即以下自定义配置可以处理任意类型对象的列表类型,例如:List
、List
等等(其中User为自定义的对象)
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import lombok.extern.slf4j.Slf4j;
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 org.springframework.util.StringUtils;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
@Slf4j
@MappedJdbcTypes(JdbcType.VARCHAR) //数据库类型
@MappedTypes({List.class}) //java数据类型
public abstract class ListTypeHandler<T> extends BaseTypeHandler<List<T>> {
@Override
public void setNonNullParameter(PreparedStatement ps, int i, List<T> parameter, JdbcType jdbcType) throws SQLException {
String content = StringUtils.isEmpty(parameter) ? null : JSON.toJSONString(parameter);
ps.setString(i, content);
}
@Override
public List<T> getNullableResult(ResultSet rs, String columnName) throws SQLException {
return this.getListByJsonArrayString(rs.getString(columnName));
}
@Override
public List<T> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
return this.getListByJsonArrayString(rs.getString(columnIndex));
}
@Override
public List<T> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
return this.getListByJsonArrayString(cs.getString(columnIndex));
}
private List<T> getListByJsonArrayString(String content) {
return StringUtils.isEmpty(content) ? new ArrayList<>() : JSON.parseObject(content, this.specificType());
}
/**
* 具体类型,由子类提供
* @return 具体类型
*/
protected abstract TypeReference<List<T>> specificType();
}
这边以String类型为例
import com.alibaba.fastjson.TypeReference;
import java.util.List;
public class StringTypeHandler extends ListTypeHandler<String> {
// 将ListTypeHandler(T为任意对象),具体为特定的对象String
@Override
protected TypeReference<List<String>> specificType() {
return new TypeReference<List<String>>() {
};
}
}
以List
为例,添加@TableField
注解,表示该字段需要进行对应的转化
@ApiModelProperty("售后人员")
@TableField(typeHandler = StringTypeHandler.class)
private List<String> afterSaleList;
通过以上操作后,可以实现
List
列表类型的添加和修改
在实体类表头添加注解@TableName
,一定要配置属性autoResultMap = true
@TableName(value = "base_knowledge", autoResultMap = true)
添加以上配置后,即可完成对List
列表类型字段的读取
当使用mybatis-plus的select方法时,是直接使用其提供的autoResultMap
生成的resultMap
。但是当我们使用mybatis的@select
注解自定义查询语句时,只会生产普通resultMap
,注解@TableField(typeHandler = StringTypeHandler.class)
并不会生效,对应的字段查询出来为null,所以为了支持mybatis的@select
注解,我们还需要手动添加注解@ResultMap
,具体写法如下:
import static com.baomidou.mybatisplus.core.toolkit.Constants.MYBATIS_PLUS;
import static com.baomidou.mybatisplus.core.toolkit.StringPool.UNDERSCORE;
@ResultMap(MYBATIS_PLUS + UNDERSCORE + "Person")
// 或者
@ResultMap("com.example.mappers.PersonMapper" + "." + MYBATIS_PLUS + UNDERSCORE + "Person")
//@Select自定义查询写法如下
@Select("select * from base_knowledge where deleted=1 limit #{pageNum}, #{pageSize}")
// 添加@ResultMap注解
@ResultMap(MYBATIS_PLUS + UNDERSCORE + "Knowledge")
public List<Knowledge> selectDeletedKnowledgePage(int pageNum, int pageSize);