文章目录
- 一、引言
- 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开发步骤
- 加载mybatis的依赖
- 配置mybatis-config.xml
- 开发dao层接口
- 编写mapping映射文件
- 将mapping映射文件添加到mybatis-config.xml中
- 编写调用程序测试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(类))
- 表字段信息
- filminfo(表)
2.filmtype(表)
- filminfo(表)
- 表数据信息
(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表的笛卡尔积),进而筛选出符合条件的多表联合查询数据
- 一般包含三张表(A、B、C),其中A表与C表多对多的关系(
- 实现:
- 编写Plus类(一般需要编写两个,即有两种情况)
- A表(学生表)对C表(科目表)的一对多 (学生Plus类属性中含有List形式的科目对象属性)
- C表(科目表)对A表(学生表)的一对多 (科目Plus类属性中含有List形式的学生对象属性)
- 编写映射
- 确定谁对应谁是一对多
- 编写ResultMap编写对象映射,
使用< collection ofType="" >
- 编写SQL语句
- 通过中间B表(含有两表的主键列),使用
左外连接
构成笛卡尔积
- 结合
笛卡尔积
序列和SQL语句选出符合条件的记录
- 通过中间B表(含有两表的主键列),使用
- 编写Plus类(一般需要编写两个,即有两种情况)
(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();