This is an automated email from the ASF dual-hosted git repository.

panjuan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git


The following commit(s) were added to refs/heads/master by this push:
     new 16a9c3f  Shadow non-DML route (#12660)
16a9c3f is described below

commit 16a9c3f7f2046894b4eb6482694125990a5412a1
Author: gin <[email protected]>
AuthorDate: Thu Sep 23 20:03:03 2021 +0800

    Shadow non-DML route (#12660)
    
    * Refactor note shadow algorithm.
    
    * Add shadow non-DML statement routing engine.
    
    * Fix ut.
    
    * Add sql note case example.
    
    * Refactor future shadow spring boot mybatis example.
---
 .../example/core/api/entity/FutureShadowUser.java  |  91 ++++++++++++++++++
 .../repository/FutureShadowUserRepository.java}    |   8 +-
 .../MybatisFutureShadowUserRepository.java         |  82 ++++++++++++++++
 .../service/FutureShadowUserServiceImpl.java       |  94 +++++++++++++++++++
 .../META-INF/mappers/FutureShadowUserMapper.xml    |  68 ++++++++++++++
 .../mybatis/ShadowSpringBootMybatisExample.java    |  10 +-
 .../spring/boot/mybatis/domain/OrderInfo.java      |  40 --------
 .../boot/mybatis/repository/OrderMapper.java       |  25 -----
 .../mybatis/service/impl/OrderServiceImpl.java     |  56 -----------
 .../mybatis-config.xml}                            |  20 ++--
 .../application-shadow-databases.properties        |  26 ++++--
 ...pplication-shadow-sharding-databases.properties |  32 +++++--
 .../src/main/resources/application.properties      |   4 +-
 .../ShadowSpringNamespaceMybatisExample.java       |   1 +
 .../namespace/mybatis/service/SQLGenerator.java    |   9 ++
 .../namespace/mybatis/service/ShadowService.java   |   2 +
 .../mybatis/service/impl/ShadowServiceImpl.java    |   5 +
 .../META-INF/application-shadow-databases.xml      |   6 +-
 .../api/shadow/column/ShadowOperationType.java     |   7 +-
 .../api/shadow/note/PreciseNoteShadowValue.java    |   3 +
 .../shadow/note/NoteShadowAlgorithmUtil.java       |   6 +-
 .../shadow/note/SimpleSQLNoteShadowAlgorithm.java  |   3 +-
 .../future/engine/ShadowRouteEngineFactory.java    |   8 +-
 .../algorithm/NoteShadowAlgorithmDeterminer.java   |   4 +-
 .../AbstractShadowDMLStatementRouteEngine.java}    |   7 +-
 .../dml/ShadowDeleteStatementRoutingEngine.java    |   8 +-
 .../dml/ShadowInsertStatementRoutingEngine.java    |   8 +-
 .../dml/ShadowSelectStatementRoutingEngine.java    |   8 +-
 .../dml/ShadowUpdateStatementRoutingEngine.java    |   8 +-
 .../impl/ShadowNonDMLStatementRoutingEngine.java   | 103 +++++++++++++++++++++
 .../impl/ShadowNonMDLStatementRoutingEngine.java   |  33 -------
 .../shardingsphere/shadow/rule/ShadowRule.java     |  21 +++++
 .../note/SimpleSQLNoteShadowAlgorithmTest.java     |  13 +--
 .../NoteShadowAlgorithmDeterminerTest.java         |   4 +-
 .../ShadowInsertStatementRoutingEngineTest.java    |  21 +++--
 35 files changed, 605 insertions(+), 239 deletions(-)

diff --git 
a/examples/example-core/example-api/src/main/java/org/apache/shardingsphere/example/core/api/entity/FutureShadowUser.java
 
