直接先看代码:
package com.dm.td.model.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.dm.td.core.entity.BaseEntity;
import com.dm.td.handler.TripDaysHandler;
import com.dm.td.model.param.TripParam;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import java.util.List;
/**
* <p>
* 行程的每一天
* </p>
*
* @author 王进
* @since 2019-12-01
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@ApiModel(value = "TripDays对象", description = "行程的每一天")
@TableName(value = "trip_days", resultMap = "BaseResultMap")
public class TripDays extends BaseEntity {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "行程编号")
private Integer tripId;
@ApiModelProperty(value = "城市信息(北京>东京)")
private String citys;
@ApiModelProperty(value = "排序")
private Integer lvl;
@TableField(value = "citys_json", typeHandler = TripDaysHandler.class)
private List<TripParam.ChildCity> citysJson;
}
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package com.dm.td.handler;
import com.dm.td.core.util.JSONUtils;
import com.dm.td.model.param.TripParam;
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;
@MappedJdbcTypes({JdbcType.VARCHAR})
@MappedTypes({List.class})
public class TripDaysHandler extends BaseTypeHandler<List<TripParam.ChildCity>> {
private Class<TripParam.ChildCity> clazz;
public TripDaysHandler() {
clazz = TripParam.ChildCity.class;
}
@Override
public void setNonNullParameter(PreparedStatement ps, int i, List<TripParam.ChildCity> parameter, JdbcType jdbcType) throws SQLException {
ps.setString(i, JSONUtils.toJSONString(parameter));
}
@Override
public List<TripParam.ChildCity> getNullableResult(ResultSet rs, String columnName) throws SQLException {
return JSONUtils.parseListObject(rs.getString(columnName), this.clazz);
}
@Override
public List<TripParam.ChildCity> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
return JSONUtils.parseListObject(rs.getString(columnIndex), this.clazz);
}
@Override
public List<TripParam.ChildCity> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
return JSONUtils.parseListObject(cs.getString(columnIndex), this.clazz);
}
}
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package com.dm.td.handler;
import com.dm.td.core.util.JSONUtils;
import com.dm.td.model.param.TripParam;
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;
@MappedJdbcTypes({JdbcType.VARCHAR})
@MappedTypes({List.class})
public class TripDaysHandler extends BaseTypeHandler<List<TripParam.ChildCity>> {
private Class<TripParam.ChildCity> clazz;
public TripDaysHandler() {
clazz = TripParam.ChildCity.class;
}
@Override
public void setNonNullParameter(PreparedStatement ps, int i, List<TripParam.ChildCity> parameter, JdbcType jdbcType) throws SQLException {
ps.setString(i, JSONUtils.toJSONString(parameter));
}
@Override
public List<TripParam.ChildCity> getNullableResult(ResultSet rs, String columnName) throws SQLException {
return JSONUtils.parseListObject(rs.getString(columnName), this.clazz);
}
@Override
public List<TripParam.ChildCity> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
return JSONUtils.parseListObject(rs.getString(columnIndex), this.clazz);
}
@Override
public List<TripParam.ChildCity> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
return JSONUtils.parseListObject(cs.getString(columnIndex), this.clazz);
}
}
<resultMap id="BaseResultMap" type="com.dm.td.model.entity.TripDays">
<result column="id" property="id"/>
<result column="gmt_create" property="gmtCreate"/>
<result column="gmt_modified" property="gmtModified"/>
<result column="trip_id" property="tripId"/>
<result column="citys" property="citys"/>
<result column="lvl" property="lvl"/>
<result column="citys_json" property="citysJson" typeHandler="com.dm.td.handler.TripDaysHandler"/>
</resultMap>
为什么要自己写一个TripDaysHandler呢. 其实用统一的JsonTypeHandler也可以解决问题. 但是在序列化的时候. List<对象> 会被看作LinkedHashMap. 在使用的不小心就会ClassCaseException... 还得使用ObjectMapper.convert转换下. 就很麻烦. 所以还不如直接写个TripDaysHandler来处理. 这样在添加时,查询时,直接就可以把数据库中的varchar/json字符串解析为对象使用.
需要注意:加@ResultMap. xml也要加的: resultMap=BaseResultMap
@ResultMap("BaseResultMap")
@Select("select * from trip_days where trip_id = #{tripId} order by lvl asc")
List<TripDays> findAllByTripIdOrderByLvlAsc(Integer tripId);