MybatisPlus如何完成字段类型转换

这篇具有很好参考价值的文章主要介绍了MybatisPlus如何完成字段类型转换。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

先来回忆下在mybatis中的resultMap作用和是什么

resultMap的作用是什么

在使用传统的mybatis时,我们一般都会在xml文件定义一个ResultMap
image.png
对每个字段都有自己的定义都有两个类型
javaType可以不显式写出来,mybatis可以根据指定的实体类推断出来
jdbcType 也就是对应到数据库中的字段类型
mybatis完成数据库的数据到java实体类型的转换这两个类型是必不可少的。会根据javaType和jdbcType去匹配到对应的处理器完成类型转换
mybatis内置了很多typeHandler在启动时注册

public TypeHandlerRegistry(Configuration configuration) {
    this.unknownTypeHandler = new UnknownTypeHandler(configuration);

    register(Boolean.class, new BooleanTypeHandler());
    register(boolean.class, new BooleanTypeHandler());
    register(JdbcType.BOOLEAN, new BooleanTypeHandler());
    register(JdbcType.BIT, new BooleanTypeHandler());

    register(Byte.class, new ByteTypeHandler());
    register(byte.class, new ByteTypeHandler());
    register(JdbcType.TINYINT, new ByteTypeHandler());

    register(Short.class, new ShortTypeHandler());
    register(short.class, new ShortTypeHandler());
    register(JdbcType.SMALLINT, new ShortTypeHandler());

    register(Integer.class, new IntegerTypeHandler());
    register(int.class, new IntegerTypeHandler());
    register(JdbcType.INTEGER, new IntegerTypeHandler());

    register(Long.class, new LongTypeHandler());
    register(long.class, new LongTypeHandler());

    register(Float.class, new FloatTypeHandler());
    register(float.class, new FloatTypeHandler());
    register(JdbcType.FLOAT, new FloatTypeHandler());

    register(Double.class, new DoubleTypeHandler());
    register(double.class, new DoubleTypeHandler());
    register(JdbcType.DOUBLE, new DoubleTypeHandler());

    register(Reader.class, new ClobReaderTypeHandler());
    register(String.class, new StringTypeHandler());
    register(String.class, JdbcType.CHAR, new StringTypeHandler());
    register(String.class, JdbcType.CLOB, new ClobTypeHandler());
    register(String.class, JdbcType.VARCHAR, new StringTypeHandler());
    register(String.class, JdbcType.LONGVARCHAR, new StringTypeHandler());
    register(String.class, JdbcType.NVARCHAR, new NStringTypeHandler());
    register(String.class, JdbcType.NCHAR, new NStringTypeHandler());
    register(String.class, JdbcType.NCLOB, new NClobTypeHandler());
    register(JdbcType.CHAR, new StringTypeHandler());
    register(JdbcType.VARCHAR, new StringTypeHandler());
    register(JdbcType.CLOB, new ClobTypeHandler());
    register(JdbcType.LONGVARCHAR, new StringTypeHandler());
    register(JdbcType.NVARCHAR, new NStringTypeHandler());
    register(JdbcType.NCHAR, new NStringTypeHandler());
    register(JdbcType.NCLOB, new NClobTypeHandler());

    register(Object.class, JdbcType.ARRAY, new ArrayTypeHandler());
    register(JdbcType.ARRAY, new ArrayTypeHandler());

    register(BigInteger.class, new BigIntegerTypeHandler());
    register(JdbcType.BIGINT, new LongTypeHandler());

    register(BigDecimal.class, new BigDecimalTypeHandler());
    register(JdbcType.REAL, new BigDecimalTypeHandler());
    register(JdbcType.DECIMAL, new BigDecimalTypeHandler());
    register(JdbcType.NUMERIC, new BigDecimalTypeHandler());

    register(InputStream.class, new BlobInputStreamTypeHandler());
    register(Byte[].class, new ByteObjectArrayTypeHandler());
    register(Byte[].class, JdbcType.BLOB, new BlobByteObjectArrayTypeHandler());
    register(Byte[].class, JdbcType.LONGVARBINARY, new BlobByteObjectArrayTypeHandler());
    register(byte[].class, new ByteArrayTypeHandler());
    register(byte[].class, JdbcType.BLOB, new BlobTypeHandler());
    register(byte[].class, JdbcType.LONGVARBINARY, new BlobTypeHandler());
    register(JdbcType.LONGVARBINARY, new BlobTypeHandler());
    register(JdbcType.BLOB, new BlobTypeHandler());

    register(Object.class, unknownTypeHandler);
    register(Object.class, JdbcType.OTHER, unknownTypeHandler);
    register(JdbcType.OTHER, unknownTypeHandler);

    register(Date.class, new DateTypeHandler());
    register(Date.class, JdbcType.DATE, new DateOnlyTypeHandler());
    register(Date.class, JdbcType.TIME, new TimeOnlyTypeHandler());
    register(JdbcType.TIMESTAMP, new DateTypeHandler());
    register(JdbcType.DATE, new DateOnlyTypeHandler());
    register(JdbcType.TIME, new TimeOnlyTypeHandler());

    register(java.sql.Date.class, new SqlDateTypeHandler());
    register(java.sql.Time.class, new SqlTimeTypeHandler());
    register(java.sql.Timestamp.class, new SqlTimestampTypeHandler());

    register(String.class, JdbcType.SQLXML, new SqlxmlTypeHandler());

    register(Instant.class, new InstantTypeHandler());
    register(LocalDateTime.class, new LocalDateTimeTypeHandler());
    register(LocalDate.class, new LocalDateTypeHandler());
    register(LocalTime.class, new LocalTimeTypeHandler());
    register(OffsetDateTime.class, new OffsetDateTimeTypeHandler());
    register(OffsetTime.class, new OffsetTimeTypeHandler());
    register(ZonedDateTime.class, new ZonedDateTimeTypeHandler());
    register(Month.class, new MonthTypeHandler());
    register(Year.class, new YearTypeHandler());
    register(YearMonth.class, new YearMonthTypeHandler());
    register(JapaneseDate.class, new JapaneseDateTypeHandler());

    // issue #273
    register(Character.class, new CharacterTypeHandler());
    register(char.class, new CharacterTypeHandler());
  }

当然我们不指定类型的话mybatis也具备自动推断类型的能力。
org.apache.ibatis.executor.resultset.DefaultResultSetHandler#createAutomaticMappings
创建自动的字段映射根据数据库查询结果类型,和我们指定的对象字段类型做映射

mybatisPlus如何完成字段映射

当然也可以指定resultMap

@TableNam中有resultMap属性

    /**
     * 实体映射结果集,
     * 只生效与 mp 自动注入的 method
     */
    String resultMap() default "";

@Mapper
public interface UserDoMapper extends BaseMapper<User> {

    @Results(
            id = "userResultMap",
            value = {@Result(column = "id",property = "id",javaType = Integer.class,jdbcType = JdbcType.INTEGER),
                    @Result(column = "user_name",property = "userName",javaType = String.class,jdbcType = JdbcType.VARCHAR),
                    @Result(column = "pass_word",property = "passWord",javaType = String.class,jdbcType = JdbcType.VARCHAR),
                    @Result(column = "real_name",property = "realName",javaType = String.class,jdbcType = JdbcType.VARCHAR),
                    @Result(column = "json_arr",property = "jsonArr",typeHandler = StringToJsonArrayBaseTypeHandler.class),

            }
    )

    @Select("SELECT * FROM user ${ew.customSqlSegment}")
    User searchDetail( @Param(Constants.WRAPPER) Wrapper<User> wrapper);


}

@TableName(resultMap = "userResultMap")
public class User {
    @TableField(jdbcType = JdbcType.INTEGER)
    private Integer id;
    @TableField(jdbcType = JdbcType.VARCHAR)
    private String userName;
    @TableField(jdbcType = JdbcType.VARCHAR)
    private String passWord;
    @TableField(jdbcType = JdbcType.VARCHAR)
    private String realName;
    @TableField(typeHandler = StringToJsonArrayBaseTypeHandler.class)
    private List<String> jsonArr;

}

那么我们不想手动定义ResutMap但是又想处理一些复杂类型的转换 就可以使用autoResultMap

自动映射

我们在使用mybatisPlus时在大多数情况是不会定义resultMap的,那么mybatisPlus是如何完成字段映射的,那么答案显而易见,就是使用myabtis的字段自动创建映射的功能。
自动映射的方案有什么缺点?
1.对于复杂的类型,无法指定转换方案,无法使用自定义的类型转换器。
2.无法使用关联查询
开启autoResultMap