b/examples/example-core/example-api/src/main/java/org/apache/shardingsphere/example/core/api/entity/FutureShadowUser.java
new file mode 100644
index 0000000..459afd9
--- /dev/null
+++ 
b/examples/example-core/example-api/src/main/java/org/apache/shardingsphere/example/core/api/entity/FutureShadowUser.java
@@ -0,0 +1,91 @@
+/*
+ * 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.shardingsphere.example.core.api.entity;
+
+import java.io.Serializable;
+
+public class FutureShadowUser implements Serializable {
+    
+    private static final long serialVersionUID = -6711618386636677067L;
+    
+    private int userId;
+    
+    private int userType;
+    
+    private String userName;
+    
+    private String userNamePlain;
+    
+    private String pwd;
+    
+    private String assistedQueryPwd;
+    
+    public int getUserId() {
+        return userId;
+    }
+    
+    public void setUserId(int userId) {
+        this.userId = userId;
+    }
+    
+    public int getUserType() {
+        return userType;
+    }
+    
+    public void setUserType(int userType) {
+        this.userType = userType;
+    }
+    
+    public String getUserName() {
+        return userName;
+    }
+    
+    public void setUserName(String userName) {
+        this.userName = userName;
+    }
+    
+    public String getUserNamePlain() {
+        return userNamePlain;
+    }
+    
+    public void setUserNamePlain(String userNamePlain) {
+        this.userNamePlain = userNamePlain;
+    }
+    
+    public String getPwd() {
+        return pwd;
+    }
+    
+    public void setPwd(String pwd) {
+        this.pwd = pwd;
+    }
+    
+    public String getAssistedQueryPwd() {
+        return assistedQueryPwd;
+    }
+    
+    public void setAssistedQueryPwd(String assistedQueryPwd) {
+        this.assistedQueryPwd = assistedQueryPwd;
+    }
+    
+    @Override
+    public String toString() {
+        return String.format("user_id: %d, user_type: %d, user_name: %s, 
user_name_plain: %s, pwd: %s, assisted_query_pwd: %s", userId, userType, 
userName, userNamePlain, pwd,
+                assistedQueryPwd);
+    }
+}
diff --git 
a/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-boot-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/boot/mybatis/service/OrderService.java
 
b/examples/example-core/example-api/src/main/java/org/apache/shardingsphere/example/core/api/repository/FutureShadowUserRepository.java
similarity index 77%
rename from 
examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-boot-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/boot/mybatis/service/OrderService.java
rename to 
examples/example-core/example-api/src/main/java/org/apache/shardingsphere/example/core/api/repository/FutureShadowUserRepository.java
index 67c4ca0..7b079bd 100644
--- 
a/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-boot-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/boot/mybatis/service/OrderService.java
+++ 
b/examples/example-core/example-api/src/main/java/org/apache/shardingsphere/example/core/api/repository/FutureShadowUserRepository.java
@@ -15,9 +15,9 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.example.shadow.spring.boot.mybatis.service;
+package org.apache.shardingsphere.example.core.api.repository;
 
-public interface OrderService {
-    
-    void executeInsertCase();
+import org.apache.shardingsphere.example.core.api.entity.FutureShadowUser;
+
+public interface FutureShadowUserRepository extends 
CommonRepository<FutureShadowUser, Long> {
 }
diff --git 
a/examples/example-core/example-spring-mybatis/src/main/java/org/apache/shardingsphere/example/core/mybatis/repository/MybatisFutureShadowUserRepository.java
 
b/examples/example-core/example-spring-mybatis/src/main/java/org/apache/shardingsphere/example/core/mybatis/repository/MybatisFutureShadowUserRepository.java
new file mode 100644
index 0000000..9b647ac
--- /dev/null
+++ 
b/examples/example-core/example-spring-mybatis/src/main/java/org/apache/shardingsphere/example/core/mybatis/repository/MybatisFutureShadowUserRepository.java
@@ -0,0 +1,82 @@
+/*
+ * 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.shardingsphere.example.core.mybatis.repository;
+
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.shardingsphere.example.core.api.entity.FutureShadowUser;
+import 
org.apache.shardingsphere.example.core.api.repository.FutureShadowUserRepository;
+
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Mapper
+public interface MybatisFutureShadowUserRepository extends 
FutureShadowUserRepository {
+    
+    @Override
+    default void createTableIfNotExists() throws SQLException {
+        createTableIfNotExistsNative();
+        createTableIfNotExistsShadow();
+    }
+    
+    void createTableIfNotExistsNative();
+    
+    void createTableIfNotExistsShadow();
+    
+    @Override
+    default void truncateTable() throws SQLException {
+        truncateTableNative();
+        truncateTableShadow();
+    }
+    
+    void truncateTableNative();
+    
+    void truncateTableShadow();
+    
+    @Override
+    default void dropTable() throws SQLException {
+        dropTableNative();
+        dropTableShadow();
+    }
+    
+    void dropTableNative();
+    
+    void dropTableShadow();
+    
+    @Override
+    default List<FutureShadowUser> selectAll() throws SQLException {
+        List<FutureShadowUser> result = new ArrayList<>();
+        result.addAll(selectAllByShadow(0));
+        result.addAll(selectAllByShadow(1));
+        return result;
+    }
+    
+    List<FutureShadowUser> selectAllByShadow(int userType) throws SQLException;
+    
+    @Override
+    default void delete(Long primaryKey) throws SQLException {
+        Map<String, Long> idTypeMapping = new HashMap<>(2);
+        idTypeMapping.put("userId", primaryKey);
+        idTypeMapping.put("userType", primaryKey % 2);
+        deleteOne(idTypeMapping);
+    }
+    
+    void deleteOne(Map<String, Long> idTypeMapping);
+}
diff --git 
a/examples/example-core/example-spring-mybatis/src/main/java/org/apache/shardingsphere/example/core/mybatis/service/FutureShadowUserServiceImpl.java
 
b/examples/example-core/example-spring-mybatis/src/main/java/org/apache/shardingsphere/example/core/mybatis/service/FutureShadowUserServiceImpl.java
new file mode 100644
index 0000000..0588784
--- /dev/null
+++ 
b/examples/example-core/example-spring-mybatis/src/main/java/org/apache/shardingsphere/example/core/mybatis/service/FutureShadowUserServiceImpl.java
@@ -0,0 +1,94 @@
+/*
+ * 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.shardingsphere.example.core.mybatis.service;
+
+import org.apache.shardingsphere.example.core.api.entity.FutureShadowUser;
+import 
org.apache.shardingsphere.example.core.api.repository.FutureShadowUserRepository;
+import org.apache.shardingsphere.example.core.api.service.ExampleService;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.List;
+
+@Service("futureShadow")
+public class FutureShadowUserServiceImpl implements ExampleService {
+    
+    @Resource
+    private FutureShadowUserRepository userRepository;
+    
+    @Override
+    public void initEnvironment() throws SQLException {
+        userRepository.createTableIfNotExists();
+        userRepository.truncateTable();
+    }
+    
+    @Override
+    public void cleanEnvironment() throws SQLException {
+        userRepository.dropTable();
+    }
+    
+    @Override
+    public void processSuccess() throws SQLException {
+        System.out.println("-------------- Process Success Begin 
---------------");
+        List<Long> userIds = insertData();
+        printData();
+        deleteData(userIds);
+        printData();
+        System.out.println("-------------- Process Success Finish 
--------------");
+    }
+    
+    private List<Long> insertData() throws SQLException {
+        System.out.println("---------------------------- Insert Data 
----------------------------");
+        List<Long> result = new ArrayList<>(10);
+        for (int i = 1; i <= 10; i++) {
+            FutureShadowUser user = new FutureShadowUser();
+            user.setUserId(i);
+            user.setUserType(i % 2);
+            user.setUserName("test_mybatis_" + i);
+            user.setPwd("pwd_mybatis_" + i);
+            userRepository.insert(user);
+            result.add((long) user.getUserId());
+        }
+        return result;
+    }
+    
+    private void deleteData(final List<Long> userIds) throws SQLException {
+        System.out.println("---------------------------- Delete Data 
----------------------------");
+        for (Long each : userIds) {
+            userRepository.delete(each);
+        }
+    }
+    
+    @Override
+    public void processFailure() throws SQLException {
+        System.out.println("-------------- Process Failure Begin 
---------------");
+        insertData();
+        System.out.println("-------------- Process Failure Finish 
--------------");
+        throw new RuntimeException("Exception occur for transaction test.");
+    }
+    
+    @Override
+    public void printData() throws SQLException {
+        System.out.println("---------------------------- Print User Data 
-----------------------");
+        for (Object each : userRepository.selectAll()) {
+            System.out.println(each);
+        }
+    }
+}
diff --git 
a/examples/example-core/example-spring-mybatis/src/main/resources/META-INF/mappers/FutureShadowUserMapper.xml
 
b/examples/example-core/example-spring-mybatis/src/main/resources/META-INF/mappers/FutureShadowUserMapper.xml
new file mode 100644
index 0000000..e3ec076
--- /dev/null
+++ 
b/examples/example-core/example-spring-mybatis/src/main/resources/META-INF/mappers/FutureShadowUserMapper.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!--
+  ~ 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.
+  -->
+
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
"http://mybatis.org/dtd/mybatis-3-mapper.dtd";>
+<mapper 
namespace="org.apache.shardingsphere.example.core.mybatis.repository.MybatisFutureShadowUserRepository">
+    <resultMap id="baseResultMap" 
type="org.apache.shardingsphere.example.core.api.entity.FutureShadowUser">
+        <result column="user_id" property="userId" jdbcType="INTEGER"/>
+        <result column="user_type" property="userType" jdbcType="INTEGER"/>
+        <result column="user_name" property="userName" jdbcType="VARCHAR"/>
+        <result column="pwd" property="pwd" jdbcType="VARCHAR"/>
+        <result column="assisted_query_pwd" property="assistedQueryPwd" 
jdbcType="VARCHAR"/>
+    </resultMap>
+
+    <update id="createTableIfNotExistsNative">
+        CREATE TABLE IF NOT EXISTS t_user (user_id INT NOT NULL 
AUTO_INCREMENT, user_type INT(11), user_name VARCHAR(200), pwd VARCHAR(200), 
PRIMARY KEY (user_id));
+    </update>
+
+    <update id="createTableIfNotExistsShadow">
+        CREATE TABLE IF NOT EXISTS t_user (user_id INT NOT NULL 
AUTO_INCREMENT, user_type INT(11), user_name VARCHAR(200), pwd VARCHAR(200), 
PRIMARY KEY (user_id)) /*shadow:true,foo:bar*/;
+    </update>
+
+    <update id="truncateTableNative">
+        TRUNCATE TABLE t_user;
+    </update>
+
+    <update id="truncateTableShadow">
+        TRUNCATE TABLE t_user /*shadow:true,foo:bar*/;
+    </update>
+
+    <update id="dropTableNative">
+        DROP TABLE IF EXISTS t_user;
+    </update>
+
+    <update id="dropTableShadow">
+        DROP TABLE IF EXISTS t_user /*shadow:true,foo:bar*/;
+    </update>
+
+    <insert id="insert">
+        INSERT INTO t_user (user_id, user_type, user_name, pwd) VALUES 
(#{userId,jdbcType=INTEGER}, #{userType,jdbcType=INTEGER}, 
#{userName,jdbcType=VARCHAR}, #{pwd,jdbcType=VARCHAR});
+    </insert>
+
+    <delete id="deleteOne">
+        DELETE FROM t_user WHERE user_id = #{userId,jdbcType=INTEGER} AND 
user_type = #{userType,jdbcType=INTEGER};
+    </delete>
+
+    <select id="selectAll" resultMap="baseResultMap">
+        SELECT * FROM t_user WHERE user_type = #{userType,jdbcType=INTEGER};
+    </select>
+
+    <select id="selectAllByShadow" resultMap="baseResultMap">
+        SELECT * FROM t_user WHERE user_type = #{userType,jdbcType=INTEGER};
+    </select>
+</mapper>
diff --git 
a/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-boot-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/boot/mybatis/ShadowSpringBootMybatisExample.java
 
b/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-boot-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/boot/mybatis/ShadowSpringBootMybatisExample.java
index bd389cc..34b7903 100644
--- 
a/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-boot-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/boot/mybatis/ShadowSpringBootMybatisExample.java
+++ 
b/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-boot-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/boot/mybatis/ShadowSpringBootMybatisExample.java
@@ -17,23 +17,25 @@
 
 package org.apache.shardingsphere.example.shadow.spring.boot.mybatis;
 
-import 
org.apache.shardingsphere.example.shadow.spring.boot.mybatis.service.OrderService;
+import org.apache.shardingsphere.example.core.api.ExampleExecuteTemplate;
+import org.apache.shardingsphere.example.core.api.service.ExampleService;
 import org.mybatis.spring.annotation.MapperScan;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import 
org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration;
 import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.context.annotation.ComponentScan;
 
 import java.sql.SQLException;
 
-@MapperScan(basePackages = 
"org.apache.shardingsphere.example.shadow.spring.boot.mybatis.repository")
+@ComponentScan("org.apache.shardingsphere.example.core.mybatis")
+@MapperScan(basePackages = 
"org.apache.shardingsphere.example.core.mybatis.repository")
 @SpringBootApplication(exclude = JtaAutoConfiguration.class)
 public class ShadowSpringBootMybatisExample {
     
     public static void main(final String[] args) throws SQLException {
         try (ConfigurableApplicationContext applicationContext = 
SpringApplication.run(ShadowSpringBootMybatisExample.class, args)) {
-            OrderService orderService = 
applicationContext.getBean("orderService", OrderService.class);
-            orderService.executeInsertCase();
+            
ExampleExecuteTemplate.run(applicationContext.getBean("futureShadow", 
ExampleService.class));
         }
     }
 }
diff --git 
a/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-boot-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/boot/mybatis/domain/OrderInfo.java
 
b/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-boot-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/boot/mybatis/domain/OrderInfo.java
deleted file mode 100644
index 5566e31..0000000
--- 
a/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-boot-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/boot/mybatis/domain/OrderInfo.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * 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.shardingsphere.example.shadow.spring.boot.mybatis.domain;
-
-import lombok.Data;
-
-import java.io.Serializable;
-
-@Data
-public final class OrderInfo implements Serializable {
-    
-    private static final long serialVersionUID = -1590520493701492607L;
-    
-    private Integer orderId;
-    
-    private Integer userId;
-    
-    private String content;
-    
-    public OrderInfo(Integer orderId, Integer userId, String content) {
-        this.orderId = orderId;
-        this.userId = userId;
-        this.content = content;
-    }
-}
diff --git 
a/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-boot-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/boot/mybatis/repository/OrderMapper.java
 
b/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-boot-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/boot/mybatis/repository/OrderMapper.java
deleted file mode 100644
index 2b77316..0000000
--- 
a/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-boot-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/boot/mybatis/repository/OrderMapper.java
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- * 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.shardingsphere.example.shadow.spring.boot.mybatis.repository;
-
-import 
org.apache.shardingsphere.example.shadow.spring.boot.mybatis.domain.OrderInfo;
-
-public interface OrderMapper {
-    
-    void saveOne(OrderInfo orderInfo);
-}
diff --git 
a/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-boot-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/boot/mybatis/service/impl/OrderServiceImpl.java
 
b/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-boot-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/boot/mybatis/service/impl/OrderServiceImpl.java
deleted file mode 100644
index 7876adf..0000000
--- 
a/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-boot-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/boot/mybatis/service/impl/OrderServiceImpl.java
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * 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.shardingsphere.example.shadow.spring.boot.mybatis.service.impl;
-
-import 
org.apache.shardingsphere.example.shadow.spring.boot.mybatis.domain.OrderInfo;
-import 
org.apache.shardingsphere.example.shadow.spring.boot.mybatis.repository.OrderMapper;
-import 
org.apache.shardingsphere.example.shadow.spring.boot.mybatis.service.OrderService;
-import org.springframework.stereotype.Service;
-
-import javax.annotation.Resource;
-import java.util.Collection;
-import java.util.LinkedList;
-
-@Service(value = "orderService")
-public final class OrderServiceImpl implements OrderService {
-    
-    @Resource
-    private OrderMapper orderMapper;
-    
-    @Override
-    public void executeInsertCase() {
-        Collection<OrderInfo> orderInfos = initShadowOrderInfos();
-        orderInfos.forEach(each -> orderMapper.saveOne(each));
-    }
-    
-    private Collection<OrderInfo> initShadowOrderInfos() {
-        Collection<OrderInfo> result = new LinkedList<>();
-        for (int i = 0; i < 10; i++) {
-            result.add(new OrderInfo((i % 2), 1, "shadow_case"));
-        }
-        return result;
-    }
-    
-    private Collection<OrderInfo> initNativeOrderInfos() {
-        Collection<OrderInfo> result = new LinkedList<>();
-        for (int i = 0; i < 10; i++) {
-            result.add(new OrderInfo((i % 2), 2, "native_case"));
-        }
-        return result;
-    }
-}
diff --git 
a/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-boot-mybatis-example/src/main/resources/mapper/OrderMapper.xml
 
b/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-boot-mybatis-example/src/main/resources/META-INF/mybatis-config.xml
similarity index 51%
rename from 
examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-boot-mybatis-example/src/main/resources/mapper/OrderMapper.xml
rename to 
examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-boot-mybatis-example/src/main/resources/META-INF/mybatis-config.xml
index 8bd1574..ea8de7a 100644
--- 
a/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-boot-mybatis-example/src/main/resources/mapper/OrderMapper.xml
+++ 
b/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-boot-mybatis-example/src/main/resources/META-INF/mybatis-config.xml
@@ -16,15 +16,11 @@
   ~ limitations under the License.
   -->
 
-<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
"http://mybatis.org/dtd/mybatis-3-mapper.dtd";>
-<mapper 
namespace="org.apache.shardingsphere.example.shadow.spring.boot.mybatis.repository.OrderMapper">
-    <resultMap id="ShadowInfoMap" 
type="org.apache.shardingsphere.example.shadow.spring.boot.mybatis.domain.OrderInfo">
-        <result column="order_id" property="orderId" jdbcType="INTEGER"/>
-        <result column="user_id" property="userId" jdbcType="INTEGER"/>
-        <result column="content" property="content" jdbcType="VARCHAR"/>
-    </resultMap>
-
-    <insert id="saveOne" 
parameterType="org.apache.shardingsphere.example.shadow.spring.boot.mybatis.domain.OrderInfo">
-        insert into t_order(order_id, user_id, content) values (#{orderId}, 
#{userId}, #{content})
-    </insert>
-</mapper>
+<!DOCTYPE configuration
+        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-config.dtd";>
+<configuration>
+    <mappers>
+        <mapper resource="META-INF/mappers/FutureShadowUserMapper.xml"/>
+    </mappers>
+</configuration>
diff --git 
a/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-boot-mybatis-example/src/main/resources/application-shadow-databases.properties
 
b/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-boot-mybatis-example/src/main/resources/application-shadow-databases.properties
index f385be0..6d8fd03 100644
--- 
a/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-boot-mybatis-example/src/main/resources/application-shadow-databases.properties
+++ 
b/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-boot-mybatis-example/src/main/resources/application-shadow-databases.properties
@@ -37,10 +37,24 @@ spring.shardingsphere.rules.shadow.enable=true
 
spring.shardingsphere.rules.shadow.data-sources.shadow-data-source-0.source-data-source-name=ds
 
spring.shardingsphere.rules.shadow.data-sources.shadow-data-source-0.shadow-data-source-name=shadow-ds
 
-spring.shardingsphere.rules.shadow.tables.t_order.data-source-names=shadow-data-source-0
-spring.shardingsphere.rules.shadow.tables.t_order.shadow-algorithm-names=user-id-match-algorithm
+spring.shardingsphere.rules.shadow.tables.t_user.data-source-names=shadow-data-source-0
+spring.shardingsphere.rules.shadow.tables.t_user.shadow-algorithm-names=user-id-insert-match-algorithm,user-id-delete-match-algorithm,user-id-select-match-algorithm,simple-note-algorithm
 
-spring.shardingsphere.rules.shadow.shadow-algorithms.user-id-match-algorithm.type=COLUMN_REGEX_MATCH
-spring.shardingsphere.rules.shadow.shadow-algorithms.user-id-match-algorithm.props.operation=insert
-spring.shardingsphere.rules.shadow.shadow-algorithms.user-id-match-algorithm.props.column=user_id
-spring.shardingsphere.rules.shadow.shadow-algorithms.user-id-match-algorithm.props.regex=[1]
+spring.shardingsphere.rules.shadow.shadow-algorithms.user-id-insert-match-algorithm.type=COLUMN_REGEX_MATCH
+spring.shardingsphere.rules.shadow.shadow-algorithms.user-id-insert-match-algorithm.props.operation=insert
+spring.shardingsphere.rules.shadow.shadow-algorithms.user-id-insert-match-algorithm.props.column=user_type
+spring.shardingsphere.rules.shadow.shadow-algorithms.user-id-insert-match-algorithm.props.regex=[1]
+
+spring.shardingsphere.rules.shadow.shadow-algorithms.user-id-delete-match-algorithm.type=COLUMN_REGEX_MATCH
+spring.shardingsphere.rules.shadow.shadow-algorithms.user-id-delete-match-algorithm.props.operation=delete
+spring.shardingsphere.rules.shadow.shadow-algorithms.user-id-delete-match-algorithm.props.column=user_type
+spring.shardingsphere.rules.shadow.shadow-algorithms.user-id-delete-match-algorithm.props.regex=[1]
+
+spring.shardingsphere.rules.shadow.shadow-algorithms.user-id-select-match-algorithm.type=COLUMN_REGEX_MATCH
+spring.shardingsphere.rules.shadow.shadow-algorithms.user-id-select-match-algorithm.props.operation=select
+spring.shardingsphere.rules.shadow.shadow-algorithms.user-id-select-match-algorithm.props.column=user_type
+spring.shardingsphere.rules.shadow.shadow-algorithms.user-id-select-match-algorithm.props.regex=[1]
+
+spring.shardingsphere.rules.shadow.shadow-algorithms.simple-note-algorithm.type=SIMPLE_NOTE
+spring.shardingsphere.rules.shadow.shadow-algorithms.simple-note-algorithm.props.shadow=true
+spring.shardingsphere.rules.shadow.shadow-algorithms.simple-note-algorithm.props.foo=bar
diff --git 
a/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-boot-mybatis-example/src/main/resources/application-shadow-sharding-databases.properties
 
b/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-boot-mybatis-example/src/main/resources/application-shadow-sharding-databases.properties
index 3a12812..664d5de 100644
--- 
a/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-boot-mybatis-example/src/main/resources/application-shadow-sharding-databases.properties
+++ 
b/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-boot-mybatis-example/src/main/resources/application-shadow-sharding-databases.properties
@@ -41,13 +41,13 @@ 
spring.shardingsphere.datasource.shadow-ds-1.driver-class-name=com.mysql.jdbc.Dr
 spring.shardingsphere.datasource.shadow-ds-1.username=root
 spring.shardingsphere.datasource.shadow-ds-1.password=
 
-spring.shardingsphere.rules.sharding.default-database-strategy.standard.sharding-column=order_id
+spring.shardingsphere.rules.sharding.default-database-strategy.standard.sharding-column=user_id
 
spring.shardingsphere.rules.sharding.default-database-strategy.standard.sharding-algorithm-name=database-inline
 
-spring.shardingsphere.rules.sharding.tables.t_order.actual-data-nodes=ds-$->{0..1}.t_order
+spring.shardingsphere.rules.sharding.tables.t_user.actual-data-nodes=ds-$->{0..1}.t_user
 
 
spring.shardingsphere.rules.sharding.sharding-algorithms.database-inline.type=INLINE
-spring.shardingsphere.rules.sharding.sharding-algorithms.database-inline.props.algorithm-expression=ds-$->{order_id
 % 2}
+spring.shardingsphere.rules.sharding.sharding-algorithms.database-inline.props.algorithm-expression=ds-$->{user_id
 % 2}
 
 spring.shardingsphere.rules.shadow.column=shadow
 spring.shardingsphere.rules.shadow.sourceDataSourceNames=ds-0,ds-1
@@ -59,10 +59,24 @@ 
spring.shardingsphere.rules.shadow.data-sources.shadow-data-source-0.shadow-data
 
spring.shardingsphere.rules.shadow.data-sources.shadow-data-source-1.source-data-source-name=ds-1
 
spring.shardingsphere.rules.shadow.data-sources.shadow-data-source-1.shadow-data-source-name=shadow-ds-1
 
-spring.shardingsphere.rules.shadow.tables.t_order.data-source-names=shadow-data-source-0,shadow-data-source-1
-spring.shardingsphere.rules.shadow.tables.t_order.shadow-algorithm-names=user-id-match-algorithm
+spring.shardingsphere.rules.shadow.tables.t_user.data-source-names=shadow-data-source-0,shadow-data-source-1
+spring.shardingsphere.rules.shadow.tables.t_user.shadow-algorithm-names=user-id-insert-match-algorithm,user-id-delete-match-algorithm,user-id-select-match-algorithm,simple-note-algorithm
 
-spring.shardingsphere.rules.shadow.shadow-algorithms.user-id-match-algorithm.type=COLUMN_REGEX_MATCH
-spring.shardingsphere.rules.shadow.shadow-algorithms.user-id-match-algorithm.props.operation=insert
-spring.shardingsphere.rules.shadow.shadow-algorithms.user-id-match-algorithm.props.column=user_id
-spring.shardingsphere.rules.shadow.shadow-algorithms.user-id-match-algorithm.props.regex=[1]
+spring.shardingsphere.rules.shadow.shadow-algorithms.user-id-insert-match-algorithm.type=COLUMN_REGEX_MATCH
+spring.shardingsphere.rules.shadow.shadow-algorithms.user-id-insert-match-algorithm.props.operation=insert
+spring.shardingsphere.rules.shadow.shadow-algorithms.user-id-insert-match-algorithm.props.column=user_type
+spring.shardingsphere.rules.shadow.shadow-algorithms.user-id-insert-match-algorithm.props.regex=[1]
+
+spring.shardingsphere.rules.shadow.shadow-algorithms.user-id-delete-match-algorithm.type=COLUMN_REGEX_MATCH
+spring.shardingsphere.rules.shadow.shadow-algorithms.user-id-delete-match-algorithm.props.operation=delete
+spring.shardingsphere.rules.shadow.shadow-algorithms.user-id-delete-match-algorithm.props.column=user_type
+spring.shardingsphere.rules.shadow.shadow-algorithms.user-id-delete-match-algorithm.props.regex=[1]
+
+spring.shardingsphere.rules.shadow.shadow-algorithms.user-id-select-match-algorithm.type=COLUMN_REGEX_MATCH
+spring.shardingsphere.rules.shadow.shadow-algorithms.user-id-select-match-algorithm.props.operation=select
+spring.shardingsphere.rules.shadow.shadow-algorithms.user-id-select-match-algorithm.props.column=user_type
+spring.shardingsphere.rules.shadow.shadow-algorithms.user-id-select-match-algorithm.props.regex=[1]
+
+spring.shardingsphere.rules.shadow.shadow-algorithms.simple-note-algorithm.type=SIMPLE_NOTE
+spring.shardingsphere.rules.shadow.shadow-algorithms.simple-note-algorithm.props.shadow=true
+spring.shardingsphere.rules.shadow.shadow-algorithms.simple-note-algorithm.props.foo=bar
diff --git 
a/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-boot-mybatis-example/src/main/resources/application.properties
 
b/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-boot-mybatis-example/src/main/resources/application.properties
index 15af4bb..e45c594 100644
--- 
a/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-boot-mybatis-example/src/main/resources/application.properties
+++ 
b/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-boot-mybatis-example/src/main/resources/application.properties
@@ -19,4 +19,6 @@ spring.profiles.active=shadow-databases
 #spring.profiles.active=shadow-sharding-databases
 
 spring.shardingsphere.props.sql-show=true
-mybatis.mapper-locations=classpath:mapper/*.xml
+spring.shardingsphere.props.sql-comment-parse-enabled=true
+
+mybatis.config-location=classpath:META-INF/mybatis-config.xml
diff --git 
a/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/namespace/mybatis/ShadowSpringNamespaceMybatisExample.java
 
b/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/namespace/mybatis/ShadowSpringNamespace
 [...]
index 7bcf439..7832d51 100644
--- 
a/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/namespace/mybatis/ShadowSpringNamespaceMybatisExample.java
+++ 
b/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/namespace/mybatis/ShadowSpringNamespaceMybatisExample.java
@@ -48,5 +48,6 @@ public final class ShadowSpringNamespaceMybatisExample {
         shadowService.executeDeleteCase();
         shadowService.executeUpdateCase();
         shadowService.executeSelectCase();
+        shadowService.executeNoteCase();
     }
 }
diff --git 
a/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/namespace/mybatis/service/SQLGenerator.java
 
b/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/namespace/mybatis/service/SQLGenerator.java
index 336c93d..c82a96b 100644
--- 
a/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/namespace/mybatis/service/SQLGenerator.java
+++ 
b/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/namespace/mybatis/service/SQLGenerator.java
@@ -151,4 +151,13 @@ public final class SQLGenerator {
         result.add(select_case_15);
         return result;
     }
+    
+    public static Collection<String> initNoteCase() {
+        Collection<String> result = new LinkedList<>();
+        String note_case_1 = "create table t_user(id int(11) not null , 
user_name varchar(32) not null ) /*shadow:true,foo:bar,aaa:ddd*/";
+        result.add(note_case_1);
+        String note_case_2 = "INSERT INTO t_order (user_id, content) VALUES 
(1, 'note_case_1') /*shadow:true,foo:bar,aaa:ddd*/";
+        result.add(note_case_2);
+        return result;
+    }
 }
