MyBatis借助BaseTypeHandler实现特殊的字段(数组或json)映射


问题背景

假设有一张表
CREATE TABLE `tb_event_info` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键', `event_no` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '事件编号', `event_title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '事件标题', `event_type` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '事件类型多个用\',\'隔开' PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 1298 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '事件信息' ROW_FORMAT = Dynamic;

对应的entity

@TableName("event_info") @Data public class EventInfo extends Model<EventInfo> { private static final long serialVersionUID = 1L; /** * 主键 */ @TableId(value = "id", type = IdType.AUTO) private Long id; /** * 事件编号 */ private String eventNo; /** * 事件标题 */ private String eventTitle; /** * 事件类型 */ private String[] eventType; }

event_type 存的是英文逗号隔开的字符串,如(11001,11002,11003), eventType 用String类型可以正常映射,如果我想用数组String[]来映射eventType,查出来的结果是[ 11001,11002,11003 ],这样的数组,如何操作呢?

实现代码

我们可以借助 org.apache.ibatis.type.BaseTypeHandler 这个类来实现,定义一个MyArrayTypeHandler类,继承它。

 import org.apache.commons.lang3.StringUtils; import org.apache.ibatis.type.BaseTypeHandler; import org.apache.ibatis.type.JdbcType; import org.apache.ibatis.type.TypeException; import java.sql.*; /** * @Author: java890.com * @Date: 2021/10/19 14:05 */ public class MyArrayTypeHandler extends BaseTypeHandler<String[]> { 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"; @Override public void setNonNullParameter(PreparedStatement ps, int i, String[] parameter, JdbcType jdbcType) throws SQLException { String typeName = TYPE_NAME_VARCHAR; if (typeName == null) { throw new TypeException("ArrayTypeHandler parameter typeName error, your type is " + parameter.getClass().getName()); } // 这3行是关键的代码,创建Array,然后ps.setArray(i, array)就可以了 Connection conn = ps.getConnection(); Array array = conn.createArrayOf(typeName, parameter); ps.setArray(i, array); } @Override public String[] getNullableResult(ResultSet rs, String columnName) throws SQLException { return getArray(rs.getString(columnName)); } @Override public String[] getNullableResult(ResultSet rs, int columnIndex) throws SQLException { return getArray(rs.getString(columnIndex)); } @Override public String[] getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { return getArray(cs.getString(columnIndex)); } /** * 该方法就是把在 mapper xml 里配置了typeHandler=MyArrayTypeHandler的字段, * 走我们这个自定义方法来实现字符串转字符串数组 * 同理,我们可以把它转成任何我们想转的格式,如Json * @param value * @return */ private String[] getArray(String value) { if (StringUtils.isBlank(value)) { return null; } return value.split(","); } }

接下来就是EventInfoMapper.xml文件,只贴核心代码

<resultMap id="eventMap" type="com.xxxxx.EventInfo"> <id column="id" property="id" /> <result column="event_no" property="eventNo" /> <result column="event_title" property="eventTitle" /> <!-- 这一行就是核心的地方,要加上我们自定义的typeHandler类 --> <result column="event_type" property="eventType" typeHandler="com.xxxxx.handler.MyArrayTypeHandler" /> </resultMap> <select id="pageSearch" resultMap="eventMap"> select * from event_info </select>

查询结果

最后查出来就是我们想要的字符串数组结构

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM