mybatis关于ORM的使用以及设计(三)[参数对象转换为SQL语言]
上节分析了Mapper对象的创建。 在ORM的定义中可以理解为Object->SQLMapper抽象层(这一层并不负责具体的SQL执行。这一层可以理解为SQL代理层) 本节分析以下内容: ①SqlSession在具体执行SQL时,如果通过namespace+sqlid定位到具体的MappedStatement(sql的对象化表现形式) ②参数(Object) 如何填充到具体的SQL ③SQL是如何执行的
? StrictMap是Mybatis实现HashMap子类。Key重复放入的时候会报错。 ? ? ??
1、通过Executor执行SQL 2、Executor是如何获取的? SqlSessionFactory工厂中代码如下: 从Configuration中获得Excecutor,默认的执行器类型为configuration.getDefaultExecutorType()在configuration类中定义为 protected ExecutorType defaultExecutorType = ExecutorType.SIMPLE; SqlSession openSessionFromDataSource(ExecutorType execType,TransactionIsolationLevel level,= Environment environment = TransactionFactory transactionFactory == Executor executor =
ExceptionFactory.wrapException("Error opening session. Cause: " +
ExecutorType.SIMPLE会创建何种执行器? 来看Configuraiton的获得执行器的方法 默认的执行器为:SimpleExecutor,而cacheEnabled默认值为true.所以实际是CachingExecutor,使用了装饰器模式。 = executorType == ?= executorType == ? (ExecutorType.BATCH === BatchExecutor( (ExecutorType.REUSE === ReuseExecutor(executor = SimpleExecutor(,transaction);
}
cacheEnabled) {
executor = CachingExecutor(executor);
}
executor =
先看下MappedStatement中的类成员构成。sqlSource是具体获取待执行SQL的对象。
BoundSql getBoundSql(Object parameterObject)的方法,改方调用实际的SqlSource的实现类,来获取真正执行的SQL
先说说几个处理类的区别: DynamicSqlSource:sql中包含 看一段代码,我们关注rootSqlNode变量,以及getBoundSql()方法的执行。
DynamicSqlSource <span style="color: #0000ff">private <span style="color: #0000ff">final<span style="color: #000000"> Configuration configuration;
<span style="color: #0000ff">private <span style="color: #0000ff">final<span style="color: #000000"> SqlNode rootSqlNode; <span style="color: #0000ff">public<span style="color: #000000"> DynamicSqlSource(Configuration configuration,SqlNode rootSqlNode) { @Override 解析过程描述: ①rootSqlNode为从XML解析的具体SQL节点,每一行作为一个node。对于 ②
看一段IfSqlNode的代码:apply方法中的evaluateBoolean方法,将对
IfSqlNode <span style="color: #0000ff">public<span style="color: #000000"> IfSqlNode(SqlNode contents,String test) {
<span style="color: #0000ff">this.test =<span style="color: #000000"> test; <span style="color: #0000ff">this.contents =<span style="color: #000000"> contents; <span style="color: #0000ff">this.evaluator = <span style="color: #0000ff">new<span style="color: #000000"> ExpressionEvaluator(); } @Override <span style="color: #0000ff">if<span style="color: #000000"> (evaluator.evaluateBoolean(test,context.getBindings())) { contents.apply(context); <span style="color: #0000ff">return <span style="color: #0000ff">true<span style="color: #000000">; } <span style="color: #0000ff">return <span style="color: #0000ff">false<span style="color: #000000">; } } mybatis中定义的SQL节点如下。
RawSqlSource:对于不包含 DynamicSqlSource: 对sql中包含${}参数的会转换为该对象
SimpleExecutor中,创建PrepareStateMent的过程。
Statement prepareStatement(StatementHandler handler,Log statementLog) == handler.prepare(connection,transaction.getTimeout()); //设置参数
handler.parameterize(stmt);
离我们想知道的真相越来越近了,来看具体的参数化过程 StateMentHandler.parameterize RoutingStatementHandler用来做路由器:根据实际的StatementType做路由 我们来看PreparedStatementHadler parameterize(Statement statement)
?List
</span><span style="color: #0000ff">try</span><span style="color: #000000"> {
<strong>typeHandler</strong>.setParameter(ps,i </span>+ 1<span style="color: #000000">,value,jdbcType);
} </span><span style="color: #0000ff">catch</span><span style="color: #000000"> (TypeException var10) {
</span><span style="color: #0000ff">throw</span> <span style="color: #0000ff">new</span> TypeException("Could not set parameters for mapping: " + parameterMapping + ". Cause: " +<span style="color: #000000"> var10,var10);
} </span><span style="color: #0000ff">catch</span><span style="color: #000000"> (SQLException var11) {
</span><span style="color: #0000ff">throw</span> <span style="color: #0000ff">new</span> TypeException("Could not set parameters for mapping: " + parameterMapping + ". Cause: " +<span style="color: #000000"> var11,var11);
}
}
}
}
}</span></em></em></em></em></em></em></em></em></pre>
TypeHandler的继承关系如下:
?? 我们查看其中的BigDecimalTypeHandler的源码
BigDecimalTypeHandler BaseTypeHandler
<span style="color: #0000ff">public <span style="color: #0000ff">throws<span style="color: #000000"> SQLException { ps.setBigDecimal(i,parameter); } @Override @Override @Override 会调用JDBCAPI中的相应方法获得正确的值
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |