mybatis详述

news2024/11/18 5:53:50

文章目录

    • 一、引言
      • 1.1 什么是框架?
      • 1.2 什么是ORM框架?
      • 1.3使用JDBC完成ORM操作的缺点?
    • 二、MyBatis框架
      • 2.1概念
      • 2.2 MyBatis开发步骤
      • 2.3 如何编写mybatis映射文件(规范)
    • 三、mybatis-config.xml 配置补充
    • 四、mybatis接口与映射文件指令间 传递参数
      • 4.1 传递单一参数
      • 4.2 传递多参
      • 4.3 传递对象参数
      • 4.4 传递集合参数(Map)
    • 五、MyBatis工具类封装
    • 六、多表联合查询mybatis的实现
      • 6.1 自定义DTO+多表联查实现
      • 6.2 使用对象映射+多表联查
        • (1)一对一
        • (2)一对多
        • (3)多对多
        • (4)关系总结
    • 七、项目配置文件相关原理
      • 7.1 使用配置文件的原因
      • 7.2 常使用单例模式读取配置文件的原因
    • 八、动态SQL
      • 8.1 sql 标签
      • 8.2 set 标签(if标签结合使用)--- 局部字段更新
      • 8.3 where标签(if标签结合使用)--- 分类模糊查询
      • 8.4 foreach标签 --- 批量删除
      • 8.5 多参传值(对象类型+其他类型)--- 条件查询
    • 九、注解开发
      • 9.1多表联合查询注解开发
        • 9.1.1Results注解源码分析
        • 9.1.2一对一关系
        • 9.1.3一对多关系
      • 9.2动态sql注解开发
    • 十、分页插件PageHelper
      • 10.1 准备工作
      • 10.2 分页插件的使用

一、引言

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();

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/70314.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

安卓APP源码和设计报告——北京旅游系统

目 录 一、概述11 1.1 课题描述11 1.2 需求分析22 1.3 开发环境33 二、系统分析与概要设计55 2.1 系统功能分析55 2.2 系统模块结构图66 2.3 数据库表的设计66 三、北京旅游系统的登录功能模块的详细设计88 3.1 登录模块的功能描述88 3.2 登录模块的界面布局的设计9…

185: vue+openlayers 引用hover插件,展示各种鼠标cursor样式

第185个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+openlayers中使用hover效果,这里是引用了一个hover插件。鼠标对应到相应的feature中时候,获取其类型,并且设定不同的鼠标样式。 直接复制下面的 vue+openlayers源代码,操作2分钟即可运行实现效果; 注意如果Ope…

一篇知晓-内存竟被”无意“破坏,真相究竟如何?

内存是C/C程序员的好帮手&#xff0c;我们通常说C/C程序性能更高其原因之一就在于可以自己来管理内存&#xff0c;然而计算机科学中没有任何一项技术可以包治百病&#xff0c;内存问题也给C/C程序员带来无尽的烦恼。 野指针、数组越界、错误的内存分配或者释放、多线程读写导致…

kotlin之hello world

如果你想一个人写全栈的话&#xff0c;Kotlin Multiplatform &#xff08;以下简称MPP&#xff09;是目前这个星球上最好的选择&#xff0c;没有之一。 Kotlin 是一种在 Java 虚拟机上运行的静态类型编程语言&#xff0c;被称之为 Android 世界的Swift&#xff0c;由 JetBrain…

CTFSHOW web入门 java反序列化篇(更新中)

在做这部分题前&#xff0c;推荐大家先去学习下java反序列化&#xff0c;尤其是CC链 可以看下两个系列视频&#xff0c;收获颇多 https://space.bilibili.com/2142877265/channel/collectiondetail?sid29805&ctype0 https://www.bilibili.com/video/BV16h411z7o9/?spm_i…

手写Spring2(实现 Bean 的定义、注册、获取)

文章目录前言本章目标一、实现1、项目结构2、BeanFactory-bean工厂3、BeanDefinition -bean定义4、单例注册接口定义和实现-SingletonBeanRegistry 、DefaultSingletonBeanRegistry5、AbstractBeanFactory-抽象bean工厂类(定义模板方法)6、AbstractAutowireCapableBeanFactory-…

python配置环境问题记录------2022/12/07

python配置问题记录1、版本匹配的问题2、指令安装相关依赖包3、pycharm指定解释器4、运行网络模块5、总结1、版本匹配的问题 到官网下载合适的版本&#xff08;注意位数&#xff0c;我这里选的是64位&#xff09;&#xff0c;pycharm选的是21年版本的&#xff0c;太新的话会有…

【C++】异常exception

目录 一.C语言错误处理方式 1.assert(断言) 2.返回/设置错误码 二.C异常的概念与使用 1.异常的概念 2.异常的使用 三.自定义异常体系MyException 四.异常的重新抛出 五.异常安全问题 六.异常规范 七.异常的优缺点对比 一.C语言错误处理方式 一个C语言程序, 在运行期…

回归分析与相关分析的区别和联系

在本节中&#xff0c;我们将首先讨论相关性分析&#xff0c;它用于量化两个连续变量之间的关联&#xff08;例如&#xff0c;独立变量与因变量之间或两个独立变量之间&#xff09;。 最近我们被客户要求撰写关于回归分析与相关分析的研究报告&#xff0c;包括一些图形和统计输…

软件测试经验与教训

下面精选出10条&#xff0c;和大家分享。 01 测试人员是项目的前灯 一个项目就像是一次陆上旅行。有些项目很简单、很平常&#xff0c;就像是大白天开车去商店买东西。但是大多数值得开发的项目更像是夜间在山里开越野卡车&#xff0c;这些项目需要前灯&#xff0c;而测试员要照…

直播带货行业如何入局?先了解一下直播商城源码吧

直播行业的爆火已经持续了多个年头&#xff0c;直到今天&#xff0c;在人们的生活中依然有着举足轻重的地位&#xff0c;它通过多元化的方案为许多行业带来了新的思路&#xff0c;特别是与传统商业所结合的“直播电商”、“直播商城”的卖货新形式&#xff0c;让多方因此而受益…

数理化解题研究杂志社数理化解题研究编辑部2022年第30期目录

教学改革探索 信息技术下中职数学“翻转课堂”教学创新策略研究 李宇仙; 2-4《数理化解题研究》投稿&#xff1a;cn7kantougao163.com 基于高中数学核心素养的错题讲评课之探索与实践 施浩妹; 17-20 高中数学“问题导学”模式的实践研究 吴金桥; 21-23 立于神而…

【测试沉思录】21. 如何用 JMeter 编写性能测试脚本?

作者&#xff1a;宋赟 编辑&#xff1a;毕小烦 Apache JMeter 应该是应用最广泛的性能测试工具。怎么用 JMeter 编写性能测试脚本&#xff1f; 1. 编写 HTTP 性能测试脚本 STEP 1. 添加 HTTP 请求 STEP 2. 了解配置信息 HTTP 请求各项信息说明&#xff08;以 JMeter 5.1 为例…

【强化学习论文合集】十.2018智能体和多智能体系统国际联合会议论文(AAMAS2018)

强化学习(Reinforcement Learning, RL),又称再励学习、评价学习或增强学习,是机器学习的范式和方法论之一,用于描述和解决智能体(agent)在与环境的交互过程中通过学习策略以达成回报最大化或实现特定目标的问题。 本专栏整理了近几年国际顶级会议中,涉及强化学习(Rein…

十四、SpringBoot-自动装配原理

十四、SpringBoot-自动装配原理 SpringBoot与Spring比较起来&#xff0c;优化的点主要有&#xff1a; 自动配置&#xff1a;是一个运行时&#xff08;应用程序启动时&#xff09;的过程&#xff0c;考虑了众多因素&#xff0c;才决定Spring配置应该用哪个&#xff0c;不该用哪…

软件测试基础丨测试工程师之间要善于发现闪光点——测试理念篇

测试理念有多种&#xff0c;有一些理念&#xff0c;深藏于我的心中&#xff0c; 而这些理念&#xff0c;您或许偶尔想到&#xff0c;却没有说出&#xff0c;或许您感受到了&#xff0c;却因为工作生活的忙碌&#xff0c;没有将其背后的含义想具体&#xff0c; 在此我非常愿意和…

零基础小白hadoop分布式集群环境搭建(超详细)

搭建集群所需要安装包 虚拟机、ubuntu镜像文件、jdk安装包、hadoop安装包 百度云盘地址&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1ejVamlrlyoWtJRo1QQqlsA提取码&#xff1a;fcqm 本文的环境是两台windows笔记本&#xff0c;在每台笔记本上安装一个虚拟机&…

超详细的水果FL Studio21最新版更新全功能详细介绍!80项更新与改进!

万众期待的 FL Studio 21 版本将于正式发布上线&#xff0c;目前在紧锣密鼓的安排上线中&#xff0c;届时所有购买正版 FL Studio 的用户&#xff0c;都可以免费升级到21版&#xff01;按照惯例&#xff0c;本次新版也会增加全新插件&#xff0c;来帮助大家更好地创作。今天先给…

SMART原则介绍

一、SMART原则简介 什么是SMART原则? SMART原则(S=Specific、M=Measurable、A=Attainable、R=Relevant、T=Time-bound)是为了利于员工更加明确高效地工作,更是为了管理者将来对员工实施绩效考核提供了考核目标和考核标准,使考核更加科学化、规范化,更能保证考核的公正、…

五万字详解“GoF”的23种设计模式

大家好&#xff0c;我是栗筝i&#xff0c;近期我总结梳理了 “GoF”的 23 种设计模式&#xff0c;并使用 Java 对每种设计模式都进行了伪代码与 Demo 实现&#xff0c;并总结了每种设计模式的应用场景&#xff0c;优缺点&#xff0c;UML图等相关内容&#xff0c;字/词数达到了5…