思考
为什么要分页?
如果一条查询语句查询的记录太多,那么结果返回也就越慢,那么执行的效率也就越低,而且我们一次性也看不完这么多的数据,所以我们采用了分页处理,减少数据的处理量
一、使用limit实现分页(重点)
MYSQL中通过Limit关键字实现分页(Limit是MYSQL的方言)
- 语法:SELECT * FROM USER LIMIT startIndex,pageSize;
- startIndex:指定是记录的index,从0开始,0对应数据库中的第一条记录
- pageSize:每页显示几条记录
- 如果LIMIT后面只跟了一个数字NUM,那么取值为[1,NUM] (记录的index)
在MyBatis中实现分页,核心还是SQL语句
- 接口定义
package com.thhh.dao; import com.thhh.pojo.User; import java.util.List; import java.util.Map; //在mybatis中,我们一般不写dao,而将其改写为mapper,其实二者是一样的,只是名字变了 public interface UserMapper { //1、通过ID查询用户 User getUserById(int id); //2、使用limit实现分页 List<User> getUserLimit(Map<String,Object> map); }
- mapper.xml文件实现接口
<?xml version="1.0" encoding="UTF8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.thhh.dao.UserMapper"><!--属性namespace,即命名空间,用于绑定一个 mapper/dao 接口--> <!--②创建一个resultMap节点,将其id属性设为①中设置的resultMap的属性值,type属性设置为集合中元素的类型--> <resultMap id="UserMap" type="User"> <!--设置映射规则,column属性代表数据表中的字段名,property代表实体类中的属性名 这里就是将二者之间的映射显示的写出来,这样在返回的时候就算字段名称和属性名称不一致,也知道怎么设置实体类的属性值--> <result column="pwd" property="password"/> </resultMap> <!--①返回值属性从resultType改为resultMap,并设置属性值为自定义的一个resultMap的值--> <select id="getUserById" resultMap="UserMap"> select * from mybatis.user where id = #{id} </select> <select id="getUserLimit" parameterType="map" resultMap="UserMap"> select * from mybatis.user limit #{startIndex},#{pageSize} </select> </mapper>
注意:由于在8里面我们学习结果集映射的时候将pojo的属性名称修改,使得它的属性名称和数据库中的字段不对应,所以上面的分页查询使用的不是resultType,而是resultMap来设置返回类型
- 测试
@Test public void testGetUserLimit(){ //1、获取SqlSession对象 SqlSession sqlSession = MyBatisUtils.getSqlSession(); //2、获取执行SQL的对象,获取的方法就是通过sqlSession.getMapper(),去获取User.class的mapper映射器 UserMapper mapper = sqlSession.getMapper(UserMapper.class); Map<String,Object> map = new HashMap<String,Object>(); map.put("startIndex",2); map.put("pageSize",2); List<User> userList = mapper.getUserLimit(map); for (User user : userList) { System.out.println(user); } sqlSession.close(); }
输入的startIndex = 2,对应数据库中的第3条数据,所以上面的输出是正确的
测试成功!
二、使用RowBounds实现分页(了解)
了解为主,比较老的技术了,现在开发中很少用
为什么有RowBounds?就是有开发者觉得SQL语句查询应该就是做查询的事情,分页的操作应该使用Java代码实现;即不再使用SQL实现分页
使用步骤
- 接口
package com.thhh.dao;
import com.thhh.pojo.User;
import java.util.List;
import java.util.Map;
//在mybatis中,我们一般不写dao,而将其改写为mapper,其实二者是一样的,只是名字变了
public interface UserMapper {
//1、通过ID查询用户
User getUserById(int id);
//2、使用limit实现分页
List<User> getUserLimit(Map<String,Object> map);
//3、使用rowbounds实现分页
List<User> getUserByRowbounds(Map<String,Object> map);
}
- mapper.xml
<?xml version="1.0" encoding="UTF8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.thhh.dao.UserMapper"><!--属性namespace,即命名空间,用于绑定一个 mapper/dao 接口-->
<!--②创建一个resultMap节点,将其id属性设为①中设置的resultMap的属性值,type属性设置为集合中元素的类型-->
<resultMap id="UserMap" type="User">
<!--设置映射规则,column属性代表数据表中的字段名,property代表实体类中的属性名
这里就是将二者之间的映射显示的写出来,这样在返回的时候就算字段名称和属性名称不一致,也知道怎么设置实体类的属性值-->
<result column="pwd" property="password"/>
</resultMap>
<!--①返回值属性从resultType改为resultMap,并设置属性值为自定义的一个resultMap的值-->
<select id="getUserById" resultMap="UserMap">
select * from mybatis.user where id = #{id}
</select>
<select id="getUserLimit" parameterType="map" resultMap="UserMap">
select * from mybatis.user limit #{startIndex},#{pageSize}
</select>
<select id="getUserByRowbounds" resultMap="UserMap">
select * from mybatis.user
</select>
</mapper>
- 测试
@Test
public void testGetUserByRowbounds(){
//1、获取SqlSession对象
SqlSession sqlSession = MyBatisUtils.getSqlSession();
//rowbounds实现
RowBounds rowBounds = new RowBounds(1,2);//构造就传入startIndex,pageSize
List<User> userList = sqlSession.selectList("com.thhh.dao.UserMapper.getUserByRowbounds", null, rowBounds);
//mybatis第二种调用方法,不推荐使用,但是RowBounds要依赖这个方法实现
//第二个参数没有直接传一个null
//第一个参数相当于前面的sqlSession.getMapper(UserMapper.class);
//第三个参数就是RowBounds对象
for (User user : userList) {
System.out.println(user);
}
sqlSession.close();
}
三、分页插件(了解)
对于这个插件,我们现在只要知道就行,如果以后工作中要求用这个,我们直接到官网找到文档使用即可,文档中有详细的使用步骤,只是文档中的描述不是很让人接受,在看的时候最好转为自己的话来理解;实在不行了还可以百度别人总结的用法,大家都是老缝合怪了,应该都知道怎么用