diff --git 
a/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/namespace/mybatis/service/ShadowService.java
 
b/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/namespace/mybatis/service/ShadowService.java
index 1f7450f..811e448 100644
--- 
a/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/namespace/mybatis/service/ShadowService.java
+++ 
b/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/namespace/mybatis/service/ShadowService.java
@@ -26,4 +26,6 @@ public interface ShadowService {
     void executeDeleteCase();
     
     void executeSelectCase();
+    
+    void executeNoteCase();
 }
diff --git 
a/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/namespace/mybatis/service/impl/ShadowServiceImpl.java
 
b/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/namespace/mybatis/service/impl/ShadowService
 [...]
index abd08f2..7e23a43 100644
--- 
a/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/namespace/mybatis/service/impl/ShadowServiceImpl.java
+++ 
b/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/java/org/apache/shardingsphere/example/shadow/spring/namespace/mybatis/service/impl/ShadowServiceImpl.java
@@ -53,4 +53,9 @@ public final class ShadowServiceImpl implements ShadowService 
{
     public void executeSelectCase() {
         SQLGenerator.initSelectCase().forEach(this::execute);
     }
+    
+    @Override
+    public void executeNoteCase() {
+        SQLGenerator.initNoteCase().forEach(this::execute);
+    }
 }
diff --git 
a/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/resources/META-INF/application-shadow-databases.xml
 
b/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/resources/META-INF/application-shadow-databases.xml
index cc18ddb..c203159 100644
--- 
a/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/resources/META-INF/application-shadow-databases.xml
+++ 
b/examples/shardingsphere-jdbc-example/other-feature-example/future-shadow-example/future-shadow-spring-namespace-mybatis-example/src/main/resources/META-INF/application-shadow-databases.xml
@@ -64,16 +64,18 @@
     <shadow:rule id="shadowRule" enable="true" column="shadow" 
sourceDataSourceNames="ds" shadowDataSourceNames="ds_shadow">
         <shadow:data-source id="shadow-data-source" 
source-data-source-name="ds" shadow-data-source-name="ds_shadow"/>
         <shadow:shadow-table name="t_order" data-sources="shadow-data-source">
-            <shadow:algorithm shadow-algorithm-ref= "user-id-match-algorithm" 
/>
+            <shadow:algorithm shadow-algorithm-ref="user-id-match-algorithm" />
+            <shadow:algorithm shadow-algorithm-ref="simple-note-algorithm" />
         </shadow:shadow-table>
         <shadow:shadow-table name="t_user" data-sources="shadow-data-source">
-            <shadow:algorithm shadow-algorithm-ref= "simple-note-algorithm" />
+            <shadow:algorithm shadow-algorithm-ref="simple-note-algorithm" />
         </shadow:shadow-table>
     </shadow:rule>
 
     <shardingsphere:data-source id="shadowDataSource" 
