org.apache.ibatis.executor.statement.RoutingStatementHandler Java Examples

The following examples show how to use org.apache.ibatis.executor.statement.RoutingStatementHandler. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: PageInterceptor.java    From dubbo-mock with Apache License 2.0 6 votes vote down vote up
/**
 * 拦截后要执行的方法
 */
@Override
public Object intercept(Invocation invocation) throws Throwable {
    Page<?> page = PageThreadLocal.getThreadLocalPage();
    if (page == null) {
        return invocation.proceed();
    }
    PageThreadLocal.removeThreadLocalPage();
    RoutingStatementHandler handler = (RoutingStatementHandler) invocation.getTarget();
    // 通过反射获取到当前RoutingStatementHandler对象的delegate属性
    StatementHandler delegate = (StatementHandler) ReflectUtil.getFieldValue(handler, "delegate");
    BoundSql boundSql = delegate.getBoundSql();
    MappedStatement mappedStatement = (MappedStatement) ReflectUtil.getFieldValue(delegate, "mappedStatement");
    // 获取当前要执行的Sql语句,也就是我们直接在Mapper映射语句中写的Sql语句
    String sql = boundSql.getSql();
    // 是否查询总页数和总数据 默认为TRUE
    if (page.getTotalFlag()) {
        // 给当前的page参数对象设置总记录数
        this.setTotalRecord(page, mappedStatement, boundSql, sql);
    }

    String pageSql = this.getPageSql(sql, page);
    // 利用反射设置当前BoundSql对应的sql属性为我们建立好的分页Sql语句
    ReflectUtil.setFieldValue(boundSql, "sql", pageSql);
    return invocation.proceed();
}
 
Example #2
Source File: MyBatisInterceptor.java    From open-cloud with MIT License 5 votes vote down vote up
@Override
public Object intercept(Invocation invocation) throws Throwable {
    Connection o = (Connection) invocation.getArgs()[0];
    invocation.getArgs();
    try {
        RoutingStatementHandler handler = (RoutingStatementHandler) invocation.getTarget();
        String sql = handler.getBoundSql().getSql();
        return invocation.proceed();
    } catch (Exception e) {
        logger.error("执行失败!", e);
        return null;
    } finally {

    }
}
 
Example #3
Source File: PageInterceptor.java    From ssm-demo with Apache License 2.0 5 votes vote down vote up
/**
 * 拦截后要执行的方法
 */
public Object intercept(Invocation invocation) throws Throwable {
	// 对于StatementHandler其实只有两个实现类,
	// 一个是RoutingStatementHandler,
	// 另一个是抽象类BaseStatementHandler,
	// BaseStatementHandler有三个子类,分别是SimpleStatementHandler,PreparedStatementHandler和CallableStatementHandler,
	// SimpleStatementHandler是用于处理Statement的,
	// PreparedStatementHandler是处理PreparedStatement的,
	// 而CallableStatementHandler是 处理CallableStatement的。
	// Mybatis在进行Sql语句处理的时候都是建立的RoutingStatementHandler,而在RoutingStatementHandler里面拥有一个StatementHandler类型的delegate属性,
	// RoutingStatementHandler会依据Statement的不同建立对应的BaseStatementHandler,
	// 即SimpleStatementHandler、PreparedStatementHandler或CallableStatementHandler,
	// 在RoutingStatementHandler里面所有StatementHandler接口方法的实现都是调用的delegate对应的方法。
	// 我们在PageInterceptor类上已经用@Signature标记了该Interceptor只拦截StatementHandler接口的prepare方法,
	// 又因为Mybatis只有在建立RoutingStatementHandler的时候是通过Interceptor的plugin方法进行包裹的,
	// 所以我们这里拦截到的目标对象肯定是RoutingStatementHandler对象。
	RoutingStatementHandler handler = (RoutingStatementHandler) invocation.getTarget();

	// 通过反射获取到当前RoutingStatementHandler对象的delegate属性
	StatementHandler delegate = (StatementHandler) ReflectUtil.getFieldValue(handler, "delegate");

	// 获取到当前StatementHandler的boundSql,这里不管是调用handler.getBoundSql()还是直接调用delegate.getBoundSql()结果是一样的,因为之前已经说过了
	// RoutingStatementHandler实现的所有StatementHandler接口方法里面都是调用的delegate对应的方法。
	BoundSql boundSql = delegate.getBoundSql();

	// 拿到当前绑定Sql的参数对象,就是我们在调用对应的Mapper映射语句时所传入的参数对象
	Object obj = boundSql.getParameterObject();

	// 这里我们简单的通过传入的是Page对象就认定它是需要进行分页操作的。
	if (obj instanceof Page<?>) {

		Page<?> page = (Page<?>) obj;

		// 通过反射获取delegate父类BaseStatementHandler的mappedStatement属性
		MappedStatement mappedStatement = (MappedStatement) ReflectUtil.getFieldValue(delegate, "mappedStatement");

		// 拦截到的prepare方法参数是一个Connection对象
		Connection connection = (Connection) invocation.getArgs()[0];

		// 获取当前要执行的Sql语句,也就是我们直接在Mapper映射语句中写的Sql语句
		String sql = boundSql.getSql();

		// 给当前的page参数对象设置总记录数
		this.setTotalRecord(page, mappedStatement, connection);

		// 获取分页Sql语句
		String pageSql = this.getPageSql(page, sql);

		// 利用反射设置当前BoundSql对应的sql属性为我们建立好的分页Sql语句
		ReflectUtil.setFieldValue(boundSql, "sql", pageSql);

	}

	return invocation.proceed();
}
 
Example #4
Source File: DialectStatementHandlerInterceptor.java    From layui-admin with MIT License 5 votes vote down vote up
public Object intercept(Invocation invocation) throws Throwable {
	RoutingStatementHandler statement = (RoutingStatementHandler) invocation
			.getTarget();
	if ("true".equals(debug)) {
		log.info("Executing SQL: {}", statement.getBoundSql().getSql().replaceAll("\\s+", " "));
		log.info("\twith params: {}", statement.getBoundSql().getParameterObject());
	}
	return invocation.proceed();
}
 
Example #5
Source File: PreparePaginationInterceptor.java    From Shop-for-JavaWeb with MIT License 5 votes vote down vote up
@Override
    public Object intercept(Invocation ivk) throws Throwable {
        if (ivk.getTarget().getClass().isAssignableFrom(RoutingStatementHandler.class)) {
            final RoutingStatementHandler statementHandler = (RoutingStatementHandler) ivk.getTarget();
            final BaseStatementHandler delegate = (BaseStatementHandler) Reflections.getFieldValue(statementHandler, DELEGATE);
            final MappedStatement mappedStatement = (MappedStatement) Reflections.getFieldValue(delegate, MAPPED_STATEMENT);

//            //拦截需要分页的SQL
////            if (mappedStatement.getId().matches(_SQL_PATTERN)) { 
//            if (StringUtils.indexOfIgnoreCase(mappedStatement.getId(), _SQL_PATTERN) != -1) {
                BoundSql boundSql = delegate.getBoundSql();
                //分页SQL<select>中parameterType属性对应的实体参数,即Mapper接口中执行分页方法的参数,该参数不得为空
                Object parameterObject = boundSql.getParameterObject();
                if (parameterObject == null) {
                    log.error("参数未实例化");
                    throw new NullPointerException("parameterObject尚未实例化!");
                } else {
                    final Connection connection = (Connection) ivk.getArgs()[0];
                    final String sql = boundSql.getSql();
                    //记录统计
                    final int count = SQLHelper.getCount(sql, connection, mappedStatement, parameterObject, boundSql, log);
                    Page<Object> page = null;
                    page = convertParameter(parameterObject, page);
                    page.setCount(count);
                    String pagingSql = SQLHelper.generatePageSql(sql, page, DIALECT);
                    if (log.isDebugEnabled()) {
                        log.debug("PAGE SQL:" + pagingSql);
                    }
                    //将分页sql语句反射回BoundSql.
                    Reflections.setFieldValue(boundSql, "sql", pagingSql);
                }
                
                if (boundSql.getSql() == null || "".equals(boundSql.getSql())){
                    return null;
                }
                
            }
//        }
        return ivk.proceed();
    }
 
Example #6
Source File: SQLRouterInterceptor.java    From dubbox with Apache License 2.0 4 votes vote down vote up
public Object intercept(Invocation invocation) throws Throwable {
	Object result = null;

	if (invocation.getTarget() instanceof RoutingStatementHandler) {
		RoutingStatementHandler statementHandler = (RoutingStatementHandler) invocation.getTarget();
		StatementHandler delegate = (StatementHandler) ReflectionUtil.getFieldValue(statementHandler, "delegate");
		BoundSql boundSql = delegate.getBoundSql();

		// 拦截到的prepare方法参数是一个Connection对象
		Connection connection = (Connection) invocation.getArgs()[0];
		String sql = boundSql.getSql();

		// 1、 如果前端有指定路由则,优先采用指定的路由
		if (RouterContext.containsKey(RouterConsts.ROUTER_KEY) && !hasAnnotation(sql)) {
			RouterInfo routerInfo = RouterContext.get(RouterConsts.ROUTER_KEY);
			sql = new StringBuilder(routerInfo.getSqlrouter()).append(sql).toString();

			// 利用反射设置当前BoundSql对应的sql属性为我们建立好的分页Sql语句
			ReflectionUtil.setFieldValue(boundSql, "sql", sql);
		}

		// 2、如果没有路由信息,对只读事物添加读取从库的路由
		if (!hasAnnotation(sql) && connection.isReadOnly()) {

			// 获取当前要执行的Sql语句,也就是我们直接在Mapper映射语句中写的Sql语句
			sql = msHint.genRouteInfo(MasterSlaveHint.SLAVE, sql);

			// 利用反射设置当前BoundSql对应的sql属性为我们建立好的分页Sql语句
			ReflectionUtil.setFieldValue(boundSql, "sql", sql);
		}

		result = invocation.proceed();

		// if (isDML(sql) &&
		// !RouterContext.containsKey(RouterConsts.ROUTER_KEY)) {
		// 如果更改执行的是DML语句,则设置后续的CRUD路由到master
		// String appName = PropertiesUtil.get("app.name");
		// //TODO这里可能需要针对应用来进行主从路由,存在一条链路路由到多个应用的不同DB中
		// RouterContext.put(RouterConsts.ROUTER_KEY,
		// msHint.getRouteMasterHint());
		// }

	} else {
		result = invocation.proceed();
	}

	return result;
}
 
Example #7
Source File: PagePlugin.java    From cms with Apache License 2.0 4 votes vote down vote up
@SuppressWarnings("unchecked")
	public Object intercept(Invocation invocation) throws Throwable {

		if (invocation.getTarget() instanceof RoutingStatementHandler) {
			RoutingStatementHandler statementHandler = (RoutingStatementHandler) invocation.getTarget();
			BaseStatementHandler delegate = (BaseStatementHandler) ReflectHelper.getValueByFieldName(statementHandler,
					"delegate");
			MappedStatement mappedStatement = (MappedStatement) ReflectHelper.getValueByFieldName(delegate,
					"mappedStatement");

			if (mappedStatement.getId().matches(pageSqlId)) {
				BoundSql boundSql = delegate.getBoundSql();
				Object parameterObject = boundSql.getParameterObject();
				if (parameterObject == null) {
					throw new NullPointerException("parameterObject is null.");
				} else {
					Connection connection = (Connection) invocation.getArgs()[0];
					String sql = boundSql.getSql();
					String countSql="select count(0) from (" + sql + ") tmp_count ";
					/*if ("mysql".equals(dialect)) {
						
					} else if ("oracle".equals(dialect)) {
					}*/
					PreparedStatement countStmt = connection.prepareStatement(countSql);
					BoundSql countBS = new BoundSql(mappedStatement.getConfiguration(), countSql,
							boundSql.getParameterMappings(), parameterObject);
					setParameters(countStmt, mappedStatement, countBS, parameterObject);
					ResultSet rs = countStmt.executeQuery();
					int count = 0;
					if (rs.next()) {
						count = rs.getInt(1);
					}
					rs.close();
					countStmt.close();

					Page page = null;
					if (parameterObject instanceof Page) {
						page = (Page) parameterObject;
						page.setTotalResult(count);
					} else if (parameterObject instanceof Map) {
						Map<String, Object> map = (Map<String, Object>) parameterObject;
						page = (Page) map.get("page");
						if (page == null)
							page = new Page();
						page.setTotalResult(count);
					} else {
						Field pageField = ReflectHelper.getFieldByFieldName(parameterObject, "page");
						if (pageField != null) {
							page = (Page) ReflectHelper.getValueByFieldName(parameterObject, "page");
							if (page == null)
								page = new Page();
							page.setTotalResult(count);
							ReflectHelper.setValueByFieldName(parameterObject, "page", page);
						} else {
							throw new NoSuchFieldException(parameterObject.getClass().getName());
						}
					}
					String pageSql = generatePageSql(sql, page);
					ReflectHelper.setValueByFieldName(boundSql, "sql", pageSql);
				}
			}
		}

//		 Object result = invocation.proceed(); //执行请求方法,并将所得结果保存到result中
//		    if (result instanceof ArrayList) {
//		        ArrayList resultList = (ArrayList) result;
//		        for (int i = 0; i < resultList.size(); i++) {
//		            if (resultList.get(i) instanceof Map) {
//		                Map resultMap = (Map) resultList.get(i);
//		                resultMap.put("CERT_NO", "这个是加密结果"); //取出相应的字段进行加密
//		            }
//		        }
//		    }
		
		return invocation.proceed();
	}
 
Example #8
Source File: QueryInformation.java    From sinavi-jfw with Apache License 2.0 4 votes vote down vote up
private StatementHandler getConcreteStatementHandler(StatementHandler handler) throws Exception {
    RoutingStatementHandler routingStatementHandler = (RoutingStatementHandler)handler;
    Field filed = routingStatementHandler.getClass().getDeclaredField("delegate");
    filed.setAccessible(true);
    return (StatementHandler)filed.get(routingStatementHandler);        
}