mybatis-plus如何配置自定义数据类型TypeHandle

目录
  • 如何配置自定义数据类型TypeHandle
    • 1.背景
    • 2.举例
    • 3.TypeHandle配置
  • 自定义TypeHandler的使用笔记
    • 类型转换器还可以通过注解配置java类型和jdbc类型

如何配置自定义数据类型TypeHandle

1.背景

mybatis-plus在mybatis的基础的上,做了全面增强功能,极大的提高了我们的开发效率。有时候我们使用的实体字段类型,与数据库创建的字段类型无法对应上,这时候就需要配之自定义的类型处理类,来处理代码和数据库之间的数据流转。

2.举例

我们有个实体类TestEntity,使用注解@TableName表示对应数据库表名为test

@Data
@TableName(value = "test")
public class TestEntity{
  private static final long serialVersionUID = 8565214506859404278L;
  private String id;
  private String type;
  private Document content;
}

DAO层对象

@Mapper
public interface TestDao extends BaseMapper<TestEntity> {
}

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="com.aisino.dao.TestDao">
    <resultMap type="com.aisino.entity.TestEntity" id="testMap">
        <result property="id" column="id"/>
        <result property="type" column="name"/>
        <result property="content" column="content"/>
    </resultMap>
</mapper>

其中Document使用的是org.w3c.dom.Document对象,数据库存储的字段类型为bytea,我这里使用的是postgresql,显然数据类型无法匹配,这里需要编写类型处理类进行数据类型转换。

3.TypeHandle配置

1.编写TypeHandle,首先需要明确我们代码中和数据库中各自的数据类型,编写处理类DocumentTypeHandler继承BaseTypeHandler,并重写4个方法:

(1)setNonNullParameter表示从代码中的数据类型转换成数据库数据类型,即Document转为BLOB类型。这里的基本思路就是将Document转为String再转为字节流,最后利用setBinaryStream方法转为数据库对象。

(2)getNullableResult,getNullableResult,getNullableResult表示从数据库类型中获取数据并转换为代码中的数据类型,即BLOB转为Document类型。这里的基本思路就是上一步的逆过程。

  • @MappedTypes中填写的是我们代码中的数据类型
  • @MappedJdbcTypes中填写的是数据库中的数据类型
@MappedTypes(Document.class)
@MappedJdbcTypes(JdbcType.BLOB)
public class DocumentTypeHandler extends BaseTypeHandler {
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException {
        String docStr = docToString((org.w3c.dom.Document) parameter);
        InputStream in = new ByteArrayInputStream(docStr.getBytes());
        ps.setBinaryStream(i, in);
    }
    @Override
    public Object getNullableResult(ResultSet rs, String columnName) throws SQLException {
        byte[] bytes = rs.getBytes(columnName);
        return !rs.wasNull() && bytes != null ? stringToDoc(new String(bytes)) : null;
    }
    @Override
    public Object getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        byte[] bytes = rs.getBytes(columnIndex);
        return !rs.wasNull() && bytes != null ? stringToDoc(new String(bytes)) : null;
    }
    @Override
    public Object getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        byte[] bytes = cs.getBytes(columnIndex);
        return !cs.wasNull() && bytes != null ? stringToDoc(new String(bytes)) : null;
    }
    public static String docToString(Document doc) {
        // XML转字符串
        String xmlStr = "";
        try {
            TransformerFactory tf = TransformerFactory.newInstance();
            Transformer t = tf.newTransformer();
            t.setOutputProperty("encoding", "UTF-8");
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            t.transform(new DOMSource(doc), new StreamResult(bos));
            xmlStr = bos.toString();
        } catch (TransformerConfigurationException e) {
            // TODO
            e.printStackTrace();
        } catch (TransformerException e) {
            // TODO
            e.printStackTrace();
        }
        return xmlStr;
    }
    public static Document stringToDoc(String xmlStr) {
        //字符串转XML
        Document doc = null;
        try {
            xmlStr = new String(xmlStr.getBytes(), "UTF-8");
            StringReader sr = new StringReader(xmlStr);
            InputSource is = new InputSource(sr);
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            DocumentBuilder builder;
            builder = factory.newDocumentBuilder();
            doc = builder.parse(is);
        } catch (ParserConfigurationException e) {
            // TODO
            e.printStackTrace();
        } catch (SAXException e) {
            // TODO
            e.printStackTrace();
        } catch (IOException e) {
            // TODO
            e.printStackTrace();
        }
        return doc;
    }
}

2.回到实体类配置,以下是修改后的实体类

(1)在注解@TableName中增加autoResultMap = true表示使用xml中的映射配置

(2)增加注解配置@TableField(typeHandler = DocumentTypeHandler.class)表示content字段使用数据类型处理类DocumentTypeHandler.class

@Data
@TableName(value = "test",autoResultMap = true)
public class TestEntity{
  private static final long serialVersionUID = 8565214506859404278L;
  private String id;
  private String type;
  @TableField(typeHandler = DocumentTypeHandler.class)
  private Document content;
}

3.以下是修改后的xml配置

(1)content字段配置jdbcType=“OTHER”,配置数据处理类typeHandler=“com.aisino.jdbc.ibatis.DocumentTypeHandler”

<?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="com.aisino.dao.TestDao">
    <resultMap type="com.aisino.entity.TestEntity" id="testMap">
        <result property="id" column="id"/>
        <result property="type" column="name"/>
        <result property="content" column="content" jdbcType="OTHER" typeHandler="com.aisino.jdbc.ibatis.DocumentTypeHandler"/>
    </resultMap>
</mapper>

4.注意事项

(1)编写TypeHandle类时候,继承BaseTypeHandler<Document>试过不行,原因暂未深究。

(2)实体类的注解@TableField(typeHandler = DocumentTypeHandler.class)与xml配置的处理类路径typeHandler="com.aisino.jdbc.ibatis.DocumentTypeHandler"缺一不可,因为看过网上说只配置注解即可,我试了不行,原因暂未深究。

自定义TypeHandler的使用笔记

可通过自定义的TypeHandler实现某个属性在插入数据库以及查询时的自动转换,本例中是要将Map类型的属性转化成CLOB,然后存入数据库。由于是复杂的Map,mp自带的json转换器会丢失部分信息。

类型转换器还可以通过注解配置java类型和jdbc类型

  • @MappedTypes:注解配置 java 类型
  • @MappedJdbcTypes:注解配置 jdbc 类型

定义:

@Slf4j
@MappedTypes({Object.class})
@MappedJdbcTypes(JdbcType.VARCHAR)
public class WeightListTypeHandler  extends AbstractJsonTypeHandler<Object> {
    private static Gson gson = new Gson();
    private final Class<?> type;
    public WeightListTypeHandler(Class<?> type) {
        if (log.isTraceEnabled()) {
            log.trace("WeightListTypeHandler(" + type + ")");
        }
        Assert.notNull(type, "Type argument cannot be null");
        this.type = type;
    }
    @Override
    protected Object parse(String json) {
        Type type1 = new TypeToken<Map<String, List<WeightItem>>>(){}.getType();
        return gson.fromJson(json, type1);
    }
    @Override
    protected String toJson(Object obj) {
        return gson.toJson(obj);
    }
    public static void setGson(Gson gson) {
        Assert.notNull(gson, "Gson should not be null");
        WeightListTypeHandler.gson = gson;
    }
}

使用:

注意@TableName 注解 autoResultMap 属性

@Data
@NoArgsConstructor
@TableName(value = "mix_target",autoResultMap = true)
public class MixTarget extends Model<MixTarget> {
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;
    /**
     *指标描述
     */
    @TableField("description")
    private String description;
    /**
     * 指标名
     */
    @TableField("name")
    private String name;
    /**
     * 对应属性名
     */
    @TableField("property_name")
    private String propertyName;
    /**
     * 起始点类型
     */
    @TableField("source_type")
    private String sourceType;
    /**
     * 属性对应权值列表
     * key 属性名 value指定条件下的权值
     */
    @TableField(value = "weight_list",typeHandler = WeightListTypeHandler.class,jdbcType = JdbcType.CLOB)
    private Map<String, List<WeightItem>> weightList;
    /**
     * 运行状态
     * 0 新建未运行
     * 1 运行中
     * 2 已运行 成功
     * 3 已运行 失败
     */
    @TableField("status")
    private Integer status;
    /**
     * 是否可用
     * 1 true
     * 0 false
     */
    @TableField("enable")
    private Integer enable;
    @TableField("create_time")
    private LocalDateTime createTime;
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • Mybatis自定义typeHandle过程解析

    一 前言 本篇文章的基础是建立在mybatis配置 二 准备工作 2.1建表语句 CREATE TABLE `customer` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', `customer_name` varchar(255) DEFAULT NULL COMMENT '顾客名称', `gender` varchar(255) DEFAULT NULL COMMENT '性别', `telephone` varchar(255)

  • MyBatis自定义typeHandler的完整实例

    自定义typeHandler 对于自定义typeHandler来说,需要在配置文件中注册typeHandlers 然后需要实现TypeHandler接口, 一个例子 首先编写调度的处理类 package com.ming.MyBatis; import org.apache.ibatis.type.JdbcType; import org.apache.ibatis.type.TypeHandler; import org.apache.logging.log4j.LogManager; imp

  • mybatis自定义类型处理器TypehHandler示例详解

    前言 当大家使用mybatis作为持久层框架时,在存储和查询数据时,只需要在mapper.xml文件中配置好对应字段的JdbcType和JavaType,mybatis就可以帮我们转化对应的类型.这背后是有mybatis内置的类型转换器做转换(可见源码TypeHandlerRegistry).但是有时候,我们会对某些字段做特殊处理,比如加密和解密.状态转换.类型转换等.这个时候我们需要自定义类型转换器. 类架构 从上面的图中可以看出MyBatis中整个类型处理器实现架构,TypeHandler接

