首页 >> 金融 >> java指导Mybatis动态Sql处理解析

java指导Mybatis动态Sql处理解析

2023-02-27 金融

tChildNodes();

for (int i = 0; i

XNode child = node.newXNode(children.item(i));

//辨别侄类型或表征中不会的自然语言概要 || 侄类型元数据中不会的 CDATA 部(不不会由解器解的自然语言)

if (child.getNode().getNodeType() == Node.CDATA_SECTION_NODE || child.getNode().getNodeType() == Node.TEXT_NODE) {

String data = child.getStringBody("");

//解data

TextSqlNode textSqlNode = new TextSqlNode(data);

//辨别局限性的Sql原作者是否为快照原作者

if (textSqlNode.isDynamic()) {

contents.add(textSqlNode);

isDynamic = true;

} else {

contents.add(new StaticTextSqlNode(data));

}

//如果侄类型为代表类型,则无需解侄类型

} else if (child.getNode().getNodeType() == Node.ELEMENT_NODE) { // issue #628

//换取类型的名字

String nodeName = child.getNode().getNodeName();

//根据类型名换取到类型链表的处理操作过程器,Mybatis备有了8中不会类型处理操作过程器,ChooseHandler、IfHandler、OtherwiseHandler

//TrimHandler、BindHandler、WhereHandler、SetHandler、ForEachHandler。博文不会给大家统计分析下IfHandler

NodeHandler handler = nodeHandlerMap.get(nodeName);

if (handler == null) {

throw new BuilderException("Unknown element in SQL statement.");

}

//函数调至用近似于的handler同步进行链表处理操作过程,运算符函数调至用就在这块

handler.handleNode(child, contents);

isDynamic = true;

}

}

//创建MixedSqlNode

return new MixedSqlNode(contents);

}

// 上头我们看下IfHandler是如何处理操作过程,IfHandler是XMLScriptBuilder的内部类

private class IfHandler implements NodeHandler {

public IfHandler() {

// Prevent Synthetic Access

}

//我们着重统计分析这个原理

@Override

public void handleNode(XNode nodeToHandle, List targetContents) {

//函数调至用parseDynamicTags同步进行链表解。这里就是运算符,又函数调至用了上头的原理。

MixedSqlNode mixedSqlNode = parseDynamicTags(nodeToHandle);

//换取if近似于的赋值

String test = nodeToHandle.getStringAttribute("test");

//创建IfSqlNode

IfSqlNode ifSqlNode = new IfSqlNode(mixedSqlNode, test);

targetContents.add(ifSqlNode);

}

}

上头我们根据Sql原作者和指派结果来统计分析。

// 快照Sql原作者和链表的快照Sql原作者

select * from user where id> #{ user.id}

AND name = #{ user.name}

AND name = #{ user.name}

AND name = #{ user.name}

上头我们统计分析下指派结果:

上头运算符结果已经用不通颜色上面了,大家自己看下。特别无需看下IfSqlNode的表征。

快照Sql解

快照Sql解主要是指派数据库操作的时候把快照Sql转换再加JDBC能辨认的Sql原作者。【关注尚硅谷,得心应手学IT】Mybatis中不会主要是通过SqlSource来解Sql原作者,替换再加JDBC能辨认的Sql原作者。我们先看下类图。

SqlSource:备有了Sql解的不道德。

RawSqlSource:快照Sql原作者的编译,只生再加一次StaticSqlSource。

DynamicSqlSource:每次函数调至用都不会生再加StaticSqlSource。每次函数调至用传入模板意味著不一样。无需每次生再加StaticSqlSource。

ProviderSqlSource:第三方原作者语法的集再加。

FreeMarkerSqlSource:对FreeMarker的赞成。

StaticSqlSource:StaticSqlSource只是对上头4中不会类别认真了层PCB。博文从未这个类不会更加宁静些。

我们这次主要对StaticSqlSource、RawSqlSource、和DynamicSqlSource同步进行统计分析。

StaticSqlSource

毕竟StaticSqlSource就是对其他几种类别Sql处理操作过程器结果同步进行纸盒。我们看下GCC。

//我们主要统计分析下getBoundSql

public class StaticSqlSource implements SqlSource {

private final String sql;

private final List parameterMappings;

private final Configuration configuration;

public StaticSqlSource(Configuration configuration, String sql) {

this(configuration, sql, null);

}

public StaticSqlSource(Configuration configuration, String sql, List parameterMappings) {

this.sql = sql;

this.parameterMappings = parameterMappings;

this.configuration = configuration;

}

//getBoundSql就是创建一个BoundSql实例。

@Override

public BoundSql getBoundSql(Object parameterObject) {

return new BoundSql(configuration, sql, parameterMappings, parameterObject);

}

}

看放是不是非常恰当,毕竟有些编码确实从未我们想象中不会那么自知。

RawSqlSource

// 我们着重统计分析RawSqlSource原理

public class RawSqlSource implements SqlSource {

private final SqlSource sqlSource;

public RawSqlSource(Configuration configuration, SqlNode rootSqlNode, Class parameterType) {

this(configuration, getSql(configuration, rootSqlNode), parameterType);

}

//这里意味着了对快照原作者的解,乃是的快照原作者解就是把 #{}解再加?快照Sql解是在解Mapper.xml的时候指派的

public RawSqlSource(Configuration configuration, String sql, Class parameterType) {

SqlSourceBuilder sqlSourceParser = new SqlSourceBuilder(configuration);

Class clazz = parameterType == null ? Object.class : parameterType;

//通过函数调至用SqlSourceBuilder的parse原理来解Sql

sqlSource = sqlSourceParser.parse(sql, clazz, new HashMap());

}

private static String getSql(Configuration configuration, SqlNode rootSqlNode) {

DynamicContext context = new DynamicContext(configuration, null);

rootSqlNode.apply(context);

return context.getSql();

}

@Override

public BoundSql getBoundSql(Object parameterObject) {

return sqlSource.getBoundSql(parameterObject);

}

}

