使用MyBatis进行远程网格过滤/分页/排序的极其动态查询

时间:2012-02-28 19:40:49

标签: extjs mybatis

我正在开发的项目大量使用ExtJS框架。我们有很多数据需要显示,我们通过网格实现这些数据,这些网格都有一套标准的分页,排序和过滤功能。

目前,我们的后端是PHP,我们使用的是直接SQL。我在PHP中编写了一个SQL包装器,它接受查询,过滤器列表,排序信息和页面信息,并使用原始查询作为子查询输出具有相应WHERE,ORDER BY和分页功能的查询。我应该注意到我们的项目与Oracle有关。

过滤器可以采用比较(=,<,< =,> =,>,IS NULL)或列表(IN())的形式,而排序只是一个带有方向的列。分页是开始和结束的rownumbers。

冗长的故事,我们正在使用Spring和MyBatis转向基于Java的架构。我很难弄清楚如何使用MyBatis以简单的方式实现相同的功能。包装器的好处是我们只需要编写一次基本查询,然后它就会变成网格所需的任何查询。由于我们正在谈论可能成千上万的记录,我们需要分页,将内容拉回服务器并进行基于java的过滤/排序实际上并不是一种选择。

之前有没有人解决过这个(或类似的)问题?我已经看到了MyBatis的动态SQL功能(简要地说),但它似乎并没有提供我所需要的灵活性和功能。我错了吗?

非常感谢来自经验丰富的MyBatis用户的任何指导。

我应该注意到,我们现在正在探索,并且使用ORM并不完全不在桌面上。使用Hibernate可以更轻松地完成这项工作吗?

1 个答案:

答案 0 :(得分:2)

我做的几乎完全一样(只使用Guice而不是Spring)加上我的查询是分层的(结果显示在树表中),这使问题非常复杂。

我认为MyBatis可以做得很好。 但是对于查询的动态部分,我会抛弃MyBatis amd实现它,就像你可能用PHP一样:在Java中生成语句的WHERE和ORDER BY部分。

在可重用的片段中为基本查询和基本查询本身定义mybatis结果映射,然后在映射文件中直接使用String替换:

这样的事情:

<resultMap id="TaskMap" type="de.foobar.dtos.TaskDto">
    <id column="id" property="id"/>
    <result column="description" property="description"/>
    ...
</resultMap>

<sql id="baseQuery">
    select id, description from tasks
</sql>

<select id="selectSingle" resultMap="Task2Map">
    select bq.*
    from (
            <include refid="baseQuery"/>
         ) bq
    where bq.id = #{id}
</select>

<select id="selectAll" resultMap="Task2Map">
    select bq.*
    from (
            <include refid="baseQuery"/>
         ) bq
    where ${filterClause}
    order by ${orderByClause}
</select>

对于分页,你必须包含另一个子查询以使用奇怪的oracle rownum构造(但你可能已经这样做了)。

当然也适用通常的警告:MyBatis中的$ {}语法正在执行字符串替换(而不是预准备语句的参数),因此在清理用户输入时要小心,以避免sql注入。