(我在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,有人会在某个阶段忘记它(墨菲定律)。
有人能指出我以更清洁的方式实施查询条带的解决方案吗?
答案 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) {}
}