Mybatis特性
MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架
MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集
MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录
MyBatis是一个半自动的ORM(Object Relation Mapping)框架
和其它持久化层技术对比
JDBC
SQL 夹杂在Java代码中耦合度高,导致硬编码内伤
维护不易且实际开发需求中 SQL 有变化,频繁修改的情况多见
代码冗长,开发效率低
Hibernate 和 JPA
操作简便,开发效率高
程序中的长难复杂 SQL 需要绕过框架
内部自动生产的 SQL,不容易做特殊优化
基于全映射的全自动框架,大量字段的 POJO 进行部分映射时比较困难。
反射操作太多,导致数据库性能下降
MyBatis
轻量级,性能出色
SQL 和 Java 编码分开,功能边界清晰。Java代码专注业务、SQL语句专注数据
开发效率稍逊于HIbernate,但是完全能够接受
核心配置文件
核心配置文件中的标签必须按照固定的顺序(有的标签可以不写,但顺序一定不能乱):
properties、settings、typeAliases、typeHandlers、objectFactory、objectWrapperFactory、reflectorFactory、plugins、environments、databaseIdProvider、mappers
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 <?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" > <configuration > <properties resource ="jdbc.properties" /> <settings > <setting name ="mapUnderscoreToCamelCase" value ="true" /> </settings > <typeAliases > <package name ="com.zhuweitung.mybatis.model" /> </typeAliases > <environments default ="development" > <environment id ="development" > <transactionManager type ="JDBC" /> <dataSource type ="POOLED" > <property name ="driver" value ="${jdbc.driverClassName}" /> <property name ="url" value ="${jdbc.jdbcUrl}" /> <property name ="username" value ="${jdbc.username}" /> <property name ="password" value ="${jdbc.password}" /> </dataSource > </environment > </environments > <mappers > <package name ="com.zhuweitung.mybatis.mapper" /> </mappers > </configuration >
获取参数值的方式
MyBatis获取参数值的两种方式:${}
和#{}
${}
的本质就是字符串拼接,#{}
的本质就是占位符赋值
${}
使用字符串拼接的方式拼接sql,若为字符串类型或日期类型的字段进行赋值时,需要手动加单引号;但是#{}
使用占位符赋值的方式拼接sql,此时为字符串类型或日期类型的字段进行赋值时,可以自动添加单引号
单个字面量类型的参数
若mapper接口中的方法参数为单个的字面量类型,此时可以使用${}和#{}以任意的名称(最好见名识意)获取参数的值,注意${}需要手动加单引号
1 2 3 4 <select id ="getUserByName" resultType ="User" > select * from user where name = #{name}</select >
1 2 3 <select id ="getUserByName" resultType ="User" > select * from user where name = '${name}' </select >
多个字面量类型的参数
若mapper接口中的方法参数为多个时,此时MyBatis会自动将这些参数放在一个map集合中
1 2 1. 以arg0 ,arg1. ..为键,以参数为值;2. 以param1 ,param2. ..为键,以参数为值;
因此只需要通过${}和#{}访问map集合的键就可以获取相对应的值,注意${}需要手动加单引号。
使用arg或者param都行,要注意的是,arg是从arg0开始的,param是从param1开始的
1 2 3 4 <select id ="checkLogin" resultType ="User" > select * from user where name = #{arg0} and password = #{arg1} </select >
1 2 3 <select id ="checkLogin" resultType ="User" > select * from user where name = '${param1}' and password = '${param2}'</select >
map集合类型的参数
若mapper接口中的方法需要的参数为多个时,此时可以手动创建map集合,将这些数据放在map中只需要通过${}和#{}访问map集合的键就可以获取相对应的值,注意${}需要手动加单引号
1 2 3 4 <select id ="checkLoginByMap" resultType ="User" > select * from user where name = #{name} and password = #{password}</select >
实体类类型的参数
若mapper接口中的方法参数为实体类对象时此时可以使用${}和#{},通过访问实体类对象中的属性名获取属性值,注意${}需要手动加单引号
1 2 3 4 <insert id ="insertUser" > insert into user values(null,#{name},#{password},#{age},#{sex},#{email})</insert >
使用@Param标识参数
1 2 3 4 <select id ="CheckLoginByParam" resultType ="User" > select * from user where name = #{name} and password = #{password}</select >
@Param源码解析
ParamNameResolver类中将参数解析为map
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 public Object getNamedParams (Object[] args) { final int paramCount = names.size(); if (args == null || paramCount == 0 ) { return null ; } else if (!hasParamAnnotation && paramCount == 1 ) { Object value = args[names.firstKey()]; return wrapToMapIfCollection(value, useActualParamName ? names.get(0 ) : null ); } else { final Map<String, Object> param = new ParamMap <>(); int i = 0 ; for (Map.Entry<Integer, String> entry : names.entrySet()) { param.put(entry.getValue(), args[entry.getKey()]); final String genericParamName = GENERIC_NAME_PREFIX + (i + 1 ); if (!names.containsValue(genericParamName)) { param.put(genericParamName, args[entry.getKey()]); } i++; } return param; } }
各种查询功能
如果查询出的数据只有一条,可以通过
如果查询出的数据有多条,一定不能用实体类对象接收,会抛异常TooManyResultsException,可以通过
实体类类型的LIst集合接收
Map类型的LIst集合接收
在mapper接口的方法上添加@MapKey注解
1 2 3 @MapKey("id") Map<String, Object> getAllUserToMap () ;
1 2 3 <select id ="getAllUserToMap" resultType ="map" > select * from user</select >
模糊查询
1 2 3 4 5 <select id ="getUserByLike" resultType ="User" > select * from user where name like "%"#{mohu}"%"</select >
添加功能获取自增的主键
1 2 3 <insert id ="insertUser" useGeneratedKeys ="true" keyProperty ="id" > insert into user values (null,#{name},#{password},#{age},#{sex},#{email})</insert >
需要在mapper.xml中设置两个属性
useGeneratedKeys:设置使用自增的主键
keyProperty:因为增删改有统一的返回值是受影响的行数,因此只能将获取的自增的主键放在传输的参数user对象的某个属性中
内建的类型别名
下面是一些为常见的 Java 类型内建的类型别名。它们都是不区分大小写
的,注意,为了应对原始类型的命名重复,采取了特殊的命名风格。
别名
映射的类型
_byte
byte
_char (since 3.5.10)
char
_character (since 3.5.10)
char
_long
long
_short
short
_int
int
_integer
int
_double
double
_float
float
_boolean
boolean
string
String
byte
Byte
char (since 3.5.10)
Character
character (since 3.5.10)
Character
long
Long
short
Short
int
Integer
integer
Integer
double
Double
float
Float
boolean
Boolean
date
Date
decimal
BigDecimal
bigdecimal
BigDecimal
biginteger
BigInteger
object
Object
date[]
Date[]
decimal[]
BigDecimal[]
bigdecimal[]
BigDecimal[]
biginteger[]
BigInteger[]
object[]
Object[]
map
Map
hashmap
HashMap
list
List
arraylist
ArrayList
collection
Collection
iterator
Iterator
自定义映射resultMap
resultMap字段和属性
resultMap:设置自定义映射
id:表示自定义映射的唯一标识,不能重复
type:查询的数据要映射的实体类的类型
id:设置主键的映射关系
property:设置映射关系中实体类中的属性名
column:设置映射关系中表中的字段名
result:设置普通字段的映射关系
若字段名和实体类中的属性名不一致,则可以通过resultMap设置自定义映射,即使字段名和属性名一致的属性也要映射,也就是全部属性都要列出来
1 2 3 4 5 6 7 8 9 10 11 <resultMap id ="empResultMap" type ="Emp" > <id property ="eid" column ="eid" > </id > <result property ="empName" column ="emp_name" > </result > <result property ="age" column ="age" > </result > <result property ="sex" column ="sex" > </result > <result property ="email" column ="email" > </result > </resultMap > <select id ="getAllEmp" resultMap ="empResultMap" > select * from t_emp</select >
开启驼峰映射
开启后在查询时自动将下划线
风格类型的字段名转换为驼峰,如 user_name 会转换为 userName
1 2 3 <settings > <setting name ="mapUnderscoreToCamelCase" value ="true" /> </settings >
多对一映射处理
1 2 3 4 5 6 7 8 public class Emp { private Integer eid; private String empName; private Integer age; private String sex; private String email; private Dept dept; }
级联方式处理映射关系
1 2 3 4 5 6 7 8 9 10 11 12 13 <resultMap id ="empAndDeptResultMapOne" type ="Emp" > <id property ="eid" column ="eid" > </id > <result property ="empName" column ="emp_name" > </result > <result property ="age" column ="age" > </result > <result property ="sex" column ="sex" > </result > <result property ="email" column ="email" > </result > <result property ="dept.did" column ="did" > </result > <result property ="dept.deptName" column ="dept_name" > </result > </resultMap > <select id ="getEmpAndDept" resultMap ="empAndDeptResultMapOne" > select * from t_emp left join t_dept on t_emp.eid = t_dept.did where t_emp.eid = #{eid}</select >
使用association处理映射关系
association:处理多对一的映射关系
property:需要处理多对的映射关系的属性名
javaType:该属性的Java类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <resultMap id ="empAndDeptResultMapTwo" type ="Emp" > <id property ="eid" column ="eid" > </id > <result property ="empName" column ="emp_name" > </result > <result property ="age" column ="age" > </result > <result property ="sex" column ="sex" > </result > <result property ="email" column ="email" > </result > <association property ="dept" javaType ="Dept" > <id property ="did" column ="did" > </id > <result property ="deptName" column ="dept_name" > </result > </association > </resultMap > <select id ="getEmpAndDept" resultMap ="empAndDeptResultMapTwo" > select * from t_emp left join t_dept on t_emp.eid = t_dept.did where t_emp.eid = #{eid}</select >
分步查询
先查询员工表,再查询部门表
select:设置分布查询的sql的唯一标识
column:设置分步查询的条件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 <resultMap id ="empAndDeptByStepResultMap" type ="Emp" > <id property ="eid" column ="eid" > </id > <result property ="empName" column ="emp_name" > </result > <result property ="age" column ="age" > </result > <result property ="sex" column ="sex" > </result > <result property ="email" column ="email" > </result > <association property ="dept" select ="com.atguigu.mybatis.mapper.DeptMapper.getEmpAndDeptByStepTwo" column ="did" > </association > </resultMap > <select id ="getEmpAndDeptByStepOne" resultMap ="empAndDeptByStepResultMap" > select * from t_emp where eid = #{eid}</select > <resultMap id ="EmpAndDeptByStepTwoResultMap" type ="Dept" > <id property ="did" column ="did" > </id > <result property ="deptName" column ="dept_name" > </result > </resultMap > <select id ="getEmpAndDeptByStepTwo" resultMap ="EmpAndDeptByStepTwoResultMap" > select * from t_dept where did = #{did}</select >
一对多映射处理
1 2 3 4 5 public class Dept { private Integer did; private String deptName; private List<Emp> emps; }
collection
collection:用来处理一对多的映射关系
ofType:表示该属性对饮的集合中存储的数据的类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <resultMap id ="DeptAndEmpResultMap" type ="Dept" > <id property ="did" column ="did" > </id > <result property ="deptName" column ="dept_name" > </result > <collection property ="emps" ofType ="Emp" > <id property ="eid" column ="eid" > </id > <result property ="empName" column ="emp_name" > </result > <result property ="age" column ="age" > </result > <result property ="sex" column ="sex" > </result > <result property ="email" column ="email" > </result > </collection > </resultMap > <select id ="getDeptAndEmp" resultMap ="DeptAndEmpResultMap" > select * from t_dept left join t_emp on t_dept.did = t_emp.did where t_dept.did = #{did}</select >
分步查询
先查询部门表,再查询人员表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <resultMap id ="DeptAndEmpByStepOneResultMap" type ="Dept" > <id property ="did" column ="did" > </id > <result property ="deptName" column ="dept_name" > </result > <collection property ="emps" select ="com.atguigu.mybatis.mapper.EmpMapper.getDeptAndEmpByStepTwo" column ="did" > </collection > </resultMap > <select id ="getDeptAndEmpByStepOne" resultMap ="DeptAndEmpByStepOneResultMap" > select * from t_dept where did = #{did}</select > <select id ="getDeptAndEmpByStepTwo" resultType ="Emp" > select * from t_emp where did = #{did}</select >
延迟加载
分步查询的优点:可以实现延迟加载,但是必须在核心配置文件中设置全局配置信息:
lazyLoadingEnabled: 延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 特定关联关系中可通过设置 fetchType
属性来覆盖该项的开关状态
aggressiveLazyLoading:开启时,任一方法的调用都会加载该对象的所有延迟加载属性。 否则,每个延迟加载属性会按需加载
开启设置后,可通过association
和collection
中的fetchType
属性设置当前的分步查询是否使用延迟加载,fetchType=“lazy(延迟加载)|eager(立即加载)”
效果:
关闭延迟加载,分步查询的所有步骤都会执行
开启延迟加载,调用查询方法后,只有第一步的sql会执行,其他步骤会在步骤对应属性被程序调用时执行
动态SQL
Mybatis框架的动态SQL技术是一种根据特定条件动态拼装SQL语句的功能,它存在的意义是为了解决拼接SQL语句字符串时的痛点问题
if
1 2 3 4 5 6 7 8 9 10 <select id ="findActiveBlogLike" resultType ="Blog" > SELECT * FROM BLOG WHERE state = ‘ACTIVE’ <if test ="title != null" > AND title like #{title} </if > <if test ="author != null and author.name != null" > AND author_name like #{author.name} </if > </select >
choose、when、otherwise
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <select id ="findActiveBlogLike" resultType ="Blog" > SELECT * FROM BLOG WHERE state = ‘ACTIVE’ <choose > <when test ="title != null" > AND title like #{title} </when > <when test ="author != null and author.name != null" > AND author_name like #{author.name} </when > <otherwise > AND featured = 1 </otherwise > </choose > </select >
trim、where、set
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <select id ="findActiveBlogLike" resultType ="Blog" > SELECT * FROM BLOG WHERE <if test ="state != null" > state = #{state} </if > <if test ="title != null" > AND title like #{title} </if > <if test ="author != null and author.name != null" > AND author_name like #{author.name} </if > </select >
上面的例子中,当所有查询条件都不满足时会输出错误的sql
1 2 SELECT * FROM BLOGWHERE
通过where元素将所有的查询条件包起来解决此问题,where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句;而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <select id ="findActiveBlogLike" resultType ="Blog" > SELECT * FROM BLOG <where > <if test ="state != null" > state = #{state} </if > <if test ="title != null" > AND title like #{title} </if > <if test ="author != null and author.name != null" > AND author_name like #{author.name} </if > </where > </select >
而where元素等价于下面
1 2 <trim prefix ="WHERE" prefixOverrides ="AND |OR " > </trim >
trim元素的 prefixOverrides 属性会忽略通过管道符分隔的文本序列,并且插入 prefix 属性中指定的内容
set 元素可以用于动态包含需要更新的列,忽略其它不更新的列
1 2 3 4 5 6 7 8 9 10 <update id ="updateAuthorIfNecessary" > update Author <set > <if test ="username != null" > username=#{username},</if > <if test ="password != null" > password=#{password},</if > <if test ="email != null" > email=#{email},</if > <if test ="bio != null" > bio=#{bio}</if > </set > where id=#{id}</update >
set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)
可以通过使用trim元素来达到同样的效果:
1 2 <trim prefix ="SET" suffixOverrides ="," > </trim >
foreach
foreach用于遍历的场景
1 2 3 4 5 6 7 8 9 10 <select id ="selectPostIn" resultType ="domain.blog.Post" > SELECT * FROM POST P <where > <foreach item ="item" index ="index" collection ="list" open ="ID in (" separator ="," close =")" nullable ="true" > #{item} </foreach > </where > </select >
script
要在带注解的映射器接口类中使用动态 SQL,可以使用 script 元素
1 2 3 4 5 6 7 8 9 10 11 @Update({"<script>", "update Author", " <set>", " <if test='username != null'>username=#{username},</if>", " <if test='password != null'>password=#{password},</if>", " <if test='email != null'>email=#{email},</if>", " <if test='bio != null'>bio=#{bio}</if>", " </set>", "where id=#{id}", "</script>"}) void updateAuthorValues (Author author) ;
bind
允许你在 OGNL 表达式以外创建一个变量,并将其绑定到当前的上下文
1 2 3 4 5 <select id ="selectBlogsLike" resultType ="Blog" > <bind name ="pattern" value ="'%' + _parameter.getTitle() + '%'" /> SELECT * FROM BLOG WHERE title LIKE #{pattern}</select >
sql片段
sql片段可以记录一段公共sql片段,在使用的地方通过include标签进行引入
1 2 3 4 <sql id ="empColumns" > eid,emp_name,age,sex,email</sql > <select id ="getEmpByCondition" resultType ="Emp" > select <include refid ="empColumns" > </include > from t_emp</select >
缓存机制
MyBatis的一级缓存
MyBatis的二级缓存
二级缓存是SqlSessionFactory
级别,通过同一个SqlSessionFactory创建的SqlSession查询的结果会被缓存;此后若再次执行相同的查询语句,结果就会从缓存中获取
二级缓存开启的条件(都必须)
在核心配置文件中,设置全局配置属性cacheEnabled="true"
,默认为true,不需要设置
在映射文件中设置标签<cache/>
二级缓存必须在SqlSession关闭或提交
之后有效
查询的数据所转换的实体类类型必须实现序列化的接口
使二级缓存失效的情况:两次查询之间执行了任意的增删改,会使一级和二级缓存同时失效
cache元素属性
1 2 3 4 5 <cache eviction ="FIFO" flushInterval ="60000" size ="512" readOnly ="true" />
eviction:清除策略,默认的清除策略是 LRU
LRU
– 最近最少使用:移除最长时间不被使用的对象。
FIFO
– 先进先出:按对象进入缓存的顺序来移除它们。
SOFT
– 软引用:基于垃圾回收器状态和软引用规则移除对象。
WEAK
– 弱引用:更积极地基于垃圾收集器状态和弱引用规则移除对象。
flushInterval:刷新间隔,可以被设置为任意的正整数,设置的值应该是一个以毫秒为单位的合理时间量。 默认情况是不设置,也就是没有刷新间隔,缓存仅仅会在调用语句时刷新
size:引用数目,属性可以被设置为任意正整数,要注意欲缓存对象的大小和运行环境中可用的内存资源。默认值是 1024
readOnly:只读,只读的缓存会给所有调用者返回缓存对象的相同实例,默认值是 false
缓存查询顺序
先查询二级缓存,因为二级缓存中可能会有其他程序已经查出来的数据,可以拿来直接使用
如果二级缓存没有命中,再查询一级缓存
如果一级缓存也没有命中,则查询数据库
SqlSession关闭之后,一级缓存中的数据会写入二级缓存
整合第三方缓存EHCache
第三方缓存替代的是mybatis的二级缓存
pom中引入依赖
1 2 3 4 5 6 7 8 9 10 11 <dependency > <groupId > org.mybatis.caches</groupId > <artifactId > mybatis-ehcache</artifactId > <exclusions > <exclusion > <artifactId > slf4j-api</artifactId > <groupId > org.slf4j</groupId > </exclusion > </exclusions > </dependency >
添加ehcache配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <?xml version="1.0" encoding="utf-8" ?> <ehcache xmlns:xsi ="http://www.w3.org/2001/XMLSchema-instance" > <diskStore path ="D:\tmp\ehcache" /> <defaultCache maxElementsInMemory ="1000" maxElementsOnDisk ="10000000" eternal ="false" overflowToDisk ="true" timeToIdleSeconds ="120" timeToLiveSeconds ="120" diskExpiryThreadIntervalSeconds ="120" memoryStoreEvictionPolicy ="LRU" > </defaultCache > </ehcache >
mappper.xml中修改二级缓存类型
1 <cache type ="org.mybatis.caches.ehcache.EhcacheCache" />
逆向工程
通过数据库表逆向生成代码
pom中引入maven插件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 <build > <plugins > <plugin > <groupId > org.mybatis.generator</groupId > <artifactId > mybatis-generator-maven-plugin</artifactId > <version > 1.3.0</version > <dependencies > <dependency > <groupId > org.mybatis.generator</groupId > <artifactId > mybatis-generator-core</artifactId > <version > 1.3.2</version > </dependency > <dependency > <groupId > com.mchange</groupId > <artifactId > c3p0</artifactId > <version > 0.9.5.5</version > </dependency > <dependency > <groupId > mysql</groupId > <artifactId > mysql-connector-java</artifactId > <version > 5.1.38</version > </dependency > </dependencies > </plugin > </plugins > </build >
添加逆向工程的配置文件,文件名必须是:generatorConfig.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd" > <generatorConfiguration > <context id ="DB2Tables" targetRuntime ="MyBatis3" > <plugin type ="org.mybatis.generator.plugins.RenameExampleClassPlugin" > <property name ="searchString" value ="Example$" /> <property name ="replaceString" value ="Query" /> </plugin > <jdbcConnection driverClass ="com.mysql.jdbc.Driver" connectionURL ="jdbc:mysql://localhost:3306/tmp?useSSL=false" userId ="root" password ="123456" > </jdbcConnection > <javaModelGenerator targetPackage ="com.zhuweitung.mybatis.model" targetProject =".\src\main\java" > <property name ="enableSubPackages" value ="true" /> <property name ="trimStrings" value ="true" /> </javaModelGenerator > <sqlMapGenerator targetPackage ="com.zhuweitung.mybatis.mapper" targetProject =".\src\main\java" > <property name ="enableSubPackages" value ="true" /> </sqlMapGenerator > <javaClientGenerator type ="XMLMAPPER" targetPackage ="com.zhuweitung.mybatis.mapper" targetProject =".\src\main\java" > <property name ="enableSubPackages" value ="true" /> </javaClientGenerator > <table tableName ="user" domainObjectName ="UserDemo" /> </context > </generatorConfiguration >
更新详细地配置可以参考MyBatis Generator官方文档
执行maven插件命令
在对应的目录下会生成文件
分页插件
配置
pom中添加依赖
1 2 3 4 5 <dependency > <groupId > com.github.pagehelper</groupId > <artifactId > pagehelper</artifactId > <version > 5.3.2</version > </dependency >
在核心配置文件中配置插件
1 2 3 4 <plugins > <plugin interceptor ="com.github.pagehelper.PageInterceptor" /> </plugins >
使用
在查询功能之前使用PageHelper.startPage(int pageNum, int pageSize)
开启分页功能
pageNum:当前页的页码
pageSize:每页显示的条数
1 2 3 4 5 6 7 @Test void testPageHelper () { Page<User> page = PageHelper.startPage(1 , 10 ); List<User> users = userMapper.findAll(); System.out.println(users.size()); System.out.println(page); }
使用PageInfo获取导航
1 2 3 4 5 6 7 8 @Test void testPageHelper () { Page<User> page = PageHelper.startPage(1 , 10 ); List<User> users = userMapper.findAll(); System.out.println(users.size()); PageInfo<User> pageInfo = new PageInfo <>(users); System.out.println(pageInfo); }
常用属性:
pageNum:当前页的页码
pageSize:每页显示的条数
size:当前页显示的真实条数
total:总记录数
pages:总页数
prePage:上一页的页码
nextPage:下一页的页码
isFirstPage/isLastPage:是否为第一页/最后一页
hasPreviousPage/hasNextPage:是否存在上一页/下一页
navigatePages:导航分页的页码数
navigatepageNums:导航分页的页码,[1,2,3,4,5]