diff --git a/CHANGES.md b/CHANGES.md
index e80cf25ef7b8373121e0fbb25e015c3886abc49c..771bd578d0887cf3e322cce0da314a171ecd7cf0 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -18,6 +18,7 @@ Release Notes.
* Extended Kafka plugin to properly trace consumers that have topic partitions directly assigned.
* Support print SkyWalking context to logs.
* Add `MessageListener` enhancement in pulsar plugin
+* Add an optional agent plugin to support mybatis.
#### OAP-Backend
* BugFix: filter invalid Envoy access logs whose socket address is empty.
diff --git a/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java b/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java
index 55c0de8b2113cb7f7ec8503183dbdb896eb67b2f..79dda4eb2b0e0b64ba47e47e14fbb15febdde34c 100755
--- a/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java
+++ b/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java
@@ -198,4 +198,6 @@ public class ComponentsDefine {
public static final OfficialComponent JSON_RPC = new OfficialComponent(107, "JsonRpc");
public static final OfficialComponent SEATA = new OfficialComponent(108, "Seata");
+
+ public static final OfficialComponent MYBATIS = new OfficialComponent(109, "MyBatis");
}
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/tag/Tags.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/tag/Tags.java
index a95d4dbf6b97cd5d835365d42456bcc128db0ea7..f911d0663ef78a5b0ebde70b7b963615000f69a7 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/tag/Tags.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/tag/Tags.java
@@ -82,6 +82,8 @@ public final class Tags {
*/
public static final StringTag MQ_STATUS = new StringTag(16, "mq_status");
+ public static final StringTag MYBATIS_MAPPER = new StringTag(17, "mybatis.mapper");
+
/**
* The latency of transmission. When there are more than one downstream parent/segment-ref(s), multiple tags will be
* recorded, such as a batch consumption in MQ.
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/AbstractSpan.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/AbstractSpan.java
index 91a8c79432f6bca45ad5e5891a8f33384280abf6..206636825e0b059fab68caaefe86b49fc07f905b 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/AbstractSpan.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/AbstractSpan.java
@@ -104,6 +104,8 @@ public interface AbstractSpan extends AsyncSpan {
String getOperationName();
+ int getComponentId();
+
/**
* Reference other trace segment.
*
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/AbstractTracingSpan.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/AbstractTracingSpan.java
index 0fad5e82c1ce197eec9aa3f160d5f74a2932516c..62fe90d16eb6f2d0308b4c70838c230cab13978a 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/AbstractTracingSpan.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/AbstractTracingSpan.java
@@ -232,6 +232,11 @@ public abstract class AbstractTracingSpan implements AbstractSpan {
return operationName;
}
+ @Override
+ public int getComponentId() {
+ return componentId;
+ }
+
@Override
public AbstractTracingSpan setLayer(SpanLayer layer) {
this.layer = layer;
diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/NoopSpan.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/NoopSpan.java
index c67148abeaa394a554e9dbb6c2fe66bbf8e7ffb7..1b5964cd4bae1df5a5046a9f7f8d3ae60e23ff21 100644
--- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/NoopSpan.java
+++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/context/trace/NoopSpan.java
@@ -100,6 +100,11 @@ public class NoopSpan implements AbstractSpan {
return "";
}
+ @Override
+ public int getComponentId() {
+ return 0;
+ }
+
@Override
public void ref(TraceSegmentRef ref) {
}
diff --git a/apm-sniffer/optional-plugins/mybatis-3.x-plugin/pom.xml b/apm-sniffer/optional-plugins/mybatis-3.x-plugin/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..973593f20b537ba7404f3a83a4f85f2b7b1970ae
--- /dev/null
+++ b/apm-sniffer/optional-plugins/mybatis-3.x-plugin/pom.xml
@@ -0,0 +1,44 @@
+
+
+
+
+ 4.0.0
+
+ org.apache.skywalking
+ optional-plugins
+ 8.6.0-SNAPSHOT
+
+
+ apm-mybatis-3.x-plugin
+ jar
+ mybatis-3.x-plugin
+
+
+ 3.4.6
+
+
+
+
+ org.mybatis
+ mybatis
+ ${mybatis.version}
+ provided
+
+
+
\ No newline at end of file
diff --git a/apm-sniffer/optional-plugins/mybatis-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/mybatis/MyBatisMethodMatch.java b/apm-sniffer/optional-plugins/mybatis-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/mybatis/MyBatisMethodMatch.java
new file mode 100644
index 0000000000000000000000000000000000000000..6ac1153636ad226c23fdc188a6e016e0fe2a2647
--- /dev/null
+++ b/apm-sniffer/optional-plugins/mybatis-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/mybatis/MyBatisMethodMatch.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.apm.plugin.mybatis;
+
+import net.bytebuddy.description.method.MethodDescription;
+import net.bytebuddy.matcher.ElementMatcher;
+
+import static net.bytebuddy.matcher.ElementMatchers.named;
+
+public enum MyBatisMethodMatch {
+ INSTANCE;
+
+ public ElementMatcher getMyBatisMethodMatcher() {
+ return named("selectOne").or(named("selectList"))
+ .or(named("selectMap"))
+ .or(named("select"))
+ .or(named("insert"))
+ .or(named("update"))
+ .or(named("delete"));
+ }
+}
diff --git a/apm-sniffer/optional-plugins/mybatis-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/mybatis/SqlSessionOperationInterceptor.java b/apm-sniffer/optional-plugins/mybatis-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/mybatis/SqlSessionOperationInterceptor.java
new file mode 100644
index 0000000000000000000000000000000000000000..88033eff6370003f4d3add0058f37cac1fdb4836
--- /dev/null
+++ b/apm-sniffer/optional-plugins/mybatis-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/mybatis/SqlSessionOperationInterceptor.java
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.apm.plugin.mybatis;
+
+import java.lang.reflect.Method;
+import org.apache.skywalking.apm.agent.core.context.ContextManager;
+import org.apache.skywalking.apm.agent.core.context.tag.Tags;
+import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult;
+import org.apache.skywalking.apm.agent.core.util.MethodUtil;
+import org.apache.skywalking.apm.network.trace.component.ComponentsDefine;
+
+public class SqlSessionOperationInterceptor implements InstanceMethodsAroundInterceptor {
+
+ public static final String MYBATIS_ENTRY_METHOD_NAME = "mybatis_entry_method_name";
+
+ @Override
+ public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class>[] argumentsTypes,
+ MethodInterceptResult result) throws Throwable {
+ String operationName = MethodUtil.generateOperationName(method);
+ AbstractSpan lastSpan = null;
+ if (ContextManager.isActive()) {
+ lastSpan = ContextManager.activeSpan();
+ }
+ if (lastSpan == null || lastSpan.getComponentId() != ComponentsDefine.MYBATIS.getId()) {
+ AbstractSpan span = ContextManager.createLocalSpan(operationName);
+ span.setComponent(ComponentsDefine.MYBATIS);
+ if (allArguments != null && allArguments.length != 0) {
+ Tags.MYBATIS_MAPPER.set(span, (String) allArguments[0]);
+ }
+ ContextManager.getRuntimeContext().put(MYBATIS_ENTRY_METHOD_NAME, operationName);
+ }
+ }
+
+ @Override
+ public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class>[] argumentsTypes,
+ Object ret) throws Throwable {
+ String operationName = MethodUtil.generateOperationName(method);
+ if (String.valueOf(ContextManager.getRuntimeContext().get(MYBATIS_ENTRY_METHOD_NAME)).equals(operationName)) {
+ ContextManager.getRuntimeContext().remove(MYBATIS_ENTRY_METHOD_NAME);
+ ContextManager.stopSpan();
+ }
+ return ret;
+ }
+
+ @Override
+ public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
+ Class>[] argumentsTypes, Throwable t) {
+ String operationName = MethodUtil.generateOperationName(method);
+ if (String.valueOf(ContextManager.getRuntimeContext().get(MYBATIS_ENTRY_METHOD_NAME)).equals(operationName)) {
+ ContextManager.activeSpan().log(t);
+ }
+ }
+}
diff --git a/apm-sniffer/optional-plugins/mybatis-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/mybatis/define/MyBatisInstrumentation.java b/apm-sniffer/optional-plugins/mybatis-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/mybatis/define/MyBatisInstrumentation.java
new file mode 100644
index 0000000000000000000000000000000000000000..cbf639eb2e78fcb4ae59055f88585096aa4888c5
--- /dev/null
+++ b/apm-sniffer/optional-plugins/mybatis-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/mybatis/define/MyBatisInstrumentation.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.apm.plugin.mybatis.define;
+
+import net.bytebuddy.description.method.MethodDescription;
+import net.bytebuddy.matcher.ElementMatcher;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
+import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
+import org.apache.skywalking.apm.plugin.mybatis.MyBatisMethodMatch;
+
+import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
+
+public class MyBatisInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
+
+ @Override
+ public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
+ return new ConstructorInterceptPoint[0];
+ }
+
+ @Override
+ public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
+ return new InstanceMethodsInterceptPoint[] {
+ new InstanceMethodsInterceptPoint() {
+ @Override
+ public ElementMatcher getMethodsMatcher() {
+ return MyBatisMethodMatch.INSTANCE.getMyBatisMethodMatcher();
+ }
+
+ @Override
+ public String getMethodsInterceptor() {
+ return "org.apache.skywalking.apm.plugin.mybatis.SqlSessionOperationInterceptor";
+ }
+
+ @Override
+ public boolean isOverrideArgs() {
+ return false;
+ }
+ }
+ };
+ }
+
+ @Override
+ public ClassMatch enhanceClass() {
+ return byName("org.apache.ibatis.session.defaults.DefaultSqlSession");
+ }
+}
diff --git a/apm-sniffer/optional-plugins/mybatis-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/mybatis/define/MyBatisSpringInstrumentation.java b/apm-sniffer/optional-plugins/mybatis-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/mybatis/define/MyBatisSpringInstrumentation.java
new file mode 100644
index 0000000000000000000000000000000000000000..f3337d4cc1a56fd4db787f102a275e60444bc270
--- /dev/null
+++ b/apm-sniffer/optional-plugins/mybatis-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/mybatis/define/MyBatisSpringInstrumentation.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.apache.skywalking.apm.plugin.mybatis.define;
+
+import net.bytebuddy.description.method.MethodDescription;
+import net.bytebuddy.matcher.ElementMatcher;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint;
+import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine;
+import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch;
+import org.apache.skywalking.apm.plugin.mybatis.MyBatisMethodMatch;
+
+import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName;
+
+public class MyBatisSpringInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {
+
+ @Override
+ public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
+ return new ConstructorInterceptPoint[0];
+ }
+
+ @Override
+ public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
+ return new InstanceMethodsInterceptPoint[] {
+ new InstanceMethodsInterceptPoint() {
+ @Override
+ public ElementMatcher getMethodsMatcher() {
+ return MyBatisMethodMatch.INSTANCE.getMyBatisMethodMatcher();
+ }
+
+ @Override
+ public String getMethodsInterceptor() {
+ return "org.apache.skywalking.apm.plugin.mybatis.SqlSessionOperationInterceptor";
+ }
+
+ @Override
+ public boolean isOverrideArgs() {
+ return false;
+ }
+ }
+ };
+ }
+
+ @Override
+ public ClassMatch enhanceClass() {
+ return byName("org.mybatis.spring.SqlSessionTemplate");
+ }
+}
diff --git a/apm-sniffer/optional-plugins/mybatis-3.x-plugin/src/main/resources/skywalking-plugin.def b/apm-sniffer/optional-plugins/mybatis-3.x-plugin/src/main/resources/skywalking-plugin.def
new file mode 100644
index 0000000000000000000000000000000000000000..b84e04959d469b355b0f7249b94ce8b6919912e1
--- /dev/null
+++ b/apm-sniffer/optional-plugins/mybatis-3.x-plugin/src/main/resources/skywalking-plugin.def
@@ -0,0 +1,18 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+mybatis-3.x=org.apache.skywalking.apm.plugin.mybatis.define.MyBatisInstrumentation
+mybatis-3.x=org.apache.skywalking.apm.plugin.mybatis.define.MyBatisSpringInstrumentation
\ No newline at end of file
diff --git a/apm-sniffer/optional-plugins/pom.xml b/apm-sniffer/optional-plugins/pom.xml
index 59aeea9a37a7f251cd7de00705e556fe30284ad6..18e6b9467a77519fd4f9a68be02a24c3f8209819 100644
--- a/apm-sniffer/optional-plugins/pom.xml
+++ b/apm-sniffer/optional-plugins/pom.xml
@@ -49,6 +49,7 @@
customize-enhance-pluginkotlin-coroutine-pluginquartz-scheduler-2.x-plugin
+ mybatis-3.x-plugin
diff --git a/docs/en/setup/service-agent/java-agent/Plugin-list.md b/docs/en/setup/service-agent/java-agent/Plugin-list.md
index c082e232bcf4c67c88e1230cfa971df6f207d896..09c841ed31c32695212db89ee6f79d5b7582bff8 100644
--- a/docs/en/setup/service-agent/java-agent/Plugin-list.md
+++ b/docs/en/setup/service-agent/java-agent/Plugin-list.md
@@ -46,6 +46,7 @@
- mongodb-3.x
- mongodb-4.x
- motan-0.x
+- mybatis-3.x
- mysql-5.x
- mysql-6.x
- mysql-8.x
diff --git a/docs/en/setup/service-agent/java-agent/README.md b/docs/en/setup/service-agent/java-agent/README.md
index 6c96e249bf7013f6d5112a27800857915f7157c6..562ee7da0784f64839e1363b95a36bfed0116d32 100755
--- a/docs/en/setup/service-agent/java-agent/README.md
+++ b/docs/en/setup/service-agent/java-agent/README.md
@@ -190,6 +190,7 @@ Now, we have the following known optional plugins.
* [Plugin of Kotlin coroutine](agent-optional-plugins/Kotlin-Coroutine-plugin.md) provides the tracing across coroutines automatically. As it will add local spans to all across routines scenarios, Please assess the performance impact.
* Plugin of quartz-scheduler-2.x in the optional plugin folder. The reason for being an optional plugin is, many task scheduling systems are based on quartz-scheduler, this will cause duplicate tracing and link different sub-tasks as they share the same quartz level trigger, such as ElasticJob.
* Plugin of spring-webflux-5.x in the optional plugin folder. Please only activate this plugin when you use webflux alone as a web container. If you are using SpringMVC 5 or Spring Gateway, you don't need this plugin.
+* Plugin of mybatis-3.x in optional plugin folder. The reason of being optional plugin is, many local span are generated, which also spend more CPU, memory and network.
## Bootstrap class plugins
All bootstrap plugins are optional, due to unexpected risk. Bootstrap plugins are provided in `bootstrap-plugins` folder.
diff --git a/docs/en/setup/service-agent/java-agent/Supported-list.md b/docs/en/setup/service-agent/java-agent/Supported-list.md
index 1c47b4052011c43907832e1b47681135967e76cc..c8d957cced205764cb758675a246f0d49235c41b 100644
--- a/docs/en/setup/service-agent/java-agent/Supported-list.md
+++ b/docs/en/setup/service-agent/java-agent/Supported-list.md
@@ -123,6 +123,8 @@ metrics based on the tracing data.
* [log4j](https://github.com/apache/log4j) 2.x
* [log4j2](https://github.com/apache/logging-log4j2) 1.2.x
* [logback](https://github.com/qos-ch/logback) 1.2.x
+* ORM
+ * [MyBatis](https://github.com/mybatis/mybatis-3) 3.4.x -> 3.5.x
# Meter Plugins
The meter plugin provides the advanced metrics collections, which are not a part of tracing.
diff --git a/oap-server/server-bootstrap/src/main/resources/component-libraries.yml b/oap-server/server-bootstrap/src/main/resources/component-libraries.yml
index 6c0aef64039881d3d0cc41b22419688ef17560bd..ddcd3e9aed89c8af575003eb1cab9e7ca71a9bc3 100755
--- a/oap-server/server-bootstrap/src/main/resources/component-libraries.yml
+++ b/oap-server/server-bootstrap/src/main/resources/component-libraries.yml
@@ -356,6 +356,9 @@ JsonRpc:
seata:
id: 108
languages: Java
+MyBatis:
+ id: 109
+ languages: Java
# .NET/.NET Core components
# [3000, 4000) for C#/.NET only
diff --git a/test/plugin/scenarios/mybatis-3.x-scenario/bin/startup.sh b/test/plugin/scenarios/mybatis-3.x-scenario/bin/startup.sh
new file mode 100644
index 0000000000000000000000000000000000000000..86c257d4603985d17209f412e8bcd5ccfe36eab0
--- /dev/null
+++ b/test/plugin/scenarios/mybatis-3.x-scenario/bin/startup.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+home="$(cd "$(dirname $0)"; pwd)"
+
+java -Dmysql.servers=${MYSQL_SERVERS} -jar ${agent_opts} ${home}/../libs/mybatis-3.x-scenario.jar &
\ No newline at end of file
diff --git a/test/plugin/scenarios/mybatis-3.x-scenario/config/expectedData.yaml b/test/plugin/scenarios/mybatis-3.x-scenario/config/expectedData.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..e242619539d0b2250d127aaa4783087fae3f9959
--- /dev/null
+++ b/test/plugin/scenarios/mybatis-3.x-scenario/config/expectedData.yaml
@@ -0,0 +1,128 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+segmentItems:
+- serviceName: mybatis-3.x-scenario
+ segmentSize: nq 0
+ segments:
+ - segmentId: not null
+ spans:
+ - operationName: Mysql/JDBI/PreparedStatement/execute
+ operationId: 0
+ parentSpanId: 1
+ spanId: 2
+ spanLayer: Database
+ startTime: not null
+ endTime: not null
+ componentId: 33
+ isError: false
+ spanType: Exit
+ peer: mysql:3306
+ skipAnalysis: 'false'
+ tags:
+ - {key: db.type, value: sql}
+ - {key: db.instance, value: ''}
+ - {key: db.statement, value: 'insert into test.table_demo (name) values (?)'}
+ - operationName: Mysql/JDBI/Connection/close
+ operationId: 0
+ parentSpanId: 1
+ spanId: 3
+ spanLayer: Database
+ startTime: not null
+ endTime: not null
+ componentId: 33
+ isError: false
+ spanType: Exit
+ peer: mysql:3306
+ skipAnalysis: 'false'
+ tags:
+ - {key: db.type, value: sql}
+ - {key: db.instance, value: ''}
+ - {key: db.statement, value: ''}
+ - operationName: org.mybatis.spring.SqlSessionTemplate.insert(java.lang.String,java.lang.Object)
+ operationId: 0
+ parentSpanId: 0
+ spanId: 1
+ spanLayer: Unknown
+ startTime: not null
+ endTime: not null
+ componentId: 109
+ isError: false
+ spanType: Local
+ peer: ''
+ skipAnalysis: 'false'
+ tags:
+ - {key: mybatis.mapper, value: test.apache.skywalking.apm.testcase.mybatis.mapper.DemoMapper.insert}
+ - operationName: Mysql/JDBI/PreparedStatement/execute
+ operationId: 0
+ parentSpanId: 4
+ spanId: 5
+ spanLayer: Database
+ startTime: not null
+ endTime: not null
+ componentId: 33
+ isError: false
+ spanType: Exit
+ peer: mysql:3306
+ skipAnalysis: 'false'
+ tags:
+ - {key: db.type, value: sql}
+ - {key: db.instance, value: ''}
+ - {key: db.statement, value: 'insert into test.table_demo (name) values (?)'}
+ - operationName: Mysql/JDBI/Connection/close
+ operationId: 0
+ parentSpanId: 4
+ spanId: 6
+ spanLayer: Database
+ startTime: not null
+ endTime: not null
+ componentId: 33
+ isError: false
+ spanType: Exit
+ peer: mysql:3306
+ skipAnalysis: 'false'
+ tags:
+ - {key: db.type, value: sql}
+ - {key: db.instance, value: ''}
+ - {key: db.statement, value: ''}
+ - operationName: org.mybatis.spring.SqlSessionTemplate.insert(java.lang.String,java.lang.Object)
+ operationId: 0
+ parentSpanId: 0
+ spanId: 4
+ spanLayer: Unknown
+ startTime: not null
+ endTime: not null
+ componentId: 109
+ isError: false
+ spanType: Local
+ peer: ''
+ skipAnalysis: 'false'
+ tags:
+ - {key: mybatis.mapper, value: test.apache.skywalking.apm.testcase.mybatis.mapper.DemoMapper.insert}
+ - operationName: /case/mybatis-case
+ operationId: 0
+ parentSpanId: -1
+ spanId: 0
+ spanLayer: Http
+ startTime: not null
+ endTime: not null
+ componentId: 14
+ isError: false
+ spanType: Entry
+ peer: ''
+ skipAnalysis: 'false'
+ tags:
+ - {key: url, value: 'http://localhost:8080/mybatis-3.x-scenario/case/mybatis-case'}
+ - {key: http.method, value: GET}
\ No newline at end of file
diff --git a/test/plugin/scenarios/mybatis-3.x-scenario/configuration.yml b/test/plugin/scenarios/mybatis-3.x-scenario/configuration.yml
new file mode 100644
index 0000000000000000000000000000000000000000..19a26f9aeb28a9c8acb5c5adeb68072184537eae
--- /dev/null
+++ b/test/plugin/scenarios/mybatis-3.x-scenario/configuration.yml
@@ -0,0 +1,33 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+type: jvm
+entryService: http://localhost:8080/mybatis-3.x-scenario/case/mybatis-case
+healthCheck: http://localhost:8080/mybatis-3.x-scenario/case/healthCheck
+startScript: ./bin/startup.sh
+runningMode: with_optional
+withPlugins: apm-mybatis-3.x-plugin-*.jar
+environment:
+ - MYSQL_SERVERS=mysql:3306
+ - MYSQL_DATABASE=test
+depends_on:
+ - mysql
+dependencies:
+ mysql:
+ image: mysql:5.6
+ hostname: mysql
+ environment:
+ - MYSQL_ROOT_PASSWORD=000000
diff --git a/test/plugin/scenarios/mybatis-3.x-scenario/pom.xml b/test/plugin/scenarios/mybatis-3.x-scenario/pom.xml
new file mode 100644
index 0000000000000000000000000000000000000000..2b92a70d71c06d5fe7bb87e4cb9c4c4974a747b3
--- /dev/null
+++ b/test/plugin/scenarios/mybatis-3.x-scenario/pom.xml
@@ -0,0 +1,125 @@
+
+
+
+ 4.0.0
+
+ org.apache.skywalking
+ mybatis-3.x-scenario
+ 5.0.0
+
+
+ UTF-8
+ 1.8
+ 3.4.6
+ ${test.framework.version}
+
+
+ skywalking-mybatis-3.x-scenario
+
+
+
+ org.springframework.boot
+ spring-boot-starter-web
+ 2.0.0.RELEASE
+
+
+ org.springframework.boot
+ spring-boot-starter-jdbc
+ 2.0.0.RELEASE
+
+
+ mysql
+ mysql-connector-java
+ 6.0.6
+
+
+ org.mybatis.spring.boot
+ mybatis-spring-boot-starter
+ 1.3.1
+
+
+ org.mybatis
+ mybatis
+
+
+
+
+ org.mybatis
+ mybatis
+ ${test.framework.version}
+
+
+
+
+ mybatis-3.x-scenario
+
+
+ org.springframework.boot
+ spring-boot-maven-plugin
+
+
+
+ repackage
+
+
+
+
+
+ maven-compiler-plugin
+
+
+ ${compiler.version}
+ ${project.build.sourceEncoding}
+
+
+
+ org.apache.maven.plugins
+ maven-assembly-plugin
+
+
+ assemble
+ package
+
+ single
+
+
+
+ src/main/assembly/assembly.xml
+
+ ./target/
+
+
+
+
+
+
+
+
+
+ spring-snapshots
+ https://repo.spring.io/snapshot
+
+
+ spring-milestones
+ https://repo.spring.io/milestone
+
+
+
diff --git a/test/plugin/scenarios/mybatis-3.x-scenario/src/main/assembly/assembly.xml b/test/plugin/scenarios/mybatis-3.x-scenario/src/main/assembly/assembly.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d1fa02566a43c63ce2375f315a625a07d21d32f0
--- /dev/null
+++ b/test/plugin/scenarios/mybatis-3.x-scenario/src/main/assembly/assembly.xml
@@ -0,0 +1,41 @@
+
+
+
+
+ zip
+
+
+
+
+ ./bin
+ 0775
+
+
+
+
+
+
+ ./libs
+ 0775
+
+
+
diff --git a/test/plugin/scenarios/mybatis-3.x-scenario/src/main/java/test/apache/skywalking/apm/testcase/mybatis/Application.java b/test/plugin/scenarios/mybatis-3.x-scenario/src/main/java/test/apache/skywalking/apm/testcase/mybatis/Application.java
new file mode 100644
index 0000000000000000000000000000000000000000..c6ce1aa5ebb210f28b30350995c0c6cb651d776d
--- /dev/null
+++ b/test/plugin/scenarios/mybatis-3.x-scenario/src/main/java/test/apache/skywalking/apm/testcase/mybatis/Application.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package test.apache.skywalking.apm.testcase.mybatis;
+
+import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+
+@SpringBootApplication
+@MapperScan("test.apache.skywalking.apm.testcase.mybatis.mapper")
+public class Application {
+
+ public static void main(String[] args) {
+ SpringApplication.run(Application.class, args);
+ }
+
+}
diff --git a/test/plugin/scenarios/mybatis-3.x-scenario/src/main/java/test/apache/skywalking/apm/testcase/mybatis/config/JdbcConfig.java b/test/plugin/scenarios/mybatis-3.x-scenario/src/main/java/test/apache/skywalking/apm/testcase/mybatis/config/JdbcConfig.java
new file mode 100644
index 0000000000000000000000000000000000000000..ae0357f501f458abfd45d92aed4c8f407e4ee515
--- /dev/null
+++ b/test/plugin/scenarios/mybatis-3.x-scenario/src/main/java/test/apache/skywalking/apm/testcase/mybatis/config/JdbcConfig.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package test.apache.skywalking.apm.testcase.mybatis.config;
+
+import javax.sql.DataSource;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.datasource.DriverManagerDataSource;
+
+@Configuration
+public class JdbcConfig {
+
+ @Value("${mysql.servers}")
+ private String url;
+
+ @Bean(name = "dataSource")
+ public DataSource createDataSource() {
+ DriverManagerDataSource dataSource = new DriverManagerDataSource();
+ dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
+ dataSource.setUrl("jdbc:mysql://" + url + "?useSSL=false");
+ dataSource.setUsername("root");
+ dataSource.setPassword("000000");
+ return dataSource;
+ }
+
+ @Bean(name = "jdbcTemplate")
+ public JdbcTemplate createJdbcTemplate(DataSource dataSource) {
+ return new JdbcTemplate(dataSource);
+ }
+
+}
diff --git a/test/plugin/scenarios/mybatis-3.x-scenario/src/main/java/test/apache/skywalking/apm/testcase/mybatis/controller/CaseController.java b/test/plugin/scenarios/mybatis-3.x-scenario/src/main/java/test/apache/skywalking/apm/testcase/mybatis/controller/CaseController.java
new file mode 100644
index 0000000000000000000000000000000000000000..8f2ff7ce00ea7f844ad8d9691f17ec635178fd20
--- /dev/null
+++ b/test/plugin/scenarios/mybatis-3.x-scenario/src/main/java/test/apache/skywalking/apm/testcase/mybatis/controller/CaseController.java
@@ -0,0 +1,64 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package test.apache.skywalking.apm.testcase.mybatis.controller;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.PropertySource;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.ResponseBody;
+import test.apache.skywalking.apm.testcase.mybatis.service.DemoService;
+
+@Controller
+@RequestMapping("/case")
+@PropertySource("classpath:application.properties")
+public class CaseController {
+
+ @Value("${mysql.servers}")
+ private String address;
+ @Autowired
+ private JdbcTemplate jdbcTemplate;
+
+ @Autowired
+ private DemoService demoService;
+
+ @RequestMapping("/mybatis-case")
+ @ResponseBody
+ public String mybatisCase() {
+ demoService.doBiz();
+ return "Success";
+ }
+
+ @RequestMapping("/healthCheck")
+ @ResponseBody
+ public String healthCheck() {
+ try {
+ jdbcTemplate.execute("create database if not exists test default charset = utf8");
+ jdbcTemplate.execute("" + "CREATE TABLE IF NOT EXISTS `test`.`table_demo` (\n" + " `id` bigint(20) NOT NULL AUTO_INCREMENT,\n" + " `name` varchar(60),\n" + " PRIMARY KEY (`id`)\n" + ") ENGINE=InnoDB");
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw e;
+ }
+ return "success";
+ }
+
+}
+
diff --git a/test/plugin/scenarios/mybatis-3.x-scenario/src/main/java/test/apache/skywalking/apm/testcase/mybatis/mapper/DemoMapper.java b/test/plugin/scenarios/mybatis-3.x-scenario/src/main/java/test/apache/skywalking/apm/testcase/mybatis/mapper/DemoMapper.java
new file mode 100644
index 0000000000000000000000000000000000000000..b637f41d1eea6d1463522c1453276a63f3c0cdca
--- /dev/null
+++ b/test/plugin/scenarios/mybatis-3.x-scenario/src/main/java/test/apache/skywalking/apm/testcase/mybatis/mapper/DemoMapper.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package test.apache.skywalking.apm.testcase.mybatis.mapper;
+
+import org.apache.ibatis.annotations.Param;
+
+public interface DemoMapper {
+
+ int insert(@Param("name") String name);
+
+}
diff --git a/test/plugin/scenarios/mybatis-3.x-scenario/src/main/java/test/apache/skywalking/apm/testcase/mybatis/service/DemoService.java b/test/plugin/scenarios/mybatis-3.x-scenario/src/main/java/test/apache/skywalking/apm/testcase/mybatis/service/DemoService.java
new file mode 100644
index 0000000000000000000000000000000000000000..9a78e31daeac4afa1cb03e7f75b6f99709610870
--- /dev/null
+++ b/test/plugin/scenarios/mybatis-3.x-scenario/src/main/java/test/apache/skywalking/apm/testcase/mybatis/service/DemoService.java
@@ -0,0 +1,25 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package test.apache.skywalking.apm.testcase.mybatis.service;
+
+public interface DemoService {
+
+ void doBiz();
+
+}
diff --git a/test/plugin/scenarios/mybatis-3.x-scenario/src/main/java/test/apache/skywalking/apm/testcase/mybatis/service/impl/DemoServiceImpl.java b/test/plugin/scenarios/mybatis-3.x-scenario/src/main/java/test/apache/skywalking/apm/testcase/mybatis/service/impl/DemoServiceImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..6face9064757e2ec24791e11889c3de3fe2b02af
--- /dev/null
+++ b/test/plugin/scenarios/mybatis-3.x-scenario/src/main/java/test/apache/skywalking/apm/testcase/mybatis/service/impl/DemoServiceImpl.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package test.apache.skywalking.apm.testcase.mybatis.service.impl;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import test.apache.skywalking.apm.testcase.mybatis.mapper.DemoMapper;
+import test.apache.skywalking.apm.testcase.mybatis.service.DemoService;
+
+@Service
+public class DemoServiceImpl implements DemoService {
+
+ @Autowired
+ private DemoMapper demoMapper;
+
+ @Override
+ public void doBiz() {
+ demoMapper.insert("1");
+ demoMapper.insert("2");
+ }
+}
diff --git a/test/plugin/scenarios/mybatis-3.x-scenario/src/main/resources/application.properties b/test/plugin/scenarios/mybatis-3.x-scenario/src/main/resources/application.properties
new file mode 100644
index 0000000000000000000000000000000000000000..5ba22e5aa13c28ea1998e1ef2cc655ad9d8cda11
--- /dev/null
+++ b/test/plugin/scenarios/mybatis-3.x-scenario/src/main/resources/application.properties
@@ -0,0 +1,27 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+#
+server.port=8080
+server.servlet.context-path=/mybatis-3.x-scenario
+mybatis.mapper-locations=classpath:mapper/*.xml
+
+spring.datasource.url=jdbc:mysql://localhost:3306/test?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=false
+spring.datasource.username=root
+spring.datasource.password=000000
+spring.datasource.driver-class-name=com.mysql.jdbc.Driver
+
+mysql.servers=localhost:3306
\ No newline at end of file
diff --git a/test/plugin/scenarios/mybatis-3.x-scenario/src/main/resources/mapper/DemoMapper.xml b/test/plugin/scenarios/mybatis-3.x-scenario/src/main/resources/mapper/DemoMapper.xml
new file mode 100755
index 0000000000000000000000000000000000000000..12310192976166ac15a80ed9e194cdffc1e5bcb5
--- /dev/null
+++ b/test/plugin/scenarios/mybatis-3.x-scenario/src/main/resources/mapper/DemoMapper.xml
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+ insert into test.table_demo (name) values (#{name})
+
+
+
\ No newline at end of file
diff --git a/test/plugin/scenarios/mybatis-3.x-scenario/support-version.list b/test/plugin/scenarios/mybatis-3.x-scenario/support-version.list
new file mode 100644
index 0000000000000000000000000000000000000000..2ba14d43e5d9592af6f92bdd2456a4d9df5bae26
--- /dev/null
+++ b/test/plugin/scenarios/mybatis-3.x-scenario/support-version.list
@@ -0,0 +1,18 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+3.5.6
+3.4.6
\ No newline at end of file