溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Mybatis-Plus怎么自定義集合類型的類型處理器

發(fā)布時間:2022-01-13 16:52:25 來源:億速云 閱讀:157 作者:iii 欄目:開發(fā)技術

這篇文章主要講解了“Mybatis-Plus怎么自定義集合類型的類型處理器”,文中的講解內(nèi)容簡單清晰,易于學習與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學習“Mybatis-Plus怎么自定義集合類型的類型處理器”吧!

1.配合xml文件

TypeHandler

/**
 * 描述:fastjson的集合對象類型處理器,將mysql表中的json字段映射到實體類中的{@code List<?>}屬性
 * 對照MP自帶的FastjsonTypeHandler,自帶的類型處理器會把所有的{@code List<?>}都會解析為{@code List<JsonObject>},
 * 這樣在遍歷其中對象時,調(diào)用對象屬性的get、set方法就會發(fā)送類型轉換JsonObject->?,這種情況轉換錯誤。
 * 該處理器必須配合xml文件使用,不然無法獲取要解析的對象類型,同時不能配合MP自帶的{@link com.baomidou.mybatisplus.annotation.TableField}
 * 使用,默認情況下@TableField會將JavaType設置為字段的類型,如果是List<?>則type = List.class,無法明確其中的泛型,類型轉換會變成JsonObject。
 * 用法:
 * <pre>{@code
 * 1.實體類上使用注解@TableName(value = "表名", resultMap = "xml文件中的resultMap的id")
 * 2.xml文件中自定義resultMap并設置需要JSON轉換的字段
 * <result property="實體類屬性名" column="表字段名" javaType="List中的對象全類名,例如List<Email>,則JavaType為Email的全類名" typeHandler="自定義處理器全類名"/>
 * 3.自定義方法上的用法
 * @Mapper
 * public interface DemoDao extends BaseMapper<DemoEntity> {
 *    @Select("select * from demo where demo_id = #{demoId}")
 *    @ResultMap(value = "xml文件中的resultMap的id")
 *    List<DemoEntity> selectListByDemoId(Long demoId);
 * }
 * }</pre>
 */
@Slf4j
@MappedJdbcTypes(value = JdbcType.VARCHAR)
public class FastJsonArrayTypeHandler extends AbstractJsonTypeHandler<List<?>> { 
    private Class<?> type; 
    public FastJsonArrayTypeHandler(Class<?> type) {
        if (log.isTraceEnabled()) {
            log.trace("FastjsonTypeHandler(" + type + ")");
        }
        Assert.notNull(type, "Type argument cannot be null");
        this.type = type;
    }
 
    @Override
    protected List<?> parse(String json) {
        return JSON.parseArray(json, type);// 注意不要使用parseObject方法
    }
 
    @Override
    protected String toJson(List<?> obj) {
        return JSON.toJSONString(obj, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullListAsEmpty, SerializerFeature.WriteNullStringAsEmpty);
    } 
}

xml文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="a.b.dao.DemoDao">
    <resultMap type="a.b.entity.DemoEntity" id="demoMap">
        <result property="DemoInfo" column="demo_info" javaType="a.b.xx.DiseaseInfo" typeHandler="a.b.handler.FastJsonArrayTypeHandler"/>
    </resultMap>
</mapper>

Dao

@Mapper
public interface DemoDao extends BaseMapper<DemoEntity> {
    @Select("select * from demo where demo_id = #{demoId}")
    @ResultMap(value = "demoMap")
    List<DemoEntity> selectListByPlanId(Long demoId);
}

Entity

@Data
@TableName(value = "demo", resultMap = "demoMap")
public class DemoEntity implements Serializable {
    private static final long serialVersionUID = -1L;
 
    /**
     * 主鍵
     */
    @TableId
    private Long id;
    private Long demoId
    /**
     * json字段
     */
    private List<DemoInfo> demoInfo;
}

2.手動注冊

TypeHandler

@Slf4j
@MappedJdbcTypes(value = JdbcType.VARCHAR)
public class FastJsonArrayTypeHandler<T> extends AbstractJsonTypeHandler<Object> { 
    private TypeReference<List<T>> type; 
    public FastJsonArrayTypeHandler(TypeReference<List<T>> type) {
        this.type = type;
    }
 
    @Override
    protected Object parse(String json) {
        return JSON.parseObject(json, type);
    }
 
    @Override
    protected String toJson(Object obj) {
        return JSON.toJSONString(obj, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullListAsEmpty, SerializerFeature.WriteNullStringAsEmpty);
    } 
}

初始化,剩下的bean和dao都不需要額外配置

/**
 * 描述:初始化配置
 * 手動注冊類型處理器
 */
@Component
public class InitConfig implements CommandLineRunner {
    public static final com.alibaba.fastjson.TypeReference<List<DemoInfo>> F_DEMO_INFO = new com.alibaba.fastjson.TypeReference<List<DemoInfo>>() {
    };
    public static final TypeReference<List<DemoInfo>> M_DEMO_INFO = new TypeReference<List<DemoInfo>>() {
    };
    // mp自動裝配時注入的factory,可用于獲取mybatis的配置屬性,這里用來獲取類型處理器的注冊器
    private final SqlSessionFactory factory;
 
    public InitConfig(SqlSessionFactory factory) {
        this.factory = factory;
    }
 
    /**
     * 注冊類型處理器
     * <pre>{@code
     * 1.List<DemoInfo>類型處理器
     * ...
     * }</pre>
     *
     * @param args incoming main method arguments
     * @throws Exception on error
     */
    @SuppressWarnings("all")
    @Override
    public void run(String... args) throws Exception {
        TypeHandlerRegistry typeHandlerRegistry = factory.getConfiguration().getTypeHandlerRegistry();
        typeHandlerRegistry.register(M_DEMO_INFO, new FastJsonArrayTypeHandler(F_DEMO_INFO));
    }
}

目前方法二存在的缺陷:雖然新增、查詢不存在問題,執(zhí)行MP自帶的更新操作時,parameterMap參數(shù)類型都是Object,不會經(jīng)過自定義的TypeHandler處理,最后會把json對象直接set進去(update demo ..., demo_info = JSON對象 ...)導致報錯

感謝各位的閱讀,以上就是“Mybatis-Plus怎么自定義集合類型的類型處理器”的內(nèi)容了,經(jīng)過本文的學習后,相信大家對Mybatis-Plus怎么自定義集合類型的類型處理器這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關知識點的文章,歡迎關注!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI