com.github.antelopeframework.mybatis.criterion.plugin.CriteriaPlugin Maven / Gradle / Ivy
package com.github.antelopeframework.mybatis.criterion.plugin;
import java.sql.PreparedStatement;
import java.sql.Statement;
import java.util.Properties;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.executor.statement.StatementHandler;
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;
import com.github.antelopeframework.mybatis.criterion.CriteriaQueryTranslator;
import com.github.antelopeframework.mybatis.criterion.TypedValue;
import com.github.antelopeframework.mybatis.paged.PagedQueryRunner;
/**
* MyBatis Criteria Query Plugin.
*
* 功能说明:
*
*
* 拦截MyBatis的两个方法执行:
*
* - {@link Executor#query(MappedStatement, Object, RowBounds, ResultHandler)}
* - {@link StatementHandler#query(Statement, ResultHandler)}
*
*
* 配置方式:
*
*
* <plugins>
* <plugin interceptor="com.autonavi.db.mybatis.criterion.plugin.CriteriaPlugin"></plugin>
* </plugins>
*
*
* 分页插件:
*
*
* 分页插件可选配com.github.pagehelper
使用; pagehelper
的maven依赖配置为:
*
* <dependency>
* <groupId>com.github.pagehelper</groupId>
* <artifactId>pagehelper</artifactId>
* <version>4.1.3</version>
* </dependency>
*
*
* 使用此分页插件时, 注意配置顺序: com.github.pagehelper.PageHelper
要配置在{@lin CriteriaPlugin}后边。
*
* <plugins>
* <plugin interceptor="com.autonavi.db.mybatis.criterion.plugin.CriteriaPlugin"></plugin>
* <plugin interceptor="com.github.pagehelper.PageHelper"></plugin>
* </plugins>
*
*
* 示例:
*
*
* MyBatis XML 配置:
*
*
* <mapper namespace="----">
* <sql id="criteriaQueryCondition">
* <if test="@com.autonavi.db.mybatis.criterion.plugin.CriteriaPlugin@isCriteriaQuery()">
* ${com.autonavi.db.mybatis.criterion.plugin.CriteriaPlugin@getQueryCondition()}
* </if>
* </sql>
* <select id="findByCriteria" resultType="hashmap">
* select * from t_test_table <include refid="criteriaQueryCondition"></include>
* </select>
* </mapper>
*
*
* java 代码:
*
*
* List
*
* 使用Criteria查询时, 其他参数都会失效, 仅使用Criteria中的参数作为查询约束.
*
* 分页查询的使用方法请参考: {@link PagedQueryRunner}
*
* @author yangzhi.yzh
*
*/
@Intercepts( {
@Signature(method = "query", type = Executor.class, args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class }),
@Signature(method = "query", type = StatementHandler.class, args = { Statement.class, ResultHandler.class }),
})
public class CriteriaPlugin implements Interceptor {
/**
* 是否为Criteria Query.
*
* @return
*/
public static boolean isCriteriaQuery() {
InterceptorContext context = InterceptorContextHelper.get();
return context == null ? false : context.isCriteriaQuery();
}
/**
*
* @return
*/
public static String getQueryCondition() {
InterceptorContext context = InterceptorContextHelper.get();
CriteriaQueryTranslator queryTranslator = context == null ? null : context.getQueryTranslator();
return queryTranslator == null ? "" : queryTranslator.getQueryCondition();
}
/**
*
* @return
*/
public static TypedValue[] getQueryParams() {
InterceptorContext context = InterceptorContextHelper.get();
CriteriaQueryTranslator queryTranslator = context == null ? null : context.getQueryTranslator();
return queryTranslator != null ? queryTranslator.getQueryParams() : null;
}
@Override
public Object intercept(Invocation invocation) throws Throwable {
InterceptorContextHelper.setContext();
try {
Object target = invocation.getTarget();
if (target instanceof Executor) {
return doExecutorIntercept(invocation);
} else {
return doStatementHandlerIntercept(invocation);
}
} finally {
InterceptorContextHelper.removeContext();
}
}
/**
*
* @param invocation
* @return
* @throws Throwable
*/
private Object doExecutorIntercept(Invocation invocation) throws Throwable {
InterceptorContext context = InterceptorContextHelper.get();
//~ Criteria查询逻辑
context.initCriteriaQuery(null, invocation);
//~ 分页插件逻辑
context.initPagedQuery(invocation);
return invocation.proceed();
}
/**
*
* @param invocation
* @return
* @throws Throwable
*/
private Object doStatementHandlerIntercept(Invocation invocation) throws Throwable {
InterceptorContext context = InterceptorContextHelper.get();
Statement stm = (Statement) invocation.getArgs()[0];
if (stm instanceof PreparedStatement && context.isCriteriaQuery()) {
PreparedStatement pstm = (PreparedStatement) stm;
int index = 1;
TypedValue[] queryParams = CriteriaPlugin.getQueryParams();
if (queryParams != null) {
for (TypedValue value : queryParams) {
if (value == null) {
continue;
}
//org.postgresql.util.PSQLException: Can't infer the SQL type to use for an instance of java.util.Date. Use setObject() with an explicit Types value to specify the type to use.
Object v = value.getValue();
if (v != null && v instanceof java.util.Date) {
java.util.Date date = (java.util.Date) v;
pstm.setDate(index, new java.sql.Date(date.getTime()));
} else {
pstm.setObject(index, value.getValue());
}
index ++;
}
}
if (!context.isPagedCountQuery()) {
InterceptorContext.setPageQueryLimitParams(index, pstm);
}
}
return invocation.proceed();
}
@Override
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
@Override
public void setProperties(Properties properties) {
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy