mybatis通过TypeHandler list转换string类型转换方式
作者:lMasterSparkl
这篇文章主要介绍了mybatis通过TypeHandler list转换string类型转换方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
mybatis通过TypeHandler list转换string类型转换
问题描述
因为需要存入list数据类型所以mybatis端需要TypeHandler进行类型转换
代码
1.转换工具类
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import org.apache.ibatis.type.BaseTypeHandler; import org.apache.ibatis.type.JdbcType; import org.springframework.stereotype.Component; import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; /** * @ClassName ListToStringHandler * @Description mybatis list转换为String 相互转换工具类 * @Author ygt * @Date 2021/3/3 14:49 * @Version V1.0 */ @Component public class ListToStringHandler extends BaseTypeHandler<List> { @Override public void setNonNullParameter(PreparedStatement preparedStatement, int i, List list, JdbcType jdbcType) throws SQLException { preparedStatement.setString(i, JSON.toJSONString(list)); } @Override public List getNullableResult(ResultSet resultSet, String s) throws SQLException { JSONArray jsonArray = JSONArray.parseArray( resultSet.getString(s)); return jsonArray; } @Override public List getNullableResult(ResultSet resultSet, int i) throws SQLException { JSONArray jsonArray = JSONArray.parseArray( resultSet.getString(i)); return jsonArray; } @Override public List getNullableResult(CallableStatement callableStatement, int i) throws SQLException { JSONArray jsonArray = JSONArray.parseArray( callableStatement.getString(i)); return jsonArray; } }
2.sql xml 部分代码
需要注意 有的地方需要加双引号有的地方不需要加双引号否则有可能会出现类似如下报错 其实是双引号多了
mybatis: No enum constant org.apache.ibatis.type.JdbcType.“VARCHAR”
<resultMap id="BaseResultMap" type="xxxx.GameMatch"> <id column="id" jdbcType="INTEGER" property="id" /> <result column="game_id" jdbcType="INTEGER" property="gameId" /> <result column="positions" jdbcType="VARCHAR" property="positions" typeHandler="xxx.util.ListToStringHandler" /> <result column="sub_channels" jdbcType="VARCHAR" property="subChannels" typeHandler="xxx.util.ListToStringHandler" /> </resultMap> <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer"> delete from game_match where id = #{id,jdbcType=INTEGER} </delete> <insert id="insert" parameterType="xxx.model.GameMatch"> insert into game_match (id, game_id, positions, sub_channels) values (#{id,jdbcType=INTEGER}, #{gameId,jdbcType=INTEGER}, #{positions, jdbcType=VARCHAR ,typeHandler=xxx.util.ListToStringHandler}, #{subChannels,jdbcType=VARCHAR}) </insert> <update id="updateByPrimaryKey" parameterType="xxx.model.GameMatch"> update game_match set game_id = #{gameId,jdbcType=INTEGER}, positions = #{positions, jdbcType=VARCHAR ,typeHandler=xxx.util.ListToStringHandler}, sub_channels = #{subChannels, jdbcType=VARCHAR ,typeHandler=xxx.util.ListToStringHandler} where id = #{id,jdbcType=INTEGER} </update>
mybatis转换器TypeHandler
写一个自己的TypeHandler 实现TypeHandler接口。。泛型是你要转换的类型
@MappedJdbcTypes(JdbcType.VARCHAR) //映射的jdbctype类型 @MappedTypes(List.class) // 要转换的数据类型 public class List2StringTypeHandler implements TypeHandler<List<String>> { // 实现TypeHandler<要转换的java数据类型 /** * 将字段处理到数据库中 * @param ps prestatement * @param i prestatement 设置参数 对应的索引 * @param parameter 要转换的数据。。 这个类型和泛型类型一致 * @param jdbcType * @throws SQLException */ @Override public void setParameter(PreparedStatement ps, int i, List<String> parameter, JdbcType jdbcType) throws SQLException { // 手动将 list 处理为 string StringBuilder sb = new StringBuilder(); for (String s : parameter) { sb.append(s).append("."); } ps.setString(i,sb.toString()); } /** * 将resultSet 转换为 对象对应的字段类型 * @param rs * @param columnName * @return * @throws SQLException */ @Override public List<String> getResult(ResultSet rs, String columnName) throws SQLException { // 将字符串 转换为 list String s = rs.getString(columnName); String[] arr = s.split(","); return Arrays.asList(arr); } @Override public List<String> getResult(ResultSet rs, int columnIndex) throws SQLException { return null; } // 存储过程用到 @Override public List<String> getResult(CallableStatement cs, int columnIndex) throws SQLException { return null; } }
将这个TypeHandler注入到mybatis配置文件中,让mybatis知道这个TypeHandler
<configuration> <properties resource="db.properties"></properties> <!-- 注册typeHandler--> <typeHandlers> <package name="com.cj.typehandler"/> </typeHandlers> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="${db.driver}"/> <property name="url" value="jdbc:mysql:///test01?serverTimezone=Asia/Shanghai"/> <property name="username" value="root"/> <property name="password" value="${db.password}"/> </dataSource> </environment> </environments> <mappers> <!-- 用斜杠--> <!-- <mapper resource="com/cj/mapper/UserMapper.xml"/>--> <mapper resource="com/cj/UserMapper.xml"/> <!-- <package name="com.cj"/>--> <mapper resource="com/cj/TypeHandlerTransfer.xml" /> </mappers> </configuration>
在写mapper映射文件的时候,要指定这个字段使用的是什么类型转换器。。在读取的时候指定,,在写入的时候也要指定(全限定类名)
读取的时候指定
<resultMap id="TypeHandlerMap" type="com.cj.TypeHandlerModel"> <id property="id" column="id"/> <result property="hobby" column="hobby" typeHandler="com.cj.typehandler.List2StringTypeHandler"/> </resultMap> <select id="getEntity" resultMap="TypeHandlerMap"> select * from typehandler </select>
写入的时候指定
<insert id="insertEntity" > insert into typeHandler (hobby) values (#{hobby,typeHandler=com.cj.typehandler.List2StringTypeHandler}) </insert>
springboot可以指定typeHandler位置:
# 设置typehandler包位置 mybatis.type-handlers-package=com.cj.typeHandler
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。