上头我们来看下SqlSourceBuilder的parse原理

public SqlSource parse(String originalSql, Class parameterType, Map additionalParameters) {

ParameterMappingTokenHandler handler = new ParameterMappingTokenHandler(configuration, parameterType, additionalParameters);

//寻觅Sql原作者中不会#{}上面的原作者用?号同步进行替代。GenericTokenParser里头编码来得复杂,博文也从未分析。

//很感兴趣自己可以分析下。

GenericTokenParser parser = new GenericTokenParser("#{", "}", handler);

String sql = parser.parse(originalSql);

return new StaticSqlSource(configuration, sql, handler.getParameterMappings());

}

DynamicSqlSource

快照Sql解主要由DynamicSqlSource来放再加。这里头又是通过运算符调至同步进行sql解。我们还是依循上头的Sql给大家说什么解。

public class DynamicSqlSource implements SqlSource {

private final Configuration configuration;

private final SqlNode rootSqlNode;

public DynamicSqlSource(Configuration configuration, SqlNode rootSqlNode) {

this.configuration = configuration;

this.rootSqlNode = rootSqlNode;

}

@Override

public BoundSql getBoundSql(Object parameterObject) {

//快照Sql解表达式

DynamicContext context = new DynamicContext(configuration, parameterObject);

//rootSqlNode就是我们前面说什么解的,把快照Sql解再加SqlNode实例。表面为MixedSqlNode链表,链表唯储了

//链表下的所有侄链表。里头运算符函数调至用并根据传入模板的表征核对是否无需拼南和sql

rootSqlNode.apply(context);

//这块编码和上头快照Sql南和编码相反。

SqlSourceBuilder sqlSourceParser = new SqlSourceBuilder(configuration);

Class parameterType = parameterObject == null ? Object.class : parameterObject.getClass();

//把我们快照Sql中不会的#{}替换再加?

SqlSource sqlSource = sqlSourceParser.parse(context.getSql(), parameterType, context.getBindings());

BoundSql boundSql = sqlSource.getBoundSql(parameterObject);

for (Map.Entry entry : context.getBindings().entrySet()) {

boundSql.setAdditionalParameter(entry.getKey(), entry.getValue());

}

return boundSql;

}

}

快照Sql解apply原理博文只根据场景介绍下MixedSqlNode和IfSqlNode的apply原理。其他很感兴趣自己去分析下。逻辑大体相反,意味着有些区别。

public class MixedSqlNode implements SqlNode {

private final List contents;

public MixedSqlNode(List contents) {

this.contents = contents;

}

//换取循环系统SqlNode沙罗的所有SqlNode,函数调至用apply原理根据传入模板和必需同步进行快照sql的拼南和。

//沙罗中不会的SqlNode意味著是一个恰当的SqlNode实例,也意味著是一个MixedSqlNode或者有更加多的链表。

//博文的例证就是3个链表If查询。根据博文的Sql原作者,这里实际上不会函数调至用IfSqlNode的apply原理。

//我们南和下来看下IfSqlNode是如何意味着的。

@Override

public boolean apply(DynamicContext context) {

for (SqlNode sqlNode : contents) {

sqlNode.apply(context);

}

return true;

}

}

IfSqlNode的apply

public class IfSqlNode implements SqlNode {

//ExpressionEvaluator不会函数调至用ognl来对赋值同步进行解

private final ExpressionEvaluator evaluator;

private final String test;

private final SqlNode contents;

public IfSqlNode(SqlNode contents, String test) {

this.test = test;

this.contents = contents;

this.evaluator = new ExpressionEvaluator();

}

@Override

public boolean apply(DynamicContext context) {

//context.getBindings()里头就唯储这立即模板,这里是一个HashMap,OGNl里头编码博文从未分析。

//如果必需if再加立,实际上换取contents中不会的SqlNode的apply原理同步进行快照原作者处理操作过程。

if (evaluator.evaluateBoolean(test, context.getBindings())) {

contents.apply(context);

return true;

}

return false;

}

}

这块编码很多运算符函数调至用,博文自认为说什么的不实在太透彻,所以大家看放务必自己去调至试下。

归纳

Mybatis快照Sql从解到指派分为2个操作过程上头对这个2个操作过程同步进行恰当归纳。

1.快照Sql生再加SqlNode信息,这个操作过程发生在对select、update等Sql操作符解操作过程。如果是快照Sql实际上不会把#{}替换再加?。

2.快照Sql解在换取BoundSql时候触发。不会函数调至用SqlNode的apply同步进行Sql解再加快照Sql,然后把#{}替换再加?,并绑定ParameterMapping射影。

录用读物:

MyBatis在实践中不会配置档案

Java研发基本概念之Mybatis入门基础性

java研发SSM基本概念构建之MyBatis快照SQL

广州精神病专科医院哪家好
重庆白癜风专科医院哪里好
山东妇科医院挂号咨询
天津妇科医院哪家好
职场双减cp英太青x7分甜甩痛舞
TAG:动态
友情链接