--- /dev/null
+package de.example.mybatis.interceptor;
+
+import java.lang.reflect.Method;
+import java.util.Properties;
+
+import org.apache.ibatis.cache.CacheKey;
+import org.apache.ibatis.executor.Executor;
+import org.apache.ibatis.mapping.BoundSql;
+import org.apache.ibatis.mapping.MappedStatement;
+import org.apache.ibatis.plugin.Interceptor;
+import org.apache.ibatis.plugin.Intercepts;
+import org.apache.ibatis.plugin.Invocation;
+import org.apache.ibatis.plugin.Plugin;
+import org.apache.ibatis.plugin.Signature;
+import org.apache.ibatis.session.ResultHandler;
+import org.apache.ibatis.session.RowBounds;
+
+@Intercepts({@Signature(
+ type= Executor.class,
+ method = "query",
+ args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class})})
+public class ChangeQueryBoundStatementsInRunTimeInterceptor implements Interceptor {
+
+ @Override
+ public Object intercept(Invocation invocation) throws Throwable {
+ Method method = invocation.getMethod();
+ Object[] args = invocation.getArgs();
+ Object target = invocation.getTarget();
+
+ final MappedStatement stmt = (MappedStatement) args[0];
+ final Object parameter = args[1];
+ final BoundSql boundSql = stmt.getBoundSql(parameter);
+ final String sql = boundSql.getSql();
+
+ // THIS CODE IS USELESS. I WANTED TO CHANGE IN RUN TIME THE sql CODE BUT IT IS IMPOSSIBLE
+ // TO SET THE NEW sql STATEMENT TO THE CURRENT MappedStatement. Why MyBatis, whyyyyyyyyy???!!! :(
+
+ return invocation.proceed();
+ }
+
+ @Override
+ public Object plugin(Object target) {
+ return Plugin.wrap(target, this);
+ }
+
+ @Override
+ public void setProperties(Properties properties) {
+ }
+
+}
\ No newline at end of file
--- /dev/null
+package de.example.mybatis.interceptor;
+
+import java.lang.reflect.Method;
+import java.util.Properties;
+
+import org.apache.ibatis.executor.Executor;
+import org.apache.ibatis.mapping.BoundSql;
+import org.apache.ibatis.mapping.MappedStatement;
+import org.apache.ibatis.plugin.Interceptor;
+import org.apache.ibatis.plugin.Intercepts;
+import org.apache.ibatis.plugin.Invocation;
+import org.apache.ibatis.plugin.Plugin;
+import org.apache.ibatis.plugin.Signature;
+import org.apache.ibatis.session.ResultHandler;
+import org.apache.ibatis.session.RowBounds;
+
+@Intercepts({@Signature(
+ type= Executor.class,
+ method = "query",
+ args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})})
+public class ChangeQueryStatementsInRunTimeInterceptor implements Interceptor {
+
+ @Override
+ public Object intercept(Invocation invocation) throws Throwable {
+ Method method = invocation.getMethod();
+ Object[] args = invocation.getArgs();
+ Object target = invocation.getTarget();
+
+ final MappedStatement stmt = (MappedStatement) args[0];
+ final Object parameter = args[1];
+ final BoundSql boundSql = stmt.getBoundSql(parameter);
+ final String sql = boundSql.getSql();
+
+ // THIS CODE IS USELESS. I WANTED TO CHANGE IN RUN TIME THE sql CODE BUT IT IS IMPOSSIBLE
+ // TO SET THE NEW sql STATEMENT TO THE CURRENT MappedStatement. Why MyBatis, whyyyyyyyyy???!!! :(
+
+ return invocation.proceed();
+ }
+
+ @Override
+ public Object plugin(Object target) {
+ return Plugin.wrap(target, this);
+ }
+
+ @Override
+ public void setProperties(Properties properties) {
+ }
+
+}
--- /dev/null
+package de.example.mybatis.interceptor;
+
+import java.lang.reflect.Method;
+import java.util.Properties;
+
+import org.apache.ibatis.executor.Executor;
+import org.apache.ibatis.mapping.BoundSql;
+import org.apache.ibatis.mapping.MappedStatement;
+import org.apache.ibatis.plugin.Interceptor;
+import org.apache.ibatis.plugin.Intercepts;
+import org.apache.ibatis.plugin.Invocation;
+import org.apache.ibatis.plugin.Plugin;
+import org.apache.ibatis.plugin.Signature;
+
+@Intercepts({@Signature(
+ type= Executor.class,
+ method = "update",
+ args = {MappedStatement.class, Object.class})})
+public class ChangeUpdateStatementsInRunTimeInterceptor implements Interceptor {
+
+ @Override
+ public Object intercept(Invocation invocation) throws Throwable {
+ Method method = invocation.getMethod();
+ Object[] args = invocation.getArgs();
+ Object target = invocation.getTarget();
+
+ final MappedStatement stmt = (MappedStatement) args[0];
+ final Object parameter = args[1];
+ final BoundSql boundSql = stmt.getBoundSql(parameter);
+ final String sql = boundSql.getSql();
+
+ // THIS CODE IS USELESS. I WANTED TO CHANGE IN RUN TIME THE sql CODE BUT IT IS IMPOSSIBLE
+ // TO SET THE NEW sql STATEMENT TO THE CURRENT MappedStatement. Why MyBatis, whyyyyyyyyy???!!! :(
+
+ return invocation.proceed();
+ }
+
+ @Override
+ public Object plugin(Object target) {
+ return Plugin.wrap(target, this);
+ }
+
+ @Override
+ public void setProperties(Properties properties) {
+ }
+
+}
// If there is no transaction the cache is useless because after every DML will be cleaned up. Without transaction
// REUSE and SIMPLE are the same. With transaction REUSE skips the code calling getConnection. With transaction
// getConnection returns always the same connection. So, with transaction we can avoid some CPU cycles using REUSE.
+
+ // With Spring-MyBatis operations are ONLY batched when running this code in some transaction. Otherwise BATCH mode is useless
+ // because statements will be flushed once they are executed.
final Ad adTestTwo = new Ad();
adTestTwo.setAdMobileImage("bildTwo.jpg");
// WARNING!!! adTestOne.id keeps being NULL when using BATCH Executor of MyBatis!!!!
// So, this code will do ANYTHING AT ALL!!!!
// BE CAREFUL WHEN USING BATCH MODE FOR ACCESSING DATA BASES!!!!
- adMapper.updateByPrimaryKey(adTestOne);
+ long countOne = adMapper.updateByPrimaryKey(adTestOne);
// WARNING!!! adTestTwo.id keeps being NULL when using BATCH Executor of MyBatis!!!!
// So, this code will do ANYTHING AT ALL!!!!
// BE CAREFUL WHEN USING BATCH MODE FOR ACCESSING DATA BASES!!!!
adTestTwo.setAdMobileImage("updatedBildTwo.jpg");
- adMapper.updateByPrimaryKey(adTestTwo);
+ long countTwo = adMapper.updateByPrimaryKey(adTestTwo);
// IF YOU WANT BATCH MODE FOR ACCESSING DATA BASES YOUR CODE MUST BE IMPLEMENTED FOR BATCH MODE.
// I MEAN, IN THIS EXAMPLE SIMPLE MODE WILL WORK BUT BATCH MODE WILL NOT WORK IN ANY WAY!!!!
// BATCH has some implications that must not be forgotten. You can not abstract your code
// from the access mode to your data base!!!!!
+ // BATCH MODE: no transaction
+ // countOne.id = BatchExecutor.BATCH_UPDATE_RETURN_VALUE <-------------- IF YOU WANT TO USE BATCH MODE, YOUR CODE MUST BE IMPLEMENTED KNOWING THIS KIND OF STUFF!!!!
+ // But because there is no transaction statement is always flushed once it is executed.
+ // So, in BATCH mode and without transaction we do not return the number of updated rows but the statement was
+ // immediately flushed. :/
+ // BATCH MODE: transaction
+ // countOne.id = BatchExecutor.BATCH_UPDATE_RETURN_VALUE <-------------- IF YOU WANT TO USE BATCH MODE, YOUR CODE MUST BE IMPLEMENTED KNOWING THIS KIND OF STUFF!!!!
+ // SIMPLE MODE: no transaction
+ // countOne.id = 1
+ // SIMPLE MODE: transaction
+ // countOne.id = 1
+ // REUSE MODE: no transaction
+ // countOne.id = 1
+ // REUSE MODE: transaction
+ // countOne.id = 1
+
+ // With Spring-MyBatis operations are ONLY batched when running this code in some transaction. Otherwise BATCH mode is useless.
+ // because statements will be flushed once they are executed.
+
LOGGER.info("Insert two new Ads");
<plugins>
<plugin interceptor="de.example.mybatis.interceptor.ReuseBatchExecutorInterceptor">
</plugin>
+ <plugin interceptor="de.example.mybatis.interceptor.ChangeUpdateStatementsInRunTimeInterceptor">
+ </plugin>
+ <plugin interceptor="de.example.mybatis.interceptor.ChangeQueryStatementsInRunTimeInterceptor">
+ </plugin>
+ <plugin interceptor="de.example.mybatis.interceptor.ChangeQueryBoundStatementsInRunTimeInterceptor">
+ </plugin>
</plugins>
</configuration>
\ No newline at end of file