将SET语句与MyBatis一起使用

时间:2011-06-23 08:46:07

标签: java mybatis

(我在Teradata v12上使用MyBatis v3,Java SE v6,Tomcat v6和Spring v3。)

我当前项目的技术要求之一是使用Teradata中的查询条带功能。这可以通过在需要时运行如下语句来完成:

SET QUERY_BAND='someKey=someValue;' FOR TRANSACTION;

我希望为我的所有通话设置一个查询带。但是,我不确定如何以干净和可重用的方式添加此功能,而无需将其添加到我的映射器文件中的每个<select>语句中,如下所示:

<sql id="queryBand"> 
    SET QUERY_BAND='k=v;' FOR TRANSACTION; 
</sql>

<select ...> 
   <include refid="queryBand"/> 
   ... some SQL performing a SELECT 
</select>

我的问题是: 1)查询带的格式在我的所有映射器XML文件中是相同的,除了k&amp; v,我想根据<select>(等)来定制。我不确定如何在不传递k和v值的情况下进行此自定义,这会使我的映射器界面变得混乱。 2)上面的代码有重复让我感到不安。开发人员必须记住包含queryBand SQL,有人会在某个阶段忘记它(墨菲定律)。

有人能指出我以更清洁的方式实施查询条带的解决方案吗?

2 个答案:

答案 0 :(得分:0)

假设每个SQL字符串都应附加到查询带中。我会尝试在myBatis / Spring中找到一个方法。使用Spring的AOP可以拦截此方法,并将其结果附加到查询带并返回以进行进一步计算。

找到拦截方法可能很难,但并非不可能。下载所有依赖源并正确链接它们(使用Maven这应该是微不足道的,但在Eclipse中也不是那么难),在调试模式下运行代码并寻找合适的方法。

答案 1 :(得分:0)

解决方案是使用MyBatis Interceptor插件。例如,以下内容:

import java.sql.Connection;
import java.sql.Statement;
import java.util.Properties;

import org.apache.ibatis.executor.statement.StatementHandler;
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=StatementHandler.class,
        method = "prepare",
        args={ Connection.class })})
public class StatementInterceptor implements Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        Connection conn = (Connection) invocation.getArgs()[0];
        Statement stmt = conn.createStatement();
        stmt.executeUpdate("SET QUERY_BAND = 'k=v;' FOR TRANSACTION;");
        return invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {}
}