  • Mybatis实现自定义类型转换器TypeHandler的方法

    先给大家简单介绍下mybatis MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装.MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录. 此文其实是java操作Oracle类型XMLType总结二:使用Mybatis附带的一篇小结. Mybatis实现自定义的转换器,

  • mybatis-plus如何配置自定义数据类型TypeHandle

    目录 如何配置自定义数据类型TypeHandle 1.背景 2.举例 3.TypeHandle配置 自定义TypeHandler的使用笔记 类型转换器还可以通过注解配置java类型和jdbc类型 如何配置自定义数据类型TypeHandle 1.背景 mybatis-plus在mybatis的基础的上,做了全面增强功能,极大的提高了我们的开发效率.有时候我们使用的实体字段类型,与数据库创建的字段类型无法对应上,这时候就需要配之自定义的类型处理类,来处理代码和数据库之间的数据流转. 2.举例 我们有

  • MyBatis SqlMapConfig.xml配置

    SqlMapConfig.xml配置文件的内容和配置顺序如下 properties(属性) settings(全局配置参数) typeAiases(类型别名) typeHandlers(类型处理器) objectFactory(对象工厂) plugins(插件) environments(环境集合属性对象)mappers(映射器) environment(环境子属性对象) transactionManager(事物管理) datesource(数据源 mappers(映射器) 一.SqlMapC

  • mybatis简介与配置_动力节点Java学院整理

    MyBatis简介 MyBatis 是一个可以自定义SQL.存储过程和高级映射的持久层框架.MyBatis 摒除了大部分的JDBC代码.手工设置参数和结果集重获.MyBatis 只使用简单的XML 和注解来配置和映射基本数据类型.Map 接口和POJO 到数据库记录.相对Hibernate和Apache OJB等"一站式"ORM解决方案而言,Mybatis 是一种"半自动化"的ORM实现. 需要使用的Jar包:mybatis-3.0.2.jar(mybatis核心包

  • MyBatis简介与配置MyBatis+Spring+MySql的方法

    1.1MyBatis简介 MyBatis 是一个可以自定义SQL.存储过程和高级映射的持久层框架.MyBatis 摒除了大部分的JDBC代码.手工设置参数和结果集重获.MyBatis 只使用简单的XML 和注解来配置和映射基本数据类型.Map 接口和POJO 到数据库记录.相对Hibernate和Apache OJB等"一站式"ORM解决方案而言,Mybatis 是一种"半自动化"的ORM实现. 需要使用的Jar包:mybatis-3.0.2.jar(mybatis

  • 初识MyBatis及基本配置和执行

    1.MyBatis简介 MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录. 2. MyBatis的主要构件及其作用 从MyBatis代码实现的角度来看,MyBatis的主要的核心部件有以下几个:

  • Mybatis中SqlMapper配置的扩展与应用详细介绍(1)

    奋斗了好几个晚上调试程序,写了好几篇博客,终于建立起了Mybatis配置的扩展机制.虽然扩展机制是重要的,然而如果没有真正实用的扩展功能,那也至少是不那么鼓舞人心的,这篇博客就来举几个扩展的例子. 这次研读源码的起因是Oracle和MySQL数据库的兼容性,比如在Oracle中使用双竖线作为连接符,而MySQL中使用CONCAT函数:比如Oracle中可以使用DECODE函数,而MySQL中只能使用标准的CASE WHEN:又比如Oracle中可以执行DELETE FORM TABLE WHER

  • mybatis plus代码生成器配置过程解析

    这篇文章主要介绍了mybatis plus代码生成器配置过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 最近在玩项目,发现自己写严重浪费时间~于是想到了代码生成器,之前用过一次的mybatis-plus,再重新实现了一下 确保修改好对应的配置即可 依赖: <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boo

  • Mybatis基于xml配置实现单表的增删改查功能

    Mybatis入门-基于配置实现单表的增删改查 Mybatis简介 官网链接:https://mybatis.org/mybatis-3/zh/index.html.更加详细的信息可以去官网查看. MyBatis 是一款优秀的持久层框架,它支持自定义 SQL.存储过程以及高级映射.MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作.MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型.接口和 Java POJO(Plain Old Java Object

  • 解析MyBatis源码实现自定义持久层框架

    目录 自定义框架设计 自定义框架实现 使用端 框架端 自定义框架设计 使用端 : 提供核⼼配置⽂件: sqlMapConfig.xml : 存放数据源信息,引⼊mapper.xml Mapper.xml : sql语句的配置⽂件信息 框架端: 1.读取配置⽂件 读取完成以后以流的形式存在,我们不能将读取到的配置信息以流的形式存放在内存中,不好操作,可以创建JavaBean来存储 (1)Configuration : 存放数据库基本信息.Map<唯⼀标识,Mapper>, 唯⼀标识:namesp

  • Mybatis中 XML配置详解

    Mybatis常用带有禁用缓存的XML配置 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd" > <configuration> <

随机推荐