MyBatis分页剖析
对于Mybatis的分页,selectList方法是通过传一个RowBounds对象过去实现的。如:session.selectList("com.wheat.dao.UserDao.returnAllUser",null, new RowBounds(10,20)); 运行起来没有问题。在调优的时候发现,怎么后台的打印信息怎么那么多的?我分页大小是20,log4j却常常打印一整版。我调用出错了?查了下一切正常。
今天决定在机器上试验下。我写了两种方式的分页。一种是Mybatis内置的分页,另一种是自己写SQL的分页。数据库依然是MySQL,测试环境Junit。
上码,Mybatis内置的分页:
- <span style="font-family:SimSun;font-size:14px;"> @Test
- @SuppressWarnings("rawtypes")
- public void TestUserDaoPagingWithMybatisWay() throws IOException{
- String resource = "META-INF/conf/mybatis-config.xml";
- InputStream inputStream = Resources.getResourceAsStream(resource);
- SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
- SqlSession session = sqlSessionFactory.openSession();
- List result = session.selectList("com.wheat.dao.UserDao.returnAllUser", null, new RowBounds(10,20));
- if(result!=null){
- for(Object o:result){
- Map map = (Map) o;
- System.out.print(map.get("ID")+",");
- System.out.print(map.get("USERNO")+",");
- System.out.println(map.get("USERNAME"));
- }
- System.out.println("success!");
- }
- }</span>
SQL的分页:
- <span style="font-family:SimSun;font-size:14px;"> @Test
- @SuppressWarnings("rawtypes")
- public void TestUserDaoPagingWithMyWay() throws IOException{
- String resource = "META-INF/conf/mybatis-config.xml";
- InputStream inputStream = Resources.getResourceAsStream(resource);
- SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
- SqlSession session = sqlSessionFactory.openSession();
- HashMap<String, Object> requestParameters = new HashMap<String, Object>();
- requestParameters.put("begin", 10);
- requestParameters.put("pageSize", 20);
- List result = session.selectList("com.wheat.dao.UserDao.returnAllUserWithPaging",requestParameters);
- if(result!=null){
- for(Object o:result){
- Map map = (Map) o;
- System.out.print(map.get("ID")+",");
- System.out.print(map.get("USERNO")+",");
- System.out.println(map.get("USERNAME"));
- }
- System.out.println("success!");
- }
- }</span>
对应的Mapper文件代码:
- <span style="font-family:SimSun;font-size:14px;"> <select id="returnAllUser" resultType="java.util.HashMap" >
- <![CDATA[
- SELECT ID, USERNAME, USERNO FROM USERINFO
- ]]>
- </select>
- <select id="returnAllUserWithPaging" resultType="java.util.HashMap" parameterType="java.util.HashMap">
- <![CDATA[
- SELECT ID, USERNAME, USERNO FROM USERINFO
- ]]>
- <trim prefix="LIMIT" prefixOverrides=",">
- <if test="begin != null">#{begin,jdbcType=NUMERIC}</if>
- <if test="pageSize != null">,#{pageSize,jdbcType=NUMERIC}</if>
- </trim>
- </select></span>
运行的控制台信息:
Mybatis内置的分页:
SQL的分页:
从上面可以看到,Mybatis内置方式的分页其实是先将表中的前面 (初始位置+分页大小)行返回,再从中截取最后面分页大小行数据返回给我们。而不是像我之前所想的那样,Mybatis先将分页语句按语言特性重写再执行。
所以在使用MyBatis开发时,分页语句还是得自己写。如果涉及到上万行的查询。这个性能瓶颈将变得很明显。