`
Fred_Han
  • 浏览: 148175 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

MyBatis 物理分页foreach 参数失效

    博客分类:
  • WEB
 
阅读更多

场景:MyBatis 物理分页,查询条件中需要用到foreach ,参数失效,查不到结果

 

分析:把java.sql的debug打开,sql语句正常,参数也正常。debug物理分页代码,setParameters时,boundSql.getAdditionalParameter(propertyName)获取值始终是null,没有拿到参数。但是BoundSql的metaParameters中可以看到相关的参数值。

解决方法:

BoundSql countBS = new BoundSql(configuration, sql, boundSql.getParameterMappings(), parameterObject);
            Field metaParamsField = ReflectUtil.getFieldByFieldName(boundSql, "metaParameters");
            if (metaParamsField != null) {
                MetaObject mo = (MetaObject) ReflectUtil.getValueByFieldName(boundSql, "metaParameters");
                ReflectUtil.setValueByFieldName(countBS, "metaParameters", mo);
            }
            setParameters(prepStat, configuration, countBS, parameterObject);

 

ReflectUtil 代码:

 

public class ReflectUtil {
    /**
     * 获取obj对象fieldName的Field
     *
     * @param obj
     * @param fieldName
     * @return
     */
    public static Field getFieldByFieldName(Object obj, String fieldName) {
        for (Class<?> superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) {
            try {
                return superClass.getDeclaredField(fieldName);
            } catch (NoSuchFieldException e) {
            }
        }
        return null;
    }

    /**
     * 获取obj对象fieldName的属性值
     *
     * @param obj
     * @param fieldName
     * @return
     * @throws SecurityException
     * @throws NoSuchFieldException
     * @throws IllegalArgumentException
     * @throws IllegalAccessException
     */
    public static Object getValueByFieldName(Object obj, String fieldName) throws SecurityException,
            NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
        Field field = getFieldByFieldName(obj, fieldName);
        Object value = null;
        if (field != null) {
            if (field.isAccessible()) {
                value = field.get(obj);
            } else {
                field.setAccessible(true);
                value = field.get(obj);
                field.setAccessible(false);
            }
        }
        return value;
    }

    /**
     * 设置obj对象fieldName的属性值
     *
     * @param obj
     * @param fieldName
     * @param value
     * @throws SecurityException
     * @throws NoSuchFieldException
     * @throws IllegalArgumentException
     * @throws IllegalAccessException
     */
    public static void setValueByFieldName(Object obj, String fieldName, Object value) throws SecurityException,
            NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
        Field field = getFieldByFieldName(obj, fieldName);
        if (field.isAccessible()) {
            field.set(obj, value);
        } else {
            field.setAccessible(true);
            field.set(obj, value);
            field.setAccessible(false);
        }
    }

}

 

 

分享到:
评论
4 楼 wujingyong 2016-01-25  
zhuzf 写道
  , 我的就是这个问题,解决了,3Q

具体是怎么解决的啊

楼主说的是在哪里添加代码,没看太懂。我的是pagehelper4.1.1
3 楼 xuqiao2009 2016-01-02  
    高人高人,佩服

void processIntercept(final Object[] queryArgs) {
//queryArgs = query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler)
MappedStatement ms = (MappedStatement)queryArgs[MAPPED_STATEMENT_INDEX];
Object parameter = queryArgs[PARAMETER_INDEX];
final RowBounds rowBounds = (RowBounds)queryArgs[ROWBOUNDS_INDEX];
int offset = rowBounds.getOffset();
int limit = rowBounds.getLimit();

if(dialect.supportsLimit() && (offset != RowBounds.NO_ROW_OFFSET || limit != RowBounds.NO_ROW_LIMIT)) {
BoundSql boundSql = ms.getBoundSql(parameter);
String sql = boundSql.getSql().trim();
if (dialect.supportsLimitOffset()) {
sql = dialect.getLimitString(sql, offset, limit);
offset = RowBounds.NO_ROW_OFFSET;
} else {
sql = dialect.getLimitString(sql, 0, limit);
}
limit = RowBounds.NO_ROW_LIMIT;

queryArgs[ROWBOUNDS_INDEX] = new RowBounds(offset,limit);
BoundSql newBoundSql = new BoundSql(ms.getConfiguration(),sql, boundSql.getParameterMappings(), boundSql.getParameterObject());
Field metaParamsField = ReflectUtil.getFieldByFieldName(boundSql, "metaParameters");
        if (metaParamsField != null) {
          try {
                MetaObject mo = (MetaObject) ReflectUtil.getValueByFieldName(boundSql, "metaParameters");
         
ReflectUtil.setValueByFieldName(newBoundSql, "metaParameters", mo);
MappedStatement newMs = copyFromMappedStatement(ms, new BoundSqlSqlSource(newBoundSql));
queryArgs[MAPPED_STATEMENT_INDEX] = newMs;
} catch (Exception e) {

e.printStackTrace();
}
        }
}
}
2 楼 zhuzf 2015-08-10  
  , 我的就是这个问题,解决了,3Q
1 楼 victory_yong 2013-09-18  
lz给力,foreach分页解决了,受教,受教了......

相关推荐

    mybatis物理分页插件

    mybatis-pager插件的工作原理可能是:首先,拦截MyBatis的SQL执行过程,然后根据分页参数(如当前页和每页大小)动态修改原始SQL,添加对应的分页条件。这样,数据库只需返回所需的数据,而不是全部结果集。 使用这...

    spring+mybatis实现了物理分页

    6. **控制器层处理**:Controller层接收前端请求,传递分页参数,调用Service层的方法获取分页数据,最后将结果返回给前端。 7. **前端展示**:前端接收到分页数据后,可以显示列表并提供翻页功能。需要注意的是,...

    pring_mybatis物理分页

    然后在Service层,可以通过Page对象传递分页参数,MyBatis会自动处理分页查询。 例如,在SpringMVC项目中,我们可能有以下步骤: - 创建自定义方言类,实现MyBatis的Dialect接口,覆盖`getLimitString()`方法。 - ...

    mybatis 物理分页,借助于mybatis-paginator插件

    4. **创建分页参数类**:为了传递分页参数,需要创建一个包含当前页数和每页大小的类,如`PaginationParam`,并将其作为查询方法的参数。 5. **使用插件**:在服务层或DAO层,调用Mapper的分页查询方法,传入分页...

    Spring+Springmvc+Mybatis+Shiro+Mybatis物理分页整合

    Spring+Springmvc+Mybatis+Shiro+Mybatis物理分页整合,里面没有多的测试代码,自己测试,有问题可以留言,亲测可用,我已经用到我项目,关于里面的Mybatis的分页功能是网上某个哥们的。我加入了MSSQL的部分,分页...

    06实现mybatis分页插件demo

    06实现mybatis分页插件demo06实现mybatis分页插件demo06实现mybatis分页插件demo06实现mybatis分页插件demo06实现mybatis分页插件demo06实现mybatis分页插件demo06实现mybatis分页插件demo06实现mybatis分页插件demo...

    mybatis物理分页插件--GbatisDialect

    自己写的一个mybatis物理分页插件,支持mysql,oracle,db2,ms sql server2005-2008和ms sql server2012, 由于sql server2005的分页比较独特, 暂时只支持单order by 的情况, 多个order by会报错 , mysql,oracle,db2完美...

    Mybatis通用分页插件

    Mybatis通用分页插件通过自动处理分页参数,极大地简化了这一过程。 该插件的核心功能包括: 1. **智能分页**:根据不同的数据库(如MySQL、Oracle、SQL Server等)自动生成对应的分页SQL,无需手动编写LIMIT或...

    mybatis物理分页插件-GbatisDialect

    &lt;... PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"&gt; &lt;!-- value="mssql|oracle|mysql|db2" --&gt; &lt;/configuration&gt;

    MyBatis自动分页实现

    MyBatis自动分页实现 MyBatis 是一个流行的持久层框架,它提供了强大的数据访问功能。但是,在实际应用中,分页问题经常困扰开发者。要实现分页,开发者需要手动编写代码来实现分页逻辑,这不仅增加了开发难度,也...

    Jsp+Servlet+MyBatis完成分页查询

    1. **创建JSP页面**:在JSP页面上,创建一个表单来接收用户的分页参数,如当前页和每页记录数。此外,还需展示从服务器获取的分页数据。 2. **编写Servlet**:Servlet接收到请求后,通过`HttpServletRequest`对象...

    MyBatis拦截器分页与动态修改SQL及其参数值

    在"MyBatis拦截器分页与动态修改SQL及其参数值"的主题中,我们可以深入理解以下几个关键知识点: 1. **MyBatis拦截器**:MyBatis提供了一种插件机制,即拦截器(Interceptor),它基于Java的动态代理,可以在SQL...

    Mybatis3分页代码

    在Java代码中,你可以创建一个Map对象来传递分页参数: ```java Map, Object&gt; params = new HashMap(); params.put("start", (currentPage - 1) * pageSize); params.put("limit", pageSize); params.put("dbType",...

    mybatis逻辑分页,含分页导航

    在这个例子中,`#{offset}`和`#{limit}`是分页参数,分别代表当前页的起始位置和每页的数据量。`WHERE 1=1`是为了确保即使没有其他条件,SQL语句也能正确执行。 接下来是分页导航的实现。分页导航通常包括上一页、...

    Mybatis批量foreach merge into的用法

    Mybatis批量foreach merge into的用法 Mybatis批量foreach merge into的用法是通过Mybatis的动态SQL语法foreach循环插入实现的,这种方法可以批量插入时间价格表数据。如果某个套餐的某天的价格存在,则更新,不...

    mybatis 动态sql及参数传递

    在实际开发过程中,我们往往需要编写复杂的SQL语句,拼接稍有不注意就会导致错误,Mybatis给开发者提供了动态SQL,大大降低了拼接SQL导致的错误。 动态标签 if标签 if标签通常用那个胡where语句,update语句,insert...

    mybatis不改源码实现物理分页

    插件可以通过拦截器模式实现,例如使用MyBatis的Executor拦截器接口,通过拦截 Executor 的query() 方法,在适当的时候插入分页参数。 在MyBatis的配置文件中,我们需要启用插件并注册它: ```xml &lt;!-- 可以...

    mybatis数据库分页Spring原生例子

    为了处理分页参数,可以创建一个Page对象,包含当前页码和每页大小: ```java @Service public class UserService { @Autowired private UserMapper userMapper; public List&lt;User&gt; paginate(int pageNum, int ...

Global site tag (gtag.js) - Google Analytics