data-source-names="ds,ds_shadow" rule-refs="shadowRule">
         <props>
             <prop key="sql-show">true</prop>
+            <prop key="sql-comment-parse-enabled">true</prop>
         </props>
     </shardingsphere:data-source>
     
diff --git 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-api/src/main/java/org/apache/shardingsphere/shadow/api/shadow/column/ShadowOperationType.java
 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-api/src/main/java/org/apache/shardingsphere/shadow/api/shadow/column/ShadowOperationType.java
index c511732..80aa4e2 100644
--- 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-api/src/main/java/org/apache/shardingsphere/shadow/api/shadow/column/ShadowOperationType.java
+++ 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-api/src/main/java/org/apache/shardingsphere/shadow/api/shadow/column/ShadowOperationType.java
@@ -42,7 +42,12 @@ public enum ShadowOperationType {
     /**
      * The shadow operation is select.
      */
-    SELECT;
+    SELECT,
+    
+    /**
+     * non-DML statement shadow operation.
+     */
+    NON_DML;
     
     /**
      * Contains operation type.
diff --git 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-api/src/main/java/org/apache/shardingsphere/shadow/api/shadow/note/PreciseNoteShadowValue.java
 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-api/src/main/java/org/apache/shardingsphere/shadow/api/shadow/note/PreciseNoteShadowValue.java
index 2e297bc..636de34 100644
--- 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-api/src/main/java/org/apache/shardingsphere/shadow/api/shadow/note/PreciseNoteShadowValue.java
+++ 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-api/src/main/java/org/apache/shardingsphere/shadow/api/shadow/note/PreciseNoteShadowValue.java
@@ -20,6 +20,7 @@ package org.apache.shardingsphere.shadow.api.shadow.note;
 import lombok.Getter;
 import lombok.RequiredArgsConstructor;
 import org.apache.shardingsphere.shadow.api.shadow.ShadowValue;
+import org.apache.shardingsphere.shadow.api.shadow.column.ShadowOperationType;
 
 @RequiredArgsConstructor
 @Getter
@@ -27,5 +28,7 @@ public final class PreciseNoteShadowValue<T extends 
Comparable<?>> implements Sh
     
     private final String logicTableName;
     
+    private final ShadowOperationType shadowOperationType;
+    
     private final T sqlNoteValue;
 }
diff --git 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/algorithm/shadow/note/NoteShadowAlgorithmUtil.java
 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/algorithm/shadow/note/NoteShadowAlgorithmUtil.java
index 1b52dde..1c8c6ae 100644
--- 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/algorithm/shadow/note/NoteShadowAlgorithmUtil.java
+++ 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/algorithm/shadow/note/NoteShadowAlgorithmUtil.java
@@ -28,7 +28,7 @@ public final class NoteShadowAlgorithmUtil {
     
     private static final String SIMPLE_SQL_NOTE_SPACE = ",";
     
-    private static final String SIMPLE_SQL_NOTE_ELEMENT_SPACE = "=";
+    private static final String SIMPLE_SQL_NOTE_ELEMENT_SPACE = ":";
     
     private static final String SIMPLE_SQL_NOTE_PREFIX = "/*";
     
@@ -58,7 +58,9 @@ public final class NoteShadowAlgorithmUtil {
                 String temp = each;
                 temp = temp.trim();
                 String[] split = temp.split(SIMPLE_SQL_NOTE_ELEMENT_SPACE);
-                result.put(split[0].trim(), split[1].trim());
+                if (2 == split.length) {
+                    result.put(split[0].trim(), split[1].trim());
+                }
             }
             return Optional.of(result);
         }
diff --git 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/algorithm/shadow/note/SimpleSQLNoteShadowAlgorithm.java
 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/algorithm/shadow/note/SimpleSQLNoteShadowAlgorithm.java
index b04d895..2c47567 100644
--- 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/algorithm/shadow/note/SimpleSQLNoteShadowAlgorithm.java
+++ 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/algorithm/shadow/note/SimpleSQLNoteShadowAlgorithm.java
@@ -20,6 +20,7 @@ package 
org.apache.shardingsphere.shadow.algorithm.shadow.note;
 import com.google.common.base.Preconditions;
 import lombok.Getter;
 import lombok.Setter;
+import org.apache.shardingsphere.shadow.api.shadow.column.ShadowOperationType;
 import org.apache.shardingsphere.shadow.api.shadow.note.NoteShadowAlgorithm;
 import org.apache.shardingsphere.shadow.api.shadow.note.PreciseNoteShadowValue;
 
@@ -49,7 +50,7 @@ public final class SimpleSQLNoteShadowAlgorithm implements 
NoteShadowAlgorithm<S
     
     @Override
     public boolean isShadow(final Collection<String> shadowTableNames, final 
PreciseNoteShadowValue<String> noteShadowValue) {
-        if (!shadowTableNames.contains(noteShadowValue.getLogicTableName())) {
+        if (ShadowOperationType.NON_DML != 
noteShadowValue.getShadowOperationType() && 
!shadowTableNames.contains(noteShadowValue.getLogicTableName())) {
             return false;
         }
         Optional<Map<String, String>> noteOptional = 
NoteShadowAlgorithmUtil.parseSimpleSQLNote(noteShadowValue.getSqlNoteValue());
diff --git 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/ShadowRouteEngineFactory.java
 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/ShadowRouteEngineFactory.java
index ff24a50..1f03df0 100644
--- 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/ShadowRouteEngineFactory.java
+++ 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/ShadowRouteEngineFactory.java
@@ -28,7 +28,7 @@ import 
org.apache.shardingsphere.shadow.route.future.engine.dml.ShadowDeleteStat
 import 
org.apache.shardingsphere.shadow.route.future.engine.dml.ShadowInsertStatementRoutingEngine;
 import 
org.apache.shardingsphere.shadow.route.future.engine.dml.ShadowSelectStatementRoutingEngine;
 import 
org.apache.shardingsphere.shadow.route.future.engine.dml.ShadowUpdateStatementRoutingEngine;
-import 
org.apache.shardingsphere.shadow.route.future.engine.impl.ShadowNonMDLStatementRoutingEngine;
+import 
org.apache.shardingsphere.shadow.route.future.engine.impl.ShadowNonDMLStatementRoutingEngine;
 import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.common.statement.dml.DeleteStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.common.statement.dml.InsertStatement;
@@ -58,12 +58,12 @@ public final class ShadowRouteEngineFactory {
         } else if (sqlStatement instanceof SelectStatement) {
             return createShadowSelectStatementRoutingEngine(logicSQL);
         } else {
-            return createShadowNonMDLStatementRoutingEngine();
+            return createShadowNonMDLStatementRoutingEngine(logicSQL);
         }
     }
     
-    private static ShadowRouteEngine 
createShadowNonMDLStatementRoutingEngine() {
-        return new ShadowNonMDLStatementRoutingEngine();
+    private static ShadowRouteEngine 
createShadowNonMDLStatementRoutingEngine(final LogicSQL logicSQL) {
+        return new 
ShadowNonDMLStatementRoutingEngine(logicSQL.getSqlStatementContext());
     }
     
     private static ShadowRouteEngine 
createShadowSelectStatementRoutingEngine(final LogicSQL logicSQL) {
diff --git 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/determiner/algorithm/NoteShadowAlgorithmDeterminer.java
 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/determiner/algorithm/NoteShadowAlgorithmDeterminer.java
index 863e667..355a83b 100644
--- 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/determiner/algorithm/NoteShadowAlgorithmDeterminer.java
+++ 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/determiner/algorithm/NoteShadowAlgorithmDeterminer.java
@@ -18,6 +18,7 @@
 package 
org.apache.shardingsphere.shadow.route.future.engine.determiner.algorithm;
 
 import lombok.RequiredArgsConstructor;
+import org.apache.shardingsphere.shadow.api.shadow.column.ShadowOperationType;
 import org.apache.shardingsphere.shadow.api.shadow.note.NoteShadowAlgorithm;
 import org.apache.shardingsphere.shadow.api.shadow.note.PreciseNoteShadowValue;
 import 
org.apache.shardingsphere.shadow.route.future.engine.determiner.ShadowAlgorithmDeterminer;
@@ -47,8 +48,9 @@ public final class NoteShadowAlgorithmDeterminer implements 
ShadowAlgorithmDeter
     }
     
     private Collection<PreciseNoteShadowValue<Comparable<?>>> 
createNoteShadowValues(final ShadowDetermineCondition shadowDetermineCondition, 
final String tableName) {
+        ShadowOperationType shadowOperationType = 
shadowDetermineCondition.getShadowOperationType();
         Collection<PreciseNoteShadowValue<Comparable<?>>> result = new 
LinkedList<>();
-        shadowDetermineCondition.getSqlNotes().ifPresent(notes -> 
notes.forEach(each -> result.add(new PreciseNoteShadowValue<>(tableName, 
each))));
+        shadowDetermineCondition.getSqlNotes().ifPresent(notes -> 
notes.forEach(each -> result.add(new PreciseNoteShadowValue<>(tableName, 
shadowOperationType, each))));
         return result;
     }
 }
diff --git 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/AbstractShadowRouteEngine.java
 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/dml/AbstractShadowDMLStatementRouteEngine.java
similarity index 96%
rename from 
shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/AbstractShadowRouteEngine.java
rename to 
shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/dml/AbstractShadowDMLStatementRouteEngine.java
index a680326..52f1c85 100644
--- 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/AbstractShadowRouteEngine.java
+++ 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/dml/AbstractShadowDMLStatementRouteEngine.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.shadow.route.future.engine;
+package org.apache.shardingsphere.shadow.route.future.engine.dml;
 
 import lombok.Getter;
 import org.apache.shardingsphere.infra.route.context.RouteContext;
@@ -23,6 +23,7 @@ import 
org.apache.shardingsphere.infra.route.context.RouteMapper;
 import org.apache.shardingsphere.infra.route.context.RouteUnit;
 import 
org.apache.shardingsphere.shadow.api.shadow.column.ColumnShadowAlgorithm;
 import org.apache.shardingsphere.shadow.api.shadow.note.NoteShadowAlgorithm;
+import org.apache.shardingsphere.shadow.route.future.engine.ShadowRouteEngine;
 import 
org.apache.shardingsphere.shadow.route.future.engine.determiner.ShadowColumnCondition;
 import 
org.apache.shardingsphere.shadow.route.future.engine.determiner.ShadowDetermineCondition;
 import 
org.apache.shardingsphere.shadow.route.future.engine.determiner.ShadowDeterminerFactory;
@@ -38,9 +39,9 @@ import java.util.Map;
 import java.util.Optional;
 
 /**
- * Abstract shadow route engine.
+ * Abstract shadow DML statement route engine.
  */
-public abstract class AbstractShadowRouteEngine implements ShadowRouteEngine {
+public abstract class AbstractShadowDMLStatementRouteEngine implements 
ShadowRouteEngine {
     
     @Getter
     private final Map<String, String> tableAliasNameMappings = new 
LinkedHashMap<>();
diff --git 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/dml/ShadowDeleteStatementRoutingEngine.java
 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/dml/ShadowDeleteStatementRoutingEngine.java
index b7df2d2..756fac4 100644
--- 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/dml/ShadowDeleteStatementRoutingEngine.java
+++ 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/dml/ShadowDeleteStatementRoutingEngine.java
@@ -20,7 +20,6 @@ package 
org.apache.shardingsphere.shadow.route.future.engine.dml;
 import lombok.RequiredArgsConstructor;
 import 
org.apache.shardingsphere.infra.binder.statement.dml.DeleteStatementContext;
 import org.apache.shardingsphere.shadow.api.shadow.column.ShadowOperationType;
-import 
org.apache.shardingsphere.shadow.route.future.engine.AbstractShadowRouteEngine;
 import 
org.apache.shardingsphere.shadow.route.future.engine.determiner.ShadowColumnCondition;
 import 
org.apache.shardingsphere.shadow.route.future.engine.determiner.ShadowDetermineCondition;
 import 
org.apache.shardingsphere.shadow.route.future.engine.util.ShadowExtractor;
@@ -39,7 +38,7 @@ import java.util.Optional;
  * Shadow delete statement routing engine.
  */
 @RequiredArgsConstructor
-public final class ShadowDeleteStatementRoutingEngine extends 
AbstractShadowRouteEngine {
+public final class ShadowDeleteStatementRoutingEngine extends 
AbstractShadowDMLStatementRouteEngine {
     
     private final DeleteStatementContext deleteStatementContext;
     
@@ -79,8 +78,7 @@ public final class ShadowDeleteStatementRoutingEngine extends 
AbstractShadowRout
     @Override
     protected Optional<Collection<String>> parseSqlNotes() {
         Collection<String> result = new LinkedList<>();
-        result.add("/*foo=bar,shadow=true*/");
-        result.add("/*aaa=bbb*/");
-        return Optional.of(result);
+        
deleteStatementContext.getSqlStatement().getCommentSegments().forEach(each -> 
result.add(each.getText()));
+        return result.isEmpty() ? Optional.empty() : Optional.of(result);
     }
 }
diff --git 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/dml/ShadowInsertStatementRoutingEngine.java
 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/dml/ShadowInsertStatementRoutingEngine.java
index adb8b130..5ad1b00 100644
--- 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/dml/ShadowInsertStatementRoutingEngine.java
+++ 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/dml/ShadowInsertStatementRoutingEngine.java
@@ -21,7 +21,6 @@ import lombok.RequiredArgsConstructor;
 import 
org.apache.shardingsphere.infra.binder.segment.insert.values.InsertValueContext;
 import 
org.apache.shardingsphere.infra.binder.statement.dml.InsertStatementContext;
 import org.apache.shardingsphere.shadow.api.shadow.column.ShadowOperationType;
-import 
org.apache.shardingsphere.shadow.route.future.engine.AbstractShadowRouteEngine;
 import 
org.apache.shardingsphere.shadow.route.future.engine.determiner.ShadowColumnCondition;
 import 
org.apache.shardingsphere.shadow.route.future.engine.determiner.ShadowDetermineCondition;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SimpleTableSegment;
@@ -36,7 +35,7 @@ import java.util.Optional;
  * Shadow insert statement routing engine.
  */
 @RequiredArgsConstructor
-public final class ShadowInsertStatementRoutingEngine extends 
AbstractShadowRouteEngine {
+public final class ShadowInsertStatementRoutingEngine extends 
AbstractShadowDMLStatementRouteEngine {
     
     private final InsertStatementContext insertStatementContext;
     
@@ -87,8 +86,7 @@ public final class ShadowInsertStatementRoutingEngine extends 
AbstractShadowRout
     @Override
     protected Optional<Collection<String>> parseSqlNotes() {
         Collection<String> result = new LinkedList<>();
-        result.add("/*foo=bar,shadow=true*/");
-        result.add("/*aaa=bbb*/");
-        return Optional.of(result);
+        
insertStatementContext.getSqlStatement().getCommentSegments().forEach(each -> 
result.add(each.getText()));
+        return result.isEmpty() ? Optional.empty() : Optional.of(result);
     }
 }
diff --git 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/dml/ShadowSelectStatementRoutingEngine.java
 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/dml/ShadowSelectStatementRoutingEngine.java
index ba7687f..71f5078 100644
--- 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/dml/ShadowSelectStatementRoutingEngine.java
+++ 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/dml/ShadowSelectStatementRoutingEngine.java
@@ -20,7 +20,6 @@ package 
org.apache.shardingsphere.shadow.route.future.engine.dml;
 import lombok.RequiredArgsConstructor;
 import 
org.apache.shardingsphere.infra.binder.statement.dml.SelectStatementContext;
 import org.apache.shardingsphere.shadow.api.shadow.column.ShadowOperationType;
-import 
org.apache.shardingsphere.shadow.route.future.engine.AbstractShadowRouteEngine;
 import 
org.apache.shardingsphere.shadow.route.future.engine.determiner.ShadowColumnCondition;
 import 
org.apache.shardingsphere.shadow.route.future.engine.determiner.ShadowDetermineCondition;
 import 
org.apache.shardingsphere.shadow.route.future.engine.util.ShadowExtractor;
@@ -41,7 +40,7 @@ import java.util.Optional;
  * Shadow select statement routing engine.
  */
 @RequiredArgsConstructor
-public final class ShadowSelectStatementRoutingEngine extends 
AbstractShadowRouteEngine {
+public final class ShadowSelectStatementRoutingEngine extends 
AbstractShadowDMLStatementRouteEngine {
     
     private final SelectStatementContext selectStatementContext;
     
@@ -91,8 +90,7 @@ public final class ShadowSelectStatementRoutingEngine extends 
AbstractShadowRout
     @Override
     protected Optional<Collection<String>> parseSqlNotes() {
         Collection<String> result = new LinkedList<>();
-        result.add("/*foo=bar,shadow=true*/");
-        result.add("/*aaa=bbb*/");
-        return Optional.of(result);
+        
selectStatementContext.getSqlStatement().getCommentSegments().forEach(each -> 
result.add(each.getText()));
+        return result.isEmpty() ? Optional.empty() : Optional.of(result);
     }
 }
diff --git 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/dml/ShadowUpdateStatementRoutingEngine.java
 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/dml/ShadowUpdateStatementRoutingEngine.java
index a868293..de86e2c 100644
--- 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/dml/ShadowUpdateStatementRoutingEngine.java
+++ 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/dml/ShadowUpdateStatementRoutingEngine.java
@@ -20,7 +20,6 @@ package 
org.apache.shardingsphere.shadow.route.future.engine.dml;
 import lombok.RequiredArgsConstructor;
 import 
org.apache.shardingsphere.infra.binder.statement.dml.UpdateStatementContext;
 import org.apache.shardingsphere.shadow.api.shadow.column.ShadowOperationType;
-import 
org.apache.shardingsphere.shadow.route.future.engine.AbstractShadowRouteEngine;
 import 
org.apache.shardingsphere.shadow.route.future.engine.determiner.ShadowColumnCondition;
 import 
org.apache.shardingsphere.shadow.route.future.engine.determiner.ShadowDetermineCondition;
 import 
org.apache.shardingsphere.shadow.route.future.engine.util.ShadowExtractor;
@@ -39,7 +38,7 @@ import java.util.Optional;
  * Shadow update statement routing engine.
  */
 @RequiredArgsConstructor
-public final class ShadowUpdateStatementRoutingEngine extends 
AbstractShadowRouteEngine {
+public final class ShadowUpdateStatementRoutingEngine extends 
AbstractShadowDMLStatementRouteEngine {
     
     private final UpdateStatementContext updateStatementContext;
     
@@ -79,8 +78,7 @@ public final class ShadowUpdateStatementRoutingEngine extends 
AbstractShadowRout
     @Override
     protected Optional<Collection<String>> parseSqlNotes() {
         Collection<String> result = new LinkedList<>();
-        result.add("/*foo=bar,shadow=true*/");
-        result.add("/*aaa=bbb*/");
-        return Optional.of(result);
+        
updateStatementContext.getSqlStatement().getCommentSegments().forEach(each -> 
result.add(each.getText()));
+        return result.isEmpty() ? Optional.empty() : Optional.of(result);
     }
 }
diff --git 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/impl/ShadowNonDMLStatementRoutingEngine.java
 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/impl/ShadowNonDMLStatementRoutingEngine.java
new file mode 100644
index 0000000..f2f2023
--- /dev/null
+++ 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/impl/ShadowNonDMLStatementRoutingEngine.java
@@ -0,0 +1,103 @@
+/*
+ * 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.shardingsphere.shadow.route.future.engine.impl;
+
+import lombok.RequiredArgsConstructor;
+import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
+import org.apache.shardingsphere.infra.route.context.RouteContext;
+import org.apache.shardingsphere.infra.route.context.RouteMapper;
+import org.apache.shardingsphere.infra.route.context.RouteUnit;
+import org.apache.shardingsphere.shadow.api.shadow.column.ShadowOperationType;
+import org.apache.shardingsphere.shadow.route.future.engine.ShadowRouteEngine;
+import 
org.apache.shardingsphere.shadow.route.future.engine.determiner.ShadowDetermineCondition;
+import 
org.apache.shardingsphere.shadow.route.future.engine.determiner.ShadowDeterminerFactory;
+import org.apache.shardingsphere.shadow.rule.ShadowRule;
+import org.apache.shardingsphere.shadow.spi.ShadowAlgorithm;
+import 
org.apache.shardingsphere.sql.parser.sql.common.statement.AbstractSQLStatement;
+
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.Map;
+import java.util.Optional;
+
+/**
+ * Shadow non-DML statement routing engine.
+ */
+@RequiredArgsConstructor
+public final class ShadowNonDMLStatementRoutingEngine implements 
ShadowRouteEngine {
+    
+    private final SQLStatementContext<?> sqlStatementContext;
+    
+    @Override
+    public void route(final RouteContext routeContext, final ShadowRule 
shadowRule) {
+        Optional<Map<String, String>> shadowDataSourceMappings = 
findShadowDataSourceMappings(shadowRule);
+        shadowDataSourceMappings.ifPresent(stringStringMap -> 
shadowNonDMLStatementRouteDecorate(routeContext, stringStringMap));
+    }
+    
+    private Optional<Map<String, String>> findShadowDataSourceMappings(final 
ShadowRule shadowRule) {
+        Optional<Collection<String>> sqlNotes = parseSqlNotes();
+        if (sqlNotes.isPresent() && isShadowSqlNotes(shadowRule, 
sqlNotes.get())) {
+            return Optional.of(shadowRule.getAllShadowDataSourceMappings());
+        }
+        return Optional.empty();
+    }
+    
+    private Optional<Collection<String>> parseSqlNotes() {
+        Collection<String> result = new LinkedList<>();
+        ((AbstractSQLStatement) 
sqlStatementContext.getSqlStatement()).getCommentSegments().forEach(each -> 
result.add(each.getText()));
+        return result.isEmpty() ? Optional.empty() : Optional.of(result);
+    }
+    
+    private boolean isShadowSqlNotes(final ShadowRule shadowRule, final 
Collection<String> sqlNotes) {
+        Optional<Collection<ShadowAlgorithm>> relatedNoteShadowAlgorithms = 
shadowRule.getRelatedNoteShadowAlgorithms();
+        return relatedNoteShadowAlgorithms.filter(shadowAlgorithms -> 
isMatchNoteAlgorithms(shadowAlgorithms, shadowRule, sqlNotes)).isPresent();
+    }
+    
+    private boolean isMatchNoteAlgorithms(final Collection<ShadowAlgorithm> 
shadowAlgorithms, final ShadowRule shadowRule, final Collection<String> 
sqlNotes) {
+        for (ShadowAlgorithm each : shadowAlgorithms) {
+            if (isMatchNoteAlgorithm(each, shadowRule, sqlNotes)) {
+                return true;
+            }
+        }
+        return false;
+    }
+    
+    private boolean isMatchNoteAlgorithm(final ShadowAlgorithm 
shadowAlgorithm, final ShadowRule shadowRule, final Collection<String> 
sqlNotes) {
+        return 
ShadowDeterminerFactory.newInstance(shadowAlgorithm).isShadow(createShadowDetermineCondition(sqlNotes),
 shadowRule, "");
+    }
+    
+    private ShadowDetermineCondition createShadowDetermineCondition(final 
Collection<String> sqlNotes) {
+        ShadowDetermineCondition shadowDetermineCondition = new 
ShadowDetermineCondition(ShadowOperationType.NON_DML);
+        shadowDetermineCondition.initSqlNotes(sqlNotes);
+        return shadowDetermineCondition;
+    }
+    
+    private void shadowNonDMLStatementRouteDecorate(final RouteContext 
routeContext, final Map<String, String> shadowDataSourceMappings) {
+        Collection<RouteUnit> routeUnits = routeContext.getRouteUnits();
+        Collection<RouteUnit> toBeAdded = new LinkedList<>();
+        for (RouteUnit each : routeUnits) {
+            RouteMapper dataSourceMapper = each.getDataSourceMapper();
+            String shadowActualName = 
shadowDataSourceMappings.get(dataSourceMapper.getActualName());
+            if (null != shadowActualName) {
+                toBeAdded.add(new RouteUnit(new 
RouteMapper(dataSourceMapper.getLogicName(), shadowActualName), 
each.getTableMappers()));
+            }
+        }
+        routeUnits.clear();
+        routeUnits.addAll(toBeAdded);
+    }
+}
diff --git 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/impl/ShadowNonMDLStatementRoutingEngine.java
 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/impl/ShadowNonMDLStatementRoutingEngine.java
deleted file mode 100644
index 1960726..0000000
--- 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/route/future/engine/impl/ShadowNonMDLStatementRoutingEngine.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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.shardingsphere.shadow.route.future.engine.impl;
-
-import org.apache.shardingsphere.infra.route.context.RouteContext;
-import org.apache.shardingsphere.shadow.route.future.engine.ShadowRouteEngine;
-import org.apache.shardingsphere.shadow.rule.ShadowRule;
-
-/**
- * Shadow non-MDL statement routing engine.
- */
-public final class ShadowNonMDLStatementRoutingEngine implements 
ShadowRouteEngine {
-    
-    @Override
-    public void route(final RouteContext routeContext, final ShadowRule 
shadowRule) {
-        // TODO decorate route in non-MDL statement case
-    }
-}
diff --git 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/rule/ShadowRule.java
 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/rule/ShadowRule.java
index 06c4909..146e625 100644
--- 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/rule/ShadowRule.java
+++ 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/main/java/org/apache/shardingsphere/shadow/rule/ShadowRule.java
@@ -26,6 +26,7 @@ import 
org.apache.shardingsphere.shadow.algorithm.config.AlgorithmProvidedShadow
 import org.apache.shardingsphere.shadow.api.config.ShadowRuleConfiguration;
 import 
org.apache.shardingsphere.shadow.api.config.datasource.ShadowDataSourceConfiguration;
 import 
org.apache.shardingsphere.shadow.api.config.table.ShadowTableConfiguration;
+import org.apache.shardingsphere.shadow.api.shadow.note.NoteShadowAlgorithm;
 import org.apache.shardingsphere.shadow.rule.checker.ShadowRuleChecker;
 import org.apache.shardingsphere.shadow.spi.ShadowAlgorithm;
 import org.apache.shardingsphere.spi.ShardingSphereServiceLoader;
@@ -184,6 +185,26 @@ public final class ShadowRule implements SchemaRule, 
DataSourceContainedRule {
         return result.isEmpty() ? Optional.empty() : Optional.of(result);
     }
     
+    /**
+     * Get related note shadow algorithms.
+     *
+     * @return related note shadow algorithms
+     */
+    public Optional<Collection<ShadowAlgorithm>> 
getRelatedNoteShadowAlgorithms() {
+        Collection<ShadowAlgorithm> result = 
shadowAlgorithms.values().stream().filter(each -> each instanceof 
NoteShadowAlgorithm).collect(Collectors.toCollection(LinkedList::new));
+        return result.isEmpty() ? Optional.empty() : Optional.of(result);
+    }
+    
+    /**
+     * Get all shadow data source mappings.
+     *
+     * @return all shadow data source mappings
+     */
+    public Map<String, String> getAllShadowDataSourceMappings() {
+        return 
shadowDataSourceMappings.values().stream().collect(Collectors.toMap(ShadowDataSourceRule::getSourceDataSource,
 ShadowDataSourceRule::getShadowDataSource, (key, value) -> value,
+                LinkedHashMap::new));
+    }
+    
     @Override
     public Map<String, Collection<String>> getDataSourceMapper() {
         Map<String, Collection<String>> result = new 
HashMap<>(shadowMappings.size());
diff --git 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/test/java/org/apache/shardingsphere/shadow/algorithm/shadow/note/SimpleSQLNoteShadowAlgorithmTest.java
 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/test/java/org/apache/shardingsphere/shadow/algorithm/shadow/note/SimpleSQLNoteShadowAlgorithmTest.java
index 4e5c911..8252807 100644
--- 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/test/java/org/apache/shardingsphere/shadow/algorithm/shadow/note/SimpleSQLNoteShadowAlgorithmTest.java
+++ 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/test/java/org/apache/shardingsphere/shadow/algorithm/shadow/note/SimpleSQLNoteShadowAlgorithmTest.java
@@ -17,6 +17,7 @@
 
 package org.apache.shardingsphere.shadow.algorithm.shadow.note;
 
+import org.apache.shardingsphere.shadow.api.shadow.column.ShadowOperationType;
 import org.apache.shardingsphere.shadow.api.shadow.note.PreciseNoteShadowValue;
 import org.junit.Before;
 import org.junit.Test;
@@ -58,15 +59,15 @@ public final class SimpleSQLNoteShadowAlgorithmTest {
     }
     
     private void assertTrueCase() {
-        assertThat(shadowAlgorithm.isShadow(createShadowTableNames(), 
createNoteShadowValue("/* shadow = true */")), is(true));
-        assertThat(shadowAlgorithm.isShadow(createShadowTableNames(), 
createNoteShadowValue(" shadow = true */")), is(true));
-        assertThat(shadowAlgorithm.isShadow(createShadowTableNames(), 
createNoteShadowValue("/* shadow = true ")), is(true));
-        assertThat(shadowAlgorithm.isShadow(createShadowTableNames(), 
createNoteShadowValue(" shadow = true ")), is(true));
-        assertThat(shadowAlgorithm.isShadow(createShadowTableNames(), 
createNoteShadowValue(" shadow = true, aaa  = bbb ")), is(true));
+        assertThat(shadowAlgorithm.isShadow(createShadowTableNames(), 
createNoteShadowValue("/* shadow: true */")), is(true));
+        assertThat(shadowAlgorithm.isShadow(createShadowTableNames(), 
createNoteShadowValue(" shadow :true */")), is(true));
+        assertThat(shadowAlgorithm.isShadow(createShadowTableNames(), 
createNoteShadowValue("/* shadow : true ")), is(true));
+        assertThat(shadowAlgorithm.isShadow(createShadowTableNames(), 
createNoteShadowValue(" shadow:true ")), is(true));
+        assertThat(shadowAlgorithm.isShadow(createShadowTableNames(), 
createNoteShadowValue(" shadow:true, aaa:bbb ")), is(true));
     }
     
     private PreciseNoteShadowValue<String> createNoteShadowValue(final String 
sqlNote) {
-        return new PreciseNoteShadowValue<>("t_user", sqlNote);
+        return new PreciseNoteShadowValue<>("t_user", 
ShadowOperationType.NON_DML, sqlNote);
     }
     
     private Collection<String> createShadowTableNames() {
diff --git 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/test/java/org/apache/shardingsphere/shadow/route/future/engine/determiner/algorithm/NoteShadowAlgorithmDeterminerTest.java
 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/test/java/org/apache/shardingsphere/shadow/route/future/engine/determiner/algorithm/NoteShadowAlgorithmDeterminerTest.java
index 69c6677..a791f1b 100644
--- 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/test/java/org/apache/shardingsphere/shadow/route/future/engine/determiner/algorithm/NoteShadowAlgorithmDeterminerTest.java
+++ 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/test/java/org/apache/shardingsphere/shadow/route/future/engine/determiner/algorithm/NoteShadowAlgorithmDeterminerTest.java
@@ -61,7 +61,7 @@ public final class NoteShadowAlgorithmDeterminerTest {
     private Properties createProps() {
         Properties properties = new Properties();
         properties.setProperty("shadow", "true");
-        properties.setProperty("user_id", "1");
+        properties.setProperty("foo", "bar");
         return properties;
     }
 
@@ -112,7 +112,7 @@ public final class NoteShadowAlgorithmDeterminerTest {
 
     private Collection<String> createSqlNotes() {
         Collection<String> result = new LinkedList<>();
-        result.add("/*user_id=1,shadow=true*/");
+        result.add("/*foo:bar,shadow:true*/");
         return result;
     }
 }
diff --git 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/test/java/org/apache/shardingsphere/shadow/route/future/engine/dml/ShadowInsertStatementRoutingEngineTest.java
 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/test/java/org/apache/shardingsphere/shadow/route/future/engine/dml/ShadowInsertStatementRoutingEngineTest.java
index 56abc69..60aaf9b 100644
--- 
a/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/test/java/org/apache/shardingsphere/shadow/route/future/engine/dml/ShadowInsertStatementRoutingEngineTest.java
+++ 
b/shardingsphere-features/shardingsphere-shadow/shardingsphere-shadow-core/src/test/java/org/apache/shardingsphere/shadow/route/future/engine/dml/ShadowInsertStatementRoutingEngineTest.java
@@ -32,9 +32,11 @@ import org.apache.shardingsphere.shadow.rule.ShadowRule;
 import org.apache.shardingsphere.shadow.spi.ShadowAlgorithm;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExpressionSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.simple.LiteralExpressionSegment;
+import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.CommentSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SimpleTableSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.TableNameSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
+import 
org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dml.MySQLInsertStatement;
 import org.junit.Before;
 import org.junit.Test;
 
@@ -77,6 +79,12 @@ public final class ShadowInsertStatementRoutingEngineTest {
         valueExpressions.add(new LiteralExpressionSegment(21, 30, 
"orderName"));
         insertValueContexts.add(new InsertValueContext(valueExpressions, new 
ArrayList<>(), 0));
         when(result.getInsertValueContexts()).thenReturn(insertValueContexts);
+        MySQLInsertStatement mySQLInsertStatement = new MySQLInsertStatement();
+        Collection<CommentSegment> commentSegments = new LinkedList<>();
+        commentSegments.add(new CommentSegment("/*shadow:true,foo:bar*/", 0, 
20));
+        commentSegments.add(new CommentSegment("/*aaa:bbb*/", 21, 30));
+        mySQLInsertStatement.setCommentSegments(commentSegments);
+        when(result.getSqlStatement()).thenReturn(mySQLInsertStatement);
         return result;
     }
     
@@ -104,6 +112,12 @@ public final class ShadowInsertStatementRoutingEngineTest {
         assertThat(orderName.getColumn(), is("order_name"));
         assertThat(orderName.getTable(), is("t_order"));
         assertThat(orderName.getValues().iterator().next(), is("orderName"));
+        Optional<Collection<String>> sqlNotes = 
shadowRouteEngine.parseSqlNotes();
+        assertThat(sqlNotes.isPresent(), is(true));
+        assertThat(sqlNotes.get().size(), is(2));
+        Iterator<String> sqlNotesIt = sqlNotes.get().iterator();
+        assertThat(sqlNotesIt.next(), is("/*shadow:true,foo:bar*/"));
+        assertThat(sqlNotesIt.next(), is("/*aaa:bbb*/"));
     }
     
     private AlgorithmProvidedShadowRuleConfiguration 
createAlgorithmProvidedShadowRuleConfiguration() {
@@ -157,11 +171,4 @@ public final class ShadowInsertStatementRoutingEngineTest {
         assertThat(allTables.size(), is(1));
         
assertThat(allTables.iterator().next().getTableName().getIdentifier().getValue(),
 is("t_order"));
     }
-    
-    @Test
-    public void assertParseSqlNotes() {
-        Optional<Collection<String>> strings = 
shadowRouteEngine.parseSqlNotes();
-        assertThat(strings.isPresent(), is(true));
-        assertThat(strings.get().size(), is(2));
-    }
 }

Reply via email to