Mybatis底层映射原理!

因为遇到一些使用时候的问题,实体类的数据类型和sql里面的数据类型不是对应关系。涉及到索引失效问题,因此手撕Mybatis源码,去一探究竟!

看上面图片实体类类型,userint,username,shijian,都不是和数据库需要的java类型匹配。那么mybtis是如何实现入参映射,以及sql执行后的出参映射呢?

 首先进行执行。

进入invoke方法

下面跳过缓存,直接进入SimpleExecutor的doQuery里面的stmt = this.prepareStatement方法,此方法是进行 sql的占位符拼接。上个方法执行结束后,执行var9 = handler.query(stmt,resultHandler)方法,这个方法是执行sql,以及sql和实体类的映射。

下面stmt = this.prepareStatement方法

下面是重点,是参数的处理。以及stme:PreparedStatementProxyImpl类去设置sql。

去设置sql入参。

jdbcType没有用到,之后就是PreparedStatementProxyImpl去setString(1,”2023”)。占位符设置。 

可以发现直到sql占位符结束都是String类型,所以,Mybatis不会对入参对数据进行类型转换,只会去映射对应对sql的Varcher类型。但是sql的那一列类型是INT类型,不过依然能查出来,因为Mysql里面有隐式转换。但是有时候转换的话,sql列的数据类型发生变化会造成索引失效。

执行var9 = handler.query(stmt,resultHandler)方法

ps .execute()先去执行,之后进行映射实体类。 

下面执行nextFilter() 

 之后执行preparedStatement_execute

在这个类下 

set()设置进去。internalBeforeStatementExecute方法结束

之后执行chain.preparedStatement_execute();

 上面执行结束后。结果集开始映射实体类

 当前方法去执行映射的applyAutomaticMappings()去了。执行结束就映射完成了。返回rowValue结果。

下面执行applyAutomaticMappings(),此方法作用是将sql返回值映射到实体类。

循环设置类型。  

之后返回。

 下面接着执行applyAutomaticMappings(),循环设置值,while里面循环进行设置,第一个断点mapping.是拿对应属性的值,并且变成实体类里面需要的类型,第二个断点是.setValue设置到实体类里面。

根据getInt获取值1。

开始设置

上面的invoke去设置跳到实体类里面。

之后继续循环设置其他值 

变成String类型返回  

进行设置。

 下面开始循环,只看关键点,将返回的String类型变成int类型,之后就是设置,不在重复。

获取时间的字符串。

applyAutomaticMappers执行结束 ,所有结果都映射完成。

执行结束返回结果。 

 

总结:mybatis是根据java的入参类型进行sql查询的,(最好规范使用),如当前传入的是一个String类型的参数,那么sql里面就是Varcher类型,但是数据库里面的如果是int类型,有可能造成当前列的索引失效(隐式转换)。sql执行后返回结果后的时候,返回的是数据库类型,但是映射到实体类的时候,mybatis会自动给转成需要的类型,如返回的是int类型,但是实体类是String类型,那么就会自动转成String类型映射到实体类。(mybatis入参不管,出参管)

其他类型参数传入

传入String日期格式类,sql里面还是字符串格式。都能正常使用。

MybatisShiyan mybatisShiyan2 = orderMapper.getd("2023-05-20");

设置占位符"20230520","2023-05-20""2023--05--20"可以正常使用

传入Date日期类,Timestamp日期类这个是继承类日期类。

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date date = new Date();
try {
    date = sdf.parse("2023-05-20");
} catch (ParseException e) {
    throw new RuntimeException(e);
}
MybatisShiyan mybatisShiyan3 = orderMapper.getd2(date);

设置占位符

 

 

 

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值