mybatis详述

一、引言

1.1 什么是框架?

软件的半成品,解决了软件开发过程当中的普适性问题,从而简化了开发步骤,提供了开发的效率。

1.2 什么是ORM框架?

  • ORM (Object Relational Mapping) 对象关系映射,将程序中的一个对象与表中的一行数据一 一对应
  • ORM框架提供了持久化类与表的映射关系,在运行时参照映射文件的信息把对象持久化到数据库中

1.3使用JDBC完成ORM操作的缺点?

  • 存在大量的冗余代码。
  • 手工创建Connection、Statement 等。
  • 手工将结果集封装成实体对象。
  • 查询效率低,没有对数据访问进行过优化(Not Cache)。

二、MyBatis框架

2.1概念

  • MyBatis本是Apache软件基金会的一个开源项目iBatis, 2010年这个项目由apache software foundation迁移到了Google Code,并且改名为MyBatis。2013年11 月迁移到Github。
  • MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。
  • MyBatis 对原有JDBC操作进行了封装,几乎消除了所有JDBC代码,使开发者只需关注SQL本身。
  • MyBatis可以使用 简单的XML或Annotation来配置执行SQL,并自动完成ORM操作,将执行结果返回。

2.2 MyBatis开发步骤

  1. 加载mybatis的依赖
  2. 配置mybatis-config.xml
  3. 开发dao层接口
  4. 编写mapping映射文件
  5. 将mapping映射文件添加到mybatis-config.xml中
  6. 编写调用程序测试mybatis的dao层开发

示例:

  • 加载mybatis的依赖
<!--    添加mybatis依赖-->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.4.6</version>
    </dependency>
  • 配置mybatis-config.xml
    • 注意文件名及头部格式不可变
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
        
<!--MyBatis配置-->
<configuration>
<!--JDBC环境配置、选中默认环境-->
    <environments default="development">
    <!--MySq1数据库环境配置-->
        <environment id="development">
        <!--事务管理-->
            <transactionManager type="JDBC"/>
            <!--连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/j2205"/>
                <property name="username" value="root"/>
                <property name="password" value="root123"/>
            </dataSource>
        </environment>
    </environments>

<!--Mapper注册-->
    <mappers>
<!--        添加映射文件到数据库配置中-->
        <mapper resource="mapping/UserInfoMapper.xml"/>
    </mappers>
</configuration>
  • 开发dao层接口
	/**
	* 全查 
	* @return UserInfo 类型的对象集合
	*/
	public List<UserInfo> findAllUsers();
  • 编写mapping映射文件
    • 注意: mapper. xml默认建议存放在resources中,路径不能以 / 开头
<?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">
        <!--namespace 所需实现的接口全限定名-->
<mapper namespace="com.xcu.mybatis.dao.UserInfoMapper">
	<!--id =所需重写的接口抽象方法,resultType =查询后所需返回的对象类型-->
   <select id="findAllUsers"   resultType="com.xcu.mybatis.entity.UserInfo" >
       select * from userinfo 
   </select>
</mapper>
  • 注册Mapper
    • 将Mapper.xml注册到mybatis- config.xml中
<!--        添加映射文件到数据库配置中-->
        <mapper resource="mapping/UserInfoDao.xml"/>
  • 编写调用程序测试mybatis的dao层开发
  @Test
    public void testFindAllUsers() throws IOException {
//    1. 加载数据库配置 
        InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
//    2. 根据数据库配置的文件流创建连接工场对象
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//    3. 从连接(会话)工厂获取连接(会话) 
        SqlSession session = sqlSessionFactory.openSession();
//    4. 从连接中获取指定的mybatis实现的接口实例
        UserInfoDao userInfoDao = session.getMapper(UserInfoDao.class);
//        调用接口对象获取结果
        List<UserInfo> allUsers = userInfoDao.findAllUsers();
        System.out.println(allUsers);
//        释放资源 7
        session.close();

    }

2.3 如何编写mybatis映射文件(规范)

  • 映射文件放在maven项目的resouces目录下
  • 映射文件的命名与接口名相同.xml后缀
  • 映射文件头部必须遵循 mybatis-3-mapper.dtd
  • 映射文件只有一个根节点mapper 且含有namespace属性(绑定的接口全限定路径名)
  • 接口中有几个方法,映射文件中就应该有相应的sql指令节点
  • 每个sql节点,必有id 取值为相应接口的抽象方法名
  • 如果接口方法有入参 ,则sql节点的入参 类型与之相匹配(单一参),且sql语句中的赋值参数#{arg}为形参变量名,若入参为对象,则赋值参数#{arg}为对象的属性名
  • 方法如有返回值 则sql节点的resultType类型与之匹配
  • 如果映射的实体成员变量与对应表字段名不一致,则需要使用resultMap节点冗余此不同,对应resultType改为resultMap
  • 在一个xml文件中,任一节点的id必须不同,因此,mybatis接口不允许重载;
  • sql节点内可以使用sql注释--,但是不能含有#{ }字样

三、mybatis-config.xml 配置补充

  • properties配置文件

    • 配置文件获取实例见下示代码
      在这里插入图片描述
  • 类型别名

    • 两种配置方式不能同时存在,以下方式二选一(类的别名、包配置自动映射类名)
    • <typeAliases>标签 需要放置在<environments>标签之前
<configuration>

    <!--添加properties配置文件路径(外部配置、动态替换)-->
    <properties resource="jdbc.properties"/>

    <!--    类型别名:以下方式 二选一 -->
    <typeAliases>
        <!--        方式一:类的别名-->
        <typeAlias type="com.qf.mybatis.entity.FilmInfo" alias="FilmInfo"/>
    </typeAliases>
    
    <typeAliases>
<!--        方式二:自动扫描包,并以包中的类名作为别名-->
        <package name="com.qf.pojo"></package>
        <package name="com.qf.dao"></package>
    </typeAliases>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <mapper resource="mapping/FilmInfoMapper.xml"/>
    </mappers>
</configuration>
  • 自动扫描映射文件
    在这里插入图片描述

四、mybatis接口与映射文件指令间 传递参数

4.1 传递单一参数

  • 默认,在映射文件中使用形参引用(Mapper.xml文件中sql语句赋值变量名,与接口抽象方法的形参变量名相同)
<!--    传递单参-->
    <select id="findOneById" resultType="FilmInfo">
        select * from filminfo where filmId=#{id}
    </select>

4.2 传递多参

  • 默认时,可以使用arg0、arg1… 接收或者param1、param2…
  • 推荐使用注解:@Param(“引用名”) 加在接口抽象方法的形参前
//    多参数
    public List<FilmInfo> findOneByTypeId(@Param("typeId") int id, @Param("ticketPrice") double ticketPrice);
<!--    传递多参数(数据类型不同)-->
    <select id="findOneByTypeId" resultType="com.qf.mybatis.entity.FilmInfo">
        select * from filminfo where typeId=#{typeId} and ticketPrice=#{ticketPrice}
    </select>

4.3 传递对象参数

  • sql赋值参数#{ }直接引用对象的成员变量名(区分大小写)
<!--    传递对象参数-->
    <insert id="addFilm" parameterType="com.qf.mybatis.entity.FilmInfo">
        insert into filminfo values(#{filmId},#{typeId},#{filmName},#{actor},#{director},#{ticketPrice})
    </insert>

4.4 传递集合参数(Map)

  • sql赋值参数#{ }需要与形参Map中的key匹配,不利于程序阅读,分层间耦合度较高
<!--    传递map参数:使用map的键值作为参数-->
    <select id="findOneByTicketPrice" resultType="com.qf.mybatis.entity.FilmInfo">
        select * from filminfo where typeId=#{id} and ticketPrice between #{lowPrice} and #{highPrice}
    </select>

五、MyBatis工具类封装

public class MyBatisUtil {
    private static final String file="mybatis-config.xml";

//    本地线程变量
    private static ThreadLocal<SqlSession> threadLocal=new ThreadLocal<>();
//    加载配置
    private static SqlSessionFactory ssf=null;
    static {
        try {
            InputStream is = Resources.getResourceAsStream(file);
            ssf = new SqlSessionFactoryBuilder().build(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //    声明成员变量
    private static SqlSession sqlSession=null;

//  获取本地线程内sqlSession
    private static void getSqlSession(){
        sqlSession=threadLocal.get();
        if (sqlSession==null){
            sqlSession=ssf.openSession();
//            保存到本地线程变量
            threadLocal.set(sqlSession);
        }
    }

//    获取映射Mapper接口实例
    public static <T extends Object> TgetDao(Class<T> clazz){
        getSqlSession();
        Object mapper = sqlSession.getMapper(clazz);
        return mapper;
    }

//    提交事务
    public static void commit(){
        getSqlSession();
        sqlSession.commit();
    }

//    回滚事务
    public static void rollback(){
        getSqlSession();
        sqlSession.rollback();
    }

//    关闭资源
    public static void closeAll(){
        sqlSession=threadLocal.get();
        threadLocal.set(null);
        if (sqlSession!=null){
            sqlSession.close();
        }
    }

}

六、多表联合查询mybatis的实现

6.1 自定义DTO+多表联查实现

  • 新建DTO类,其类中属性对应多表联合查到的所有字段
  • dto: data tranfer object (数据转换对象) 等同于entity
  • 多表联查 (内连接、左外、右外、全外)
    • 基于where
    • 基于join
  • sql片段:在映射文件中可以多次使用的片段,使用include引用其id值

6.2 使用对象映射+多表联查

  • 以下探讨基于电影信息表(filminfo(表) -- FilmInfo(类))电影类型表(filmtype(表) -- FilmType(类))
  • 表字段信息
    1. filminfo(表) 在这里插入图片描述
      2.filmtype(表)
      在这里插入图片描述
  • 表数据信息
    在这里插入图片描述
    在这里插入图片描述
(1)一对一
  • 新建类(plus类),其属性包含基表的所有属性 + 以某个类作为的属性
    • 电影信息 对应 电影类型(电影类型作为电影信息的属性)
    • 每个电影信息都有一个电影类型
@Data
@NoArgsConstructor
@AllArgsConstructor
public class FilmInfoPlus {
    private int filmId;
    private FilmType filmType;	//电影类型作为电影信息的属性
    private String filmName;
    private String actor;
    private String director;
    private double ticketPrice;
}
  • 编写对象映射:ResultMap
    • 注意: 指定“一方”关系时(对象)使用< association javaType="" >
<!--    多表联合查询对象映射-->
    <resultMap id="FilmInfoPlusMap" type="com.qf.mybatis.entity.FilmInfoPlus">
        <id property="filmId" column="filmId"></id>
        <result property="filmName" column="filmName"></result>
        <result property="actor" column="actor"></result>
        <result property="director" column="director"></result>
        <result property="ticketPrice" column="ticketPrice"></result>
        <association property="filmType" javaType="com.qf.mybatis.entity.FilmType">
            <id property="typeId" column="typeId"></id>
            <result property="typeName" column="typeName"></result>
        </association>
    </resultMap>
  • 编写多表联合查询sql语句
<!--    sql节点:可以重复使用sql语句-->
    <sql id="FilmInfoPlusSql">
        f.filmId,
        f.filmName,
        f.actor,
        f.director,
        f.ticketPrice,
        t.typeId,
        t.typeName
    </sql>
<!--    多表联合查询sql语句-->
    <select id="findOneByIdPlus" resultMap="FilmInfoPlusMap">
        select
            <include refid="FilmInfoPlusSql"></include>
        from filminfo f,filmtype t
        where f.filmId=#{id} and f.typeId=t.typeId
    </select>
(2)一对多
  • 新建类(plus类),其属性包含基表的所有属性 + 以某个类的List集合作为的属性
    • 电影类型 对应 多个电影信息(电影信息List集合作为电影类型的属性)
    • 一个电影类型对应着多个电影信息
@Data
@AllArgsConstructor
@NoArgsConstructor
public class FilmTypePlus {
    private int typeId;
    private String typeName;
    private List<FilmInfo> filmInfos;	//电影信息`List集合`作为电影类型的属性
}
  • 编写对象映射:ResultMap
    • 注意: 指定“多方”关系时(集合),使用< collection ofType=" >
<!--    多表联合查询:对象映射-->
    <resultMap id="filmTypePlusMap" type="com.qf.mybatis.entity.FilmTypePlus">
        <id property="typeId" column="typeId"></id>
        <result property="typeName" column="typeName"></result>
        <collection property="filmInfos" ofType="com.qf.mybatis.entity.FilmInfo">
            <id property="filmId" column="filmId"></id>
            <result property="typeId" column="typeId"></result>
            <result property="filmName" column="filmName"></result>
            <result property="actor" column="actor"></result>
            <result property="director" column="director"></result>
            <result property="ticketPrice" column="ticketPrice"></result>
        </collection>
    </resultMap>
  • 编写多表联合查询sql语句
    <!--    sql节点:可以重复使用sql语句-->
    <sql id="FilmTypePlusSql">
        t.typeId,
        t.typeName,
        f.filmId,
        f.typeId,
        f.filmName,
        f.actor,
        f.director,
        f.ticketPrice
    </sql>
<!--    多表联合查询:一对多-->
    <select id="findFilmByTypeName" resultMap="filmTypePlusMap">
        select
            <include refid="FilmTypePlusSql"></include>
        from filminfo f,filmtype t
        where t.typeName=#{typeName} and t.typeId=f.typeId
    </select>
(3)多对多
  • 本质: 多对多的本质是 两个 一对多
  • 表现:
    • 一般包含三张表(A、B、C),其中A表与C表多对多的关系(互相是一对多的关系),比如,学生表和科目表(一个学生需要上多门课,一门课对应多个学生)
    • B表一般只有两个字段,存储的是两个表的主键列,以方便后续在编写SQL时,使用左外连接(通过B表构成A表与C表的笛卡尔积),进而筛选出符合条件的多表联合查询数据
  • 实现:
    • 编写Plus类(一般需要编写两个,即有两种情况)
      • A表(学生表)对C表(科目表)的一对多 (学生Plus类属性中含有List形式的科目对象属性)
      • C表(科目表)对A表(学生表)的一对多 (科目Plus类属性中含有List形式的学生对象属性)
    • 编写映射
      • 确定谁对应谁是一对多
      • 编写ResultMap编写对象映射,使用< collection ofType="" >
    • 编写SQL语句
      • 通过中间B表(含有两表的主键列),使用左外连接构成笛卡尔积
      • 结合笛卡尔积序列和SQL语句选出符合条件的记录
(4)关系总结
  • 一方,添加集合;
  • 多方,添加对象。
  • 双方均可建立关系属性,建立关系属性后,对应的Mapper文件中需使用< ResultMap >完成多表映射。
  • 持有对象关系属性,使用< association property="dept" javaType="department" >
  • 持有集合关系属性,使用< collection property="emps" ofType="employee" >

七、项目配置文件相关原理

7.1 使用配置文件的原因

  • 文件最终是编译成字节码文件部署到服务器上运行的,若在业务更改中需要改变程序中的硬编码(在程序中作为常量值存在的变量,eg:配置的数据源文件),如果更改源码后忘记重新编译成字节码文件,找不到新更改后的值,则会出现运行错误!
  • 若将硬编码(在程序中作为常量值存在的变量,eg:配置的数据源文件)保存到配置文件中,使程序动态获取到常量值,在业务更改时,只需要更改配置文件中的信息,不需要改变编码,当然也不需要重新编译成字节码文件(class文件)

7.2 常使用单例模式读取配置文件的原因

  • 有一些文件加有锁(一个文件被某一个程序的流打开还未关闭时,另一个程序无法读取此文件),若使用单例模式,则所有程序获取到的是同一个对象,使用的也是同一个对象中的流,不会出现流读取文件冲突的问题!

八、动态SQL

MyBatis的映射文件中支持在基础SQL上添加一些逻辑操作,并动态拼接成完整的SQL之后再执行,以达到SQL复用、简化编程的效果。

8.1 sql 标签

  • 定义sql片段实现复用
  • 在编写SQL语句时,通过<include /> 引入sql片段
    <!--    sql节点:可以重复使用sql语句-->
    <sql id="FilmTypePlusSql">
        t.typeId,
        t.typeName,
        f.filmId,
        f.typeId,
        f.filmName,
        f.actor,
        f.director,
        f.ticketPrice
    </sql>
<!--    多表联合查询:一对多-->
    <select id="findFilmByTypeName" resultMap="filmTypePlusMap">
        select
            <include refid="FilmTypePlusSql"></include>
        from filminfo f,filmtype t
        where t.typeName=#{typeName} and t.typeId=f.typeId
    </select>

8.2 set 标签(if标签结合使用)— 局部字段更新

  • set 标签会冗余逗号,(如果经动态拼接后生成的SQL语句中含有多余的,,set 标签会自动识别并删除)
  • if标签 使用test形成逻辑判断条件
<!--    更新-->
    <update id="updateFilm" parameterType="FilmInfo">
        update filminfo
        <set>
            <if test="filmName!=null">
                filmName=#{filmName},
            </if>
            <if test="typeId!=0">
                typeId=#{typeId},
            </if>
            <if test="actor!=null">
                actor=#{actor},
            </if>
            <if test="director!=null">
                director=#{director},
            </if>
            <if test="ticketPrice!=0">
                ticketPrice=#{ticketPrice}
            </if>
        </set>
        where filmId=#{filmId}
    </update>

8.3 where标签(if标签结合使用)— 分类模糊查询

  • where 标签会冗余逗号and | or(如果经动态拼接后生成的SQL语句中含有多余的and | or,where 标签会自动识别并删除)
  • 模糊查询条件: 使用concat 连接SQL语句中的字符串 eg: concat('%',#{actor},'%')
<!--    动态sql查询-->
    <select id="findFilms" parameterType="FilmInfo" resultType="FilmInfo">
        select * from filminfo
        <where>
            <if test="filmId!=0">
                filmId=#{filmId}
            </if>
            <if test="typeId!=0">
                or typeId=#{typeId}
            </if>
            <if test="filmName!=null">
                or filmName=#{filmName}
            </if>
            <if test="actor!=null">
                or actor like concat('%',#{actor},'%')
            </if>
            <if test="director!=null">
                or director like concat('%',#{director},'%')
            </if>
            <if test="ticketPrice!=0">
                or ticketPrice=#{ticketPrice}
            </if>
        </where>
    </select>

8.4 foreach标签 — 批量删除

  • 批量删除SQL语句使用 in
  • foreach标签参数
    在这里插入图片描述
<!--   批量删除 -->
    <delete id="deleteFilmsById" parameterType="int">
        delete from filminfo
        where filmId in
        <foreach collection="list" open="(" close=")" separator="," item="id">
            #{id}
        </foreach>
    </delete>

8.5 多参传值(对象类型+其他类型)— 条件查询

  • 对象参数与其他类型参数都用@param注解
  • mapper.xml中使用的时候,使用#{对象名.属性名}取值,如#{user.id},动态SQL判断时也要用 对象名.属性名
  • 使用了@pram注解的时,在mapper.xml不加parameterType
//    动态sql查询
    public List<FilmInfo> findFilmsByTicketPrice(@Param("info") FilmInfo info,@Param("lowPrice") int lowPrice,@Param("highPrice") int highPrice);
<!--    动态sql查询-->
    <select id="findFilmsByTicketPrice" resultType="FilmInfo">
        select * from filminfo
        <where>
            <if test="info.filmId!=0">
                filmId=#{info.filmId}
            </if>
            <if test="info.typeId!=0">
                or typeId=#{info.typeId}
            </if>
            <if test="info.filmName!=null">
                or filmName=#{info.filmName}
            </if>
            <if test="info.actor!=null">
                or actor like concat('%',#{info.actor},'%')
            </if>
            <if test="info.director!=null">
                or director like concat('%',#{info.director},'%')
            </if>
            <if test="info.ticketPrice!=0">
                or ticketPrice=#{info.ticketPrice}
            </if>
<!--  上半部分是属性模糊查询,下面是价格区间查询-->
            or ticketPrice between #{lowPrice} and #{highPrice}

        </where>
    </select>

九、注解开发

9.1多表联合查询注解开发

9.1.1Results注解源码分析

(1)@Results注解源码分析
在这里插入图片描述
(2)fetchType取值(FetchType枚举类)

  • fetchType取值对联合查询的结果集不会有影响,但是会影响性能
    在这里插入图片描述
  • fetchType = FetchType.LAZY(推荐
    在这里插入图片描述
  • fetchType = FetchType.EAGER
    在这里插入图片描述
9.1.2一对一关系

(1)注解实现

  • 在Results注解中,其属性one的取值为@One
  • 一对一关系子查询中的column对应的是引用单体查询方法的所依赖的字段(形参)
  • 在一对一关系注解查询中javaType可以指定也可以不指定
  • 单个column(数据表字段)可以对应多个property(实体属性)
  • Results注解可以使用其id实现复用
  • 单体查询
    在这里插入图片描述
  • 一对一关系注解查询实现在这里插入图片描述
    (2)注解对比映射文件实现在这里插入图片描述
9.1.3一对多关系
  • 在Results注解中,其属性many的取值为@Many
  • 一对一关系子查询中的column对应的是引用子查询查询方法的所依赖的字段(形参)
  • 在一对多关系注解查询中javaType不可以取值(此属性不在Results注解中出现)
  • 单个column(数据表字段)可以对应多个property(实体属性)
  • Results注解可以使用其id实现复用
  • 子查询
    在这里插入图片描述
  • 一对多关系实现
    在这里插入图片描述

9.2动态sql注解开发

  • 需要在相应注解查询语句中加入<script>标签,用于解析sql语句
  • 动态sql插入映射文件开发
    在这里插入图片描述
  • 动态sql插入注解开发
    在这里插入图片描述

在这里插入图片描述

十、分页插件PageHelper

10.1 准备工作

(1)导入依赖

<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>5.1.2</version> 
</dependency>

(2)在mybatis配置文件中加入<plugin>标签,配置插件

  • 查用配置
<!--    插件配置-->
    <plugins>
        <!-- com.github.pagehelper为PageHelper类所在包名 -->
        <plugin interceptor="com.github.pagehelper.PageInterceptor">
            <!-- 配置方言,不配置,则使用数据库连接来判断 -->
            <property name="helperDialect" value="mysql"/>
            <!-- 合理化参数 -->
              <!-- 启用合理化时,如果pageNum<1会查询第一页,如果pageNum>pages会查询最后一页 -->
            <!-- 禁用合理化时,如果pageNum<1或pageNum>pages会返回空数据 -->
            <property name="reasonable" value="true"/>
        </plugin>
    </plugins>
  • PageHelper插件详细配置解读
    <plugins>
        <!-- com.github.pagehelper为PageHelper类所在包名 -->
        <plugin interceptor="com.github.pagehelper.PageHelper">
         	<!-- 配置方言,不配置,则使用数据库连接来判断 -->
            <property name="dialect" value="mysql" />
            <!-- 该参数默认为false -->
            <!-- 设置为true时,会将RowBounds第一个参数offset当成pageNum页码使用 -->
            <!-- 和startPage中的pageNum效果一样 -->
            <property name="offsetAsPageNum" value="true" />
            <!-- 该参数默认为false -->
            <!-- 设置为true时,使用RowBounds分页会进行count查询 -->
            <property name="rowBoundsWithCount" value="true" />
            <!-- 设置为true时,如果pageSize=0或者RowBounds.limit = 0就会查询出全部的结果 -->
            <!-- (相当于没有执行分页查询,但是返回结果仍然是Page类型) -->
            <property name="pageSizeZero" value="true" />
            <!-- 3.3.0版本可用 - 分页参数合理化,默认false禁用 -->
            <!-- 启用合理化时,如果pageNum<1会查询第一页,如果pageNum>pages会查询最后一页 -->
            <!-- 禁用合理化时,如果pageNum<1或pageNum>pages会返回空数据 -->
            <property name="reasonable" value="false" />
            <!-- 3.5.0版本可用 - 为了支持startPage(Object params)方法 -->
            <!-- 增加了一个`params`参数来配置参数映射,用于从Map或ServletRequest中取值 -->
            <!-- 可以配置pageNum,pageSize,count,pageSizeZero,reasonable,不配置映射的用默认值 -->
            <!-- 不理解该含义的前提下,不要随便复制该配置 -->
            <property name="params" value="pageNum=start;pageSize=limit;" />
            <!-- always总是返回PageInfo类型,check检查返回类型是否为PageInfo,none返回Page -->
            <property name="returnPageInfo" value="check" />
        </plugin>
    </plugins>

10.2 分页插件的使用

(1)开启分页

  • 使用PageHelper.startPage 静态方法调用startPage :
  • PageHelper.startPage()方法特点:
    • 静态方法,传递两个参数(当前页码,每页查询条数)
    • 使用pageHelper 分页的时候,不再关注具体的分页语句,查询全部的语句
    • 自动的对PageHelper.startPage()方法下一行的第一个sql 查询进行分页;
  • eg:
//        开启分页插件(查询前开启),
//		紧跟着的第一个select 方法会被分页
        PageHelper.startPage(2,5);
        List<SubItem> list = mapper.findAll();

也就是说,在代码——PageHelper.startPage(2,5);语句后边,一定要紧跟查询语句。

(2)获得具体分页结果集

  • 使用PageInfo获得具体的分页结果对象
  • 使用查询的多有结果的集合,作为参数传给PageInfo的构造函数
  • 获取具体的分页结果集,就是PageHelper开启分页时,指定的页码和每页具体条数的结果集,当然也包含其他信息
  • eg:
//        开启分页插件(查询前开启)
        PageHelper.startPage(2,5);
        List<SubItem> list = mapper.findAll();
//        进行分页结果返回
        PageInfo<SubItem> pageInfo=new PageInfo<SubItem>(list);
//         获取分页结果集
        List<SubItem> list1 = pageInfo.getList();
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值