Mybatis-XML包含总条数的分页数据查询

—— Mybatis入门写法记录

momo314相同方式共享非商业用途署名转载

最近转java,开始接触Mybatis,感觉之前在C#里面写的很溜的分页查询不太会写了,这个应该是比较入门的写法,反正我是菜鸡一个,就暂且记录一下备查。

需求很简单,在一一个方法中,传入查询参数,一次性返回需要的当页数据列表和数据总条数。

假设查询参数,返回值如下:

/**
 * AppUser表 查询参数, 省略 get / set 方法...
 */
public class AppUserQueryApiModel {
    private String name;
    private String age;
    private Integer pageIndex;
    private Integer pageSize;
}

/**
 * AppUser表 列表查询返回实体, 省略 get / set 方法...
 */
public class AppUserItemModel {
    private Integer id;
    private String name;
    private Integer age;
    private String mobile;
}

/**
 * 通用分页数据类, 省略 get / set 方法...
 */
public class Paged<T> {
    private int total;
    private List<T> data;
}

又假设,Mybatis的分页查询方法定义如下:

/**
 * 因为Mapper类是Mybatis自动生成的,再次生成会被覆盖,
 * 所以用 MapperExt 继承 Mapper, 并在 MapperExt 中自定义查询方法
 */
public interface AppUserMapperExt extends AppUserMapper {
    /**
     * AppUser 表 分页查询方法,带总条数
     */
    Paged<AppUserItemModel> query(AppUserQueryApiModel model);
}

Mybatis-XML定义如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.namespace.repository.mapperext.OrderInfoMapperExt" >
  <!-- 返回值定义 -->
  <resultMap id="PagedAppUser" type="com.namespace.dto.Paged">
    <collection property="data" resultSet="data" ofType="com.namespace.dto.output.AppUserItemModel">
      <id column="id" property="id" jdbcType="INTEGER" />
      <result column="name" property="name" jdbcType="VARCHAR" />
      <result column="age" property="age" jdbcType="INTEGER" />
      <result column="mobile" property="mobile" jdbcType="VARCHAR" />
    </collection>
  </resultMap>
  <!-- 分页查询方法实现(返回数据和总条数) -->
  <select id="query" parameterType="com.namespace.dto.input.OrderQueryApiModel"
         resultSets="total,data", resultMap="PagedAppUser">
    select 
      count(1) as total
    from app_user au
    where au.deleted = 0
    <if test="name != null and name != ''">
      and au.`name` like concat('%',#{name},'%')
    </if>
    <if test="age != null and age != 0">
      and au.age > #{age}
    </if>
    ;

    select
      au.id,
      au.`name`,
      au.age,
      au.mobile
    from app_user au
    where au.deleted = 0
    <if test="name != null and name != ''">
      and au.`name` like concat('%',#{name},'%')
    </if>
    <if test="age != null and age != 0">
      and au.age > #{age}
    </if>
    order by au.id desc
    limit ${(pageIndex - 1) * pageSize}, ${pageSize};
  </select>
</mapper>

基于AppUserMapperExt extends AppUserMapper同样的理由,这里的XML也继承自Mybatis自动生成的XML文件。

注意事项:

  • Mybatis-XML中select节点中的id属性值需要与分页查询方法的名字保持一致。
  • Mybatis-XML中select节点中的parameterType属性中填写分页查询方法的参数类的完全限定名,如果该类继承自别的类,写当前类,不要写父类。
  • Mybatis-XML中select节点中的resultSets属性中定义两个结果集的名称,分别代表数据总条数和分页数据列表,且顺序必须与XML中的SQL语句顺序一致。
  • 数据总条数的SQL查询语句的输出列必须要有列名,且列名需要与resultSets中定义的相同,比如上面的total
  • Mybatis-XML中select中的resultMap属性值,为resultMap节点的id属性。
  • Mybatis-XML中resultMap节点定义了分页查询方法的返回值类型的结构,如果有继承的话:
    • 其中type属性填写父类(Paged)的完全限定名;
    • collection节点来定义其中的列表数据子类(AppUserItemModel)的结构;
    • collection节点的property属性填写父类(Paged)中列表项的字段名;
    • collection节点的ofType属性填写列表子类(AppUserItemModel)的完全限定名。
  • 两条SQL中间记得写分号。
  • 数据库连接字符串中需要指定allowMultiQueries=true, 例如:

    spring.datasource.url=jdbc:mysql://127.0.0.1:3306/dbname?allowMultiQueries=true
    
✎﹏ 本文来自于 momo314和他们家的猫,文章原创,转载请注明作者并保留原文链接。