1、我们在mysql的使用中,很多时候都需要使用类型处理器。主要可以使类型转化直接在mysql中完成转化。而不用将类型转化入侵到逻辑代码里面,可以使代码的时候更加清晰和明了。在转化的时候又有绝大部分,都是实体类转化为String类型的json的对象存入mysql数据库中。但是每个实体类都去定义一个类型转化器未免过于麻烦,我们可以将此类mysql的转化器转化用一个通用json转化的类处理来处理。
下面是具体代码:
@MappedTypes(Object.class)
@MappedJdbcTypes({JdbcType.LONGNVARCHAR,JdbcType.VARCHAR})
public class MybatisJsonTypeHandler<T extends Object> extends BaseTypeHandler<T> {
private Class<T> tClass;
public MybatisJsonTypeHandler(Class<T> tClass) {
if (null == tClass) {
throw new IllegalArgumentException("type argument cannot be null");
}
this.tClass = tClass;
}
@Override
public void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {
ps.setString(i,JSON.toJSONString(parameter));
}
@Override
public T getNullableResult(ResultSet rs, String columnName) throws SQLException {
return JSON.parseObject(rs.getString(columnName), tClass);
}
@Override
public T getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
return JSON.parseObject(rs.getString(columnIndex), tClass);
}
@Override
public T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
return JSON.parseObject(cs.getString(columnIndex), tClass);
}
}
下面是具体测试使用方法
1、新建一张表来进行测试
CREATE TABLE `type_time` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`time` varchar(255) DEFAULT '[]',
`name` varchar(100) DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8
2、在mapper.xml写插入和查询语句
//mysql 插入测试
<insert id="insertTimeTypeVO" parameterType="com.yin.freemakeradd.vo.TypeTestVO">
insert into type_time(time,name) values (
#{time,typeHandler=com.yin.freemakeradd.handler.MybatisJsonTypeHandler},#{name,jdbcType=VARCHAR})
</insert>
<resultMap type="com.yin.freemakeradd.vo.TypeTestVO" id="timeTypeHandler">
<id column="id" property="id"/>
<result column="name" property="name" />
<result column="time" property="time" typeHandler="com.yin.freemakeradd.handler.MybatisJsonTypeHandler"/>
</resultMap>
//mysql查询测试
<select id="selectTimeType" resultMap="timeTypeHandler">
select id,name,time from type_time
</select>
vo实体类
@Data
@NoArgsConstructor
public class TypeTestVO {
private Integer id;
private String name;
private List<TimeVO> time;
public TypeTestVO(String name, List<TimeVO> time) {
this.name = name;
this.time = time;
}
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class TimeVO {
private String startTime;
private String endTime;
}
构造数据测试
@Test
public void testTypeHandler(){
TimeVO timeVO = new TimeVO("2020-04-18","2020-04-19");
TimeVO timeVO2 = new TimeVO("2020-04-17","2020-04-20");
List<TimeVO> timeLst = new ArrayList<>();
timeLst.add(timeVO);
timeLst.add(timeVO2);
TypeTestVO typeTestVO = new TypeTestVO("name2", timeLst);
orderDao.insertTimeTypeVO(typeTestVO);
List<TypeTestVO> typeTestVOS = orderDao.selectTimeType();
System.out.println(typeTestVOS);
}
可以看到我们在类型处理器类并未指定mysql的具体的类型,mysql通过类型处理器可以直接将实体对象和json在查询的时候完成转化。