Fixed issues in the MySQL component where the executeBatch method could result in empty SQL statements . (#702)

diff --git a/CHANGES.md b/CHANGES.md
index f80f1f1..623b501 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -21,6 +21,7 @@
 * Fix the opentracing toolkit SPI config
 * Improve 4x performance of ContextManagerExtendService.createTraceContext()
 * Add a plugin that supports the Solon framework.
+* Fixed issues in the MySQL component where the executeBatch method could result in empty SQL statements .
 
 
 All issues and pull requests are [here](https://github.com/apache/skywalking/milestone/213?closed=1)
diff --git a/apm-sniffer/apm-sdk-plugin/mysql-common/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/StatementExecuteMethodsInterceptor.java b/apm-sniffer/apm-sdk-plugin/mysql-common/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/StatementExecuteMethodsInterceptor.java
index 8895e11..0c2f504 100644
--- a/apm-sniffer/apm-sdk-plugin/mysql-common/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/StatementExecuteMethodsInterceptor.java
+++ b/apm-sniffer/apm-sdk-plugin/mysql-common/src/main/java/org/apache/skywalking/apm/plugin/jdbc/mysql/StatementExecuteMethodsInterceptor.java
@@ -28,6 +28,7 @@
 import org.apache.skywalking.apm.plugin.jdbc.SqlBodyUtil;
 import org.apache.skywalking.apm.plugin.jdbc.define.StatementEnhanceInfos;
 import org.apache.skywalking.apm.plugin.jdbc.trace.ConnectionInfo;
+import org.apache.skywalking.apm.util.StringUtil;
 
 import java.lang.reflect.Method;
 
@@ -52,14 +53,17 @@
             Tags.DB_INSTANCE.set(span, connectInfo.getDatabaseName());
 
             /**
-             * The first argument of all intercept method in `com.mysql.jdbc.StatementImpl` class is SQL, except the
-             * `executeBatch` method that the jdbc plugin need to trace, because of this method argument size is zero.
+             * Except for the `executeBatch` method, the first parameter of all enhanced methods in `com.mysql.jdbc.StatementImpl` is the SQL statement.
+             * Therefore, executeBatch will attempt to obtain the SQL from `cacheObject`.
              */
             String sql = "";
             if (allArguments.length > 0) {
                 sql = (String) allArguments[0];
                 sql = SqlBodyUtil.limitSqlBodySize(sql);
+            } else if (StringUtil.isNotBlank(cacheObject.getSql())) {
+                sql = SqlBodyUtil.limitSqlBodySize(cacheObject.getSql());
             }
+
             Tags.DB_STATEMENT.set(span, sql);
             span.setComponent(connectInfo.getComponent());
 
diff --git a/apm-sniffer/apm-sdk-plugin/mysql-common/src/test/java/org/apache/skywalking/apm/plugin/jdbc/mysql/StatementExecuteMethodsInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/mysql-common/src/test/java/org/apache/skywalking/apm/plugin/jdbc/mysql/StatementExecuteMethodsInterceptorTest.java
index e3ceaa6..df2769b 100644
--- a/apm-sniffer/apm-sdk-plugin/mysql-common/src/test/java/org/apache/skywalking/apm/plugin/jdbc/mysql/StatementExecuteMethodsInterceptorTest.java
+++ b/apm-sniffer/apm-sdk-plugin/mysql-common/src/test/java/org/apache/skywalking/apm/plugin/jdbc/mysql/StatementExecuteMethodsInterceptorTest.java
@@ -72,7 +72,8 @@
         JDBCPluginConfig.Plugin.JDBC.SQL_BODY_MAX_LENGTH = 2048;
         serviceMethodInterceptor = new StatementExecuteMethodsInterceptor();
 
-        enhanceRequireCacheObject = new StatementEnhanceInfos(connectionInfo, "SELECT * FROM test", "CallableStatement");
+        enhanceRequireCacheObject = new StatementEnhanceInfos(connectionInfo, SQL, "CallableStatement");
+
         when(objectInstance.getSkyWalkingDynamicField()).thenReturn(enhanceRequireCacheObject);
         when(method.getName()).thenReturn("executeQuery");
         when(connectionInfo.getComponent()).thenReturn(ComponentsDefine.H2_JDBC_DRIVER);
@@ -82,6 +83,24 @@
     }
 
     @Test
+    public void testCreateDatabaseSpanWithNoMethodParamButWithCache() throws Throwable {
+        JDBCPluginConfig.Plugin.JDBC.SQL_BODY_MAX_LENGTH = 2048;
+
+        serviceMethodInterceptor.beforeMethod(objectInstance, method, new Object[0], null, null);
+        serviceMethodInterceptor.afterMethod(objectInstance, method, new Object[0], null, null);
+
+        assertThat(segmentStorage.getTraceSegments().size(), is(1));
+        TraceSegment segment = segmentStorage.getTraceSegments().get(0);
+        assertThat(SegmentHelper.getSpans(segment).size(), is(1));
+        AbstractTracingSpan span = SegmentHelper.getSpans(segment).get(0);
+        SpanAssert.assertLayer(span, SpanLayer.DB);
+        assertThat(span.getOperationName(), is("H2/JDBC/CallableStatement/executeQuery"));
+        SpanAssert.assertTag(span, 0, "H2");
+        SpanAssert.assertTag(span, 1, "test");
+        SpanAssert.assertTag(span, 2, SQL);
+    }
+
+    @Test
     public void testCreateDatabaseSpan() throws Throwable {
         JDBCPluginConfig.Plugin.JDBC.SQL_BODY_MAX_LENGTH = 2048;
         serviceMethodInterceptor.beforeMethod(objectInstance, method, new Object[] {"SELECT * FROM test"}, null, null);