@TableName(autoResultMap = true)

那么mybatisPlus会根据我们的实体类的类型,为我们自动注入resultMap,注入的resultMap也会自动推断出需要使用的类型转换器当然我们也可以指定
image.png
例如

   @TableField(typeHandler = StringToJsonArrayBaseTypeHandler.class)
    private List<String> jsonArr;

也因此说,对于查询来说,mybatisPlus通过@TableField指定类型转换器,一定要开启autoResultMap才能生效了。另外mybatisPlus只会为BaseMapper中的方法生成resultMap,而我们自定义的方法,是不会生成的。
例如

@Mapper
public interface UserDoMapper extends BaseMapper<User> {

    @Select("SELECT * FROM user ${ew.customSqlSegment}")
    User searchDetail( @Param(Constants.WRAPPER) Wrapper<User> wrapper);
}

这种写法autoResultMap和指定的类型转换器是不会生效的。如果有复杂字段转换需求,需要通过@Results标签定义resultMap
例如
image.png
以及通过@ResultMap标签进行引用
image.png

@TableField是能够指定jdbcType的

不指定jdbcType时mybatis往往也能够完成自动转换,例如java中的String自然对应到数据库的VAERCHAR
在mybatis无法根据自动完成javaType到jdbcType的转换时,可以使用@TableField注解完成转换,例如我们想将一个数据库中的VARCHAR类型映射成为java中的Integer,对于插入操作时又要完成Integer到VARCHAR的转换,如果不指定jdbcType那么插入操作将会报错

   @TableField(jdbcType = JdbcType.VARCHAR)
    private Integer age;

mybatis如何完成查询参数转换

前面看的是对于查询结果的转换,那么对于插入,更新,查询等操作,也有一个javaType到jdbcType的转换,对于复杂的字段类型 例如集合转json又是如何生效的?
还是先看传统mybatis定义映射的写法

<insert id="insert" parameterType="com.imtech.yasha.sp.common.mapper.dto.sp.ZbLabourBidAuctionList" >
    insert into zb_labour_bid_auction_list (id, uuid, uuid_t, 
                                            creater, create_time, updater, 
                                            update_time, item_d, item_n, 
                                            order_no, list_no, sub_project_name, 
                                            construction_tech, unit, project_quantity, 
                                            unit_price, total, remark, 
                                            supplier_no, supplier_name)
    values (#{id,jdbcType=BIGINT}, #{uuid,jdbcType=VARCHAR}, #{uuidT,jdbcType=VARCHAR}, 
            #{creater,jdbcType=VARCHAR}, #{createTime,jdbcType=TIMESTAMP}, #{updater,jdbcType=VARCHAR}, 
            #{updateTime,jdbcType=TIMESTAMP}, #{itemD,jdbcType=VARCHAR}, #{itemN,jdbcType=VARCHAR}, 
            #{orderNo,jdbcType=VARCHAR}, #{listNo,jdbcType=VARCHAR}, #{subProjectName,jdbcType=VARCHAR}, 
            #{constructionTech,jdbcType=VARCHAR}, #{unit,jdbcType=VARCHAR}, #{projectQuantity,jdbcType=NUMERIC}, 
            #{unitPrice,jdbcType=NUMERIC}, #{total,jdbcType=NUMERIC}, #{remark,jdbcType=VARCHAR}, 
            #{supplierNo,jdbcType=VARCHAR}, #{supplierName,jdbcType=VARCHAR})
    </insert>

在参数上一般都会定义jdbcType,至于JavaType可以从parameterType指定的class中推断出来,这样javaTyp和jdbcType都被确定下来,很容易匹配到对应的处理器进行类型转换。
那么在mybatisPlus中显然不会为每个入参字段定义jdbcType,那么对于入参是如何进行转换的,复杂类型又是如何指定的

   @TableField(typeHandler = StringToJsonArrayBaseTypeHandler.class)
    private List<String> jsonArr;

答案也是通过@TableField指定的,而且即使关闭autoResultMap,对于查询参数的转换,指定的类型转换器和jdbcType也是会生效的。
image.png文章来源地址https://www.toymoban.com/news/detail-444972.html

到了这里,关于MybatisPlus如何完成字段类型转换的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Mysql同步到ES时date和time字段类型转换问题解决办法

    这个问题中发生问题的es字段映射类型为date类型!!! 字符串类型的会好很多,关键我这边是通过logstash生成索引,并且全量同步的,不好改索引类型!!! 问题描述: 根据错误日志,似乎是Elasticsearch无法解析日期字段 START_TIME 。这个字段的格式是 YYYY-MM-DD HH:MM:SS ,而Ela

    2024年02月16日
    浏览(46)
  • Access数据库操作踩坑记:数据溢出,设置1字段为Null是因为类型转换失败

    从过了2008年以后,就没有操作过Access数据库了,本以为应该是就此告别这它了。之后有本地存储肯定是sqlite。没想到最近项目上又碰到了Access操作。类型贼少,还不和大伙一致。总是那么搞特殊。这不,一操作就踩坑。还不知道具体错在哪里。胸闷...... 1 数据溢出 多半是由

    2024年02月04日
    浏览(74)
  • mysql数据库存数组类型数据,如何判断数组中是否包含某个值?使用mybatisplus查询。

    跟mybatisplus中.in()方法相反的函数 mybatisplus的in函数:查询的是数据库的某个属性的值是否在给定的集合中。这里我们讲的是一个值是否在数据库的某个属性数组中。 说明: 这是一张学生信息表,其中包含了学生曾经就读过的学校。现在我们要做的就是查询哪些学生就读过指

    2024年02月16日
    浏览(99)
  • es如何修改字段类型

    演示:如下是一个包含date字段的索引ttteset-000001,接下来我们将其字段类型改为text类型

    2024年02月11日
    浏览(51)
  • mybatisPlus查询排除某个字段

    在 MyBatis Plus 中,可以使用 @TableField 注解来排除某个字段在查询中的使用。@TableField 注解提供了一些属性可以用于指定字段的行为,其中 exist 属性可以控制字段是否在 SQL 语句中出现。 以下是一个示例代码,展示如何使用 @TableField 注解排除某个字段在查询中的使用: 在上述

    2024年02月12日
    浏览(59)
  • Hive表字段类型转换错误解决:Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask.

    假设某有数据的Hive表temp_table的字段状况如下,需要将A字段由string类型转为int类型: 字段名称 字段类型 是否为分区字段 A string 否 B int 否 C bigint 否 D string 是 在Hdfs数据库中,该表的数据是以Parquet文件格式存储的,包含多个分区。 原本在该表中的字段A的类型为int 。然而笔者

    2024年02月02日
    浏览(82)
  • 如何将 performance_schema 中的 TIMER 字段转换为日期时间

    最近有好几个朋友问,如何将 performance_schema.events_statements_xxx 中的 TIMER 字段(主要是TIMER_START和TIMER_END)转换为日期时间。 因为 TIMER 字段的单位是皮秒(picosecond),所以很多童鞋会尝试直接转换,但转换后的结果并不对,看下面这个示例。 下面会从源码角度分析 TIMER 字段

    2024年02月05日
    浏览(43)
  • Elasticsearch 8.X 如何依据 Nested 嵌套类型的某个字段进行排序?

    这是来自社区的一个真实企业场景问题。 https://elasticsearch.cn/question/13135 如下所示, 希望在查出的结果后, 对结果进行后处理,对tags列表,根据depth进行排序。 Elasticsearch 能支持的排序方式罗列如下: 包含但不限于: 基于特定字段的排序 基于Nested对象字段的排序 基于特定

    2024年02月02日
    浏览(56)
  • 解决用MybatisPlus修改字段时会自动忽略传值为null的字段

    产生原因 我们使用mybatis-plus框架的时候会产生一个很尴尬的情况,在使用mybatis-plus的自带封装的update的方法的时候,如果你想要修改某个字段为null值,则会自动忽略修改你这个字段,导致这个字段还是原来未修改前的值 。 解决方法 根据查阅相关资料,总结出以下几点解决

    2024年02月16日
    浏览(58)
  • mybatisplus在新增或者修改时设置字段自动填充

    1、需要实现元对象字段填充控制器抽象类,如下代码 fieldName要注意对应的生成的实体字段,不是数据库对应字段,否则无效 2、在生成的实体字段,@TableField增加fill填充,并写入填充的时机是新增还是修改 在此过程中可能会出现的错: 修改或者插入的时候报类型无效,jav

    2024年01月17日
    浏览(56)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包