mybatis查找typeHandler过程分析

mybatis查找typeHandler过程分析,第1张

将sql中的所有待填参数的类型和参数的类型做组合

orgapacheibatisbuilderSqlSourceBuilder#parse

参数处理:通过sql中的参数“authorId,jdbcType=VARCHAR”解析jdbcType,java类型是通过参数类型解析的。因此如果sql中没有写jdbcType=VARCHAR,这里将解析不到jdbcType,所以查找typehandler时将只通过javaType查找

orgapacheibatisbuilderSqlSourceBuilderParameterMappingTokenHandler#buildParameterMapping

处理结果:通过类型查找typeHandler

orgapacheibatisexecutorresultsetResultSetWrapper#getTypeHandler

获取typeHandler

orgapacheibatistypeTypeHandlerRegistry

封装resultMap,其中已经封装好了所使用的typeHandler,如果查询语句没有使用resultMap,这里封装时没有添加typehandler

orgapacheibatisbuilderMapperBuilderAssistant#addMappedStatement(javalangString, orgapacheibatismappingSqlSource, orgapacheibatismappingStatementType, orgapacheibatismappingSqlCommandType, javalangInteger, javalangInteger, javalangString, javalangClass<>, javalangString, javalangClass<>, orgapacheibatismappingResultSetType, boolean, boolean, boolean, orgapacheibatisexecutorkeygenKeyGenerator, javalangString, javalangString, javalangString, orgapacheibatisscriptingLanguageDriver, javalangString)

mybatis sql的执行过程有sql的解析和结果集映射,这两个过程都使用了typehandler。

sql解析时会将参数填充到sql中,此时会通过jdbcType和javaType来查找对应的typeHandler(如果sql中没有使用类似“jdbcType=BIGINT”,则无法获取该jdbcType,因此只能通过javaType去查找对应的typeHandler)。

例如sql如下:

jdbcType是通过sql中“jdbcType=BIGINT”来获取的,所以如果我们在写sql时如果不填写“jdbcType=BIGINT”,则sql解析时将无法获取该字段的jdbcType。javaType是通过参数的名字,通过反射获取该属性的类型的。

结果集映射时分两种:使用ResultMap和不使用ResultMap

①使用ResultMap

如上述所示,如果使用ResultMap,则mybatis会根据其中的jdbcType和反射得到的java类型,来查找typeHandler。

②不使用ResultMap

例如sql如下:

这种情况下查询到结果集并映射到实体类时,无法获取到每个字段的jdbcType,而每个字段的javaType会通过反射获取到。然后通过javaType去查找typeHandler。

*** 作。具体的步骤如下:

获取 MyBatis 中的 MappedStatement 对象。可以通过 SqlSession 的 getConfiguration() 方法获取 Configuration 对象,然后再通过 Configuration 对象的 getMappedStatement() 方法获取 MappedStatement 对象。

从 MappedStatement 对象中获取 BoundSql 对象,即 SQL 语句绑定的参数对象。

从 BoundSql 对象中获取 SQL 语句字符串。可以通过调用 getSql() 方法获取 SQL 语句字符串。

对 SQL 语句进行相应的 *** 作。例如,可以对 SQL 语句进行修改、输出等 *** 作。

Java 通过反射获取 MyBatis 中的 SQL 语句的代码示例:

SqlSession sqlSession = sqlSessionFactoryopenSession();

try {

// 获取 MappedStatement 对象

MappedStatement mappedStatement = sqlSessiongetConfiguration()getMappedStatement("comexamplemapperselectUser");

// 获取 BoundSql 对象

BoundSql boundSql = mappedStatementgetBoundSql(paramObject);

// 获取 SQL 语句字符串

String sql = boundSqlgetSql();

// 对 SQL 语句进行相应的 *** 作

//

} finally {

sqlSessionclose();

}

需要注意的是,在使用反射获取 SQL 语句时,要注意保护用户隐私和安全,以免发生 SQL 注入等问题。

实体类如下:

表结构如下:

其中varId为主键,但非自增

插入时,如何查询当前最大id,并赋值给实体类,示例如下:

插入前,首先查询当前最大的id,并赋值给实体对象

如下:

插入时,获取当前最大值,插入

插入后,查询当前最大的id,并赋值给实体对象。

如下:

Mybatis的四大对象

Executor

ParameterHandler

ResultSetHandler

StatementHandler

一个MappedStatement代表一个增删改查的详细信息

Configuration包含全局配置,所有映射文件信息,接口信息

MappedStatement:一个sql对应一个MappedStatement

MapperProxyFactory:生成MapperProxy实例

Executor:执行增删改查,其中调用StatementHandler处理

原理分析

1、获取SqlSessionFactory对象

把配置文件的信息解析并保存在Configuration对象中(包含所有的映射文件信息、接口信息等),返回包含了Configuration的DefaultSqlSession对象

SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()build(inputStream);

2、获取SqlSession

返回SqlSession的实现类Default对象,包含了Executor和Configuration;会有拦截器链(interceptChainpluginAll(executor))对Executor进行插入修饰。

3、getMapper

getMapper使用MapperProxyFactory创建一个MapperProxy的代理对象,包含了DefaultSqlSession(Executor)

4、执行方法

创建MapperMethodInvoker(接口,有invoke方法),PlainMethodInvoker写入本次方法查询相关信息(MapperMethod),MapperMethod包括SqlCommand和MethodSignature。调用MapperMethodInvokerinvoke方法执行 *** 作=>PlainMethodInvoker中调用MapperMethodexcute方法。MapperMethodexcute是真正执行方法。调用MapperStatment

通过调用代理类执行方法,创建StatementHandler(ParameterHandler,ResultSetHandler)处理器对象,使用处理器调用底层JDBC执行SQL返回结果。

总结:

责任链模式+动态代理+反射机制

插件编写

>

以上就是关于mybatis查找typeHandler过程分析全部的内容,包括:mybatis查找typeHandler过程分析、java通过反射拿到mybatis中的sql语句并 *** 作怎么用什么时候用、mybatis通过selectkey返回insert或update后的值等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://www.54852.com/web/9453021.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-28
下一篇2023-04-28

发表评论

登录后才能评论

评论列表(0条)

    保存