问答详情
源自:3-6 拦截器总结

分页拦截器怎么把记录总条数传出?


public Object intercept(Invocation invocation) throws Throwable {
		StatementHandler statementHandler = (StatementHandler)invocation.getTarget();
		MetaObject metaObject = MetaObject.forObject(statementHandler, SystemMetaObject.DEFAULT_OBJECT_FACTORY, SystemMetaObject.DEFAULT_OBJECT_WRAPPER_FACTORY);
		MappedStatement mappedStatement = (MappedStatement)metaObject.getValue("delegate.mappedStatement");
		// 配置文件中SQL语句的ID
		String id = mappedStatement.getId();
		if(id.matches(".+ByPage$")) {
			BoundSql boundSql = statementHandler.getBoundSql();
			// 原始的SQL语句
			String sql = boundSql.getSql();
			// 查询总条数的SQL语句
			String countSql = "select count(*) from (" + sql + ")a";
			Connection connection = (Connection)invocation.getArgs()[0];
			PreparedStatement countStatement = connection.prepareStatement(countSql);
			ParameterHandler parameterHandler = (ParameterHandler)metaObject.getValue("delegate.parameterHandler");
			parameterHandler.setParameters(countStatement);
			ResultSet rs = countStatement.executeQuery();
			
			Map<?,?> parameter = (Map<?,?>)boundSql.getParameterObject();
			Page page = (Page)parameter.get("page");
			if(rs.next()) {
				page.setTotalNumber(rs.getInt(1));
			}
			// 改造后带分页查询的SQL语句
			String pageSql = sql + " limit " + page.getDbIndex() + "," + page.getDbNumber();
			metaObject.setValue("delegate.boundSql.sql", pageSql);
		}
		return invocation.proceed();
	}

拦截器中 中途查询了记录总条数,若要把该总条数传给外部控制如Service层要怎么做?

想把rs.getInt(1)的值传给拦截器外部类使用

提问者:SolidCocoi 2017-01-10 13:21

个回答

  • SolidCocoi
    2017-02-13 15:30:33

    我上面给出的代码中

      Page page = (Page)parameter.get("page");// 22行

    这个page对象作用范围只是在 intercept(){}方法内,而intercept方法只是 拦截器类的一个方法(该拦截器类继承了Interceptor)并不是action 所在的类,我是想把mybatis的Mapper接口中dao操作方法返回查询结果集记录条数和查询结果集。

    核心问题就是:实现Interceptor接口时,自定义步骤中产生的变量如何传出到action方法内(该变量不是查询结果集)

    HashMap<Integer,Message> map =new HashMap<Integer,Message>();
    map= (HashMap<Integer, Message>) messageMapper.queryMessageRange(5,5,"asd");
    // 我的理解 这里的map就是返回的查询结果集。messageMapper是一个DAO实现类,内部有封装的查询方法,例如queryMessageRange()


  • morethink
    2017-02-13 01:00:01

    Page page = (Page)parameter.get("page");

    这条语句只是获取了一个page对象的一个引用,在servlet调用service,service调用dao,PageInterceptor
    拦截器拦截器拦截page,page不断的在改变,当调用完成,值就已经在最开始那个page对象里面了。

  • 水止三千
    2017-01-12 19:25:13

    setTotalNumber已经在page了,通过servlet的request方法获取,再传递给service