SSM分页查询

数据库:mysql5.7java

分页查询主要用到的仍是limitmysql

    limit 10,2    查询从第11条开始的后两条,即查询结果为11,12git

    limit 10         查询前10条github

    limit 10,0    查询第11条开始后0条,即结果为0web

    limit 10,-1   查询第11条开始后全部记录(早期版本支持,比较新的版本能够设置第二个参数为一个很大的值)spring

第一种方式,自定义分页查询sql

(1)工具类数据库

package com.lzy.util;

public class FenyeParam {
	
	private String field;
	private Integer start=0,count=0;
	
	public void setField(String[] fields) {
		this.field="";
		for(String f:fields) {
			this.field+=f+",";
		}
		//抹掉最后的逗号
		this.field=this.field.substring(0, this.field.length()-1);
	}
	
	public void setField1(String sqlFields) {
		//like "field,field2,field3..."
		this.field=sqlFields;
	}
	
	public void setStart(Integer start) {
		this.start=start;
	}
	
	public void setCount(Integer count) {
		this.count=count;
	}
	
	public String getField() {
		return this.field;
	}
	
	public Integer getStart() {
		return this.start;
	}
	
	public Integer getCount() {
		return this.count;
	}

	@Override
	public String toString() {
		return "FenyeParam [field=" + field + ", start=" + start + ", count=" + count + "]";
	}
	
	
}

自定义了一个分页参数类FenyeParam:数组

    field参数为查询的字段,start为开始位置,count为查询记录条数;安全

    field参数设置提供两种方法,setField(String[])方法接收数组,自动拼接sql查询字段;setField1(String)接收String字符串,为sql字段样式(例:"id,name,sex");

(2)相关mapper.xml文件配置:

<!-- 分页查询 -->
  <select id="selectFenYe" parameterType="com.lzy.util.FenyeParam" resultType="com.lzy.bean.User">
  	SELECT ${fenyeParam.field} FROM User limit #{fenyeParam.start,jdbcType=INTEGER},#{fenyeParam.count,jdbcType=INTEGER}
  </select>

mybatis中${}和#{}区别:

    ${}为原样输入,不会修改或转义字符串

    #{}为字符串类型输入,根据PreparedStatement安全设置参数

扩充:

PreparedStatement为JDBC sql预处理,替换对应sql字符串中的?,安全,以下代码比较直观:

package sdfadf;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class JDBCUtil {
	public static void main(String[] args) {
		try {
			Class.forName("com.mysql.cj.jdbc.Driver");
			Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/testpq?characterEncoding=utf8&useSSL=true&serverTimezone=UTC","xxx","xxxxxx");
			String sql="select id,name from user where id=?";
			PreparedStatement ps = conn.prepareStatement(sql);
			ps.setString(1, "11");
			ResultSet rs = ps.executeQuery();
			while(rs.next()) {
				System.out.println(rs.getString("id")+","+rs.getString("name"));
			}
			rs.close();
			ps.close();
			conn.close();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
}

本文用的是mysql5.7,Driver和url根据需本身版本

(3)调用(没有写完完整的controller层和service层,只完成了dao层和mapper.xml,这里的测试用的是junit的单元测试)

package com.lzy.test;

import java.util.List;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.lzy.bean.User;
import com.lzy.dao.UserMapper;
import com.lzy.util.FenyeParam;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations= {"classpath:applicationContext.xml"})
public class MyTest {
	
	@Autowired
	UserMapper uMapper;
	
	@Test
	public void Test2() {
		FenyeParam fenyeParam=new FenyeParam();
		String[] fields=new String[] {"id","name"};
		fenyeParam.setField(fields);
		//fenyeParam.setField1("id,name");
		fenyeParam.setStart(10);
		fenyeParam.setCount(2);
		List<User> user = uMapper.selectFenYe(fenyeParam);
		System.out.println(user);
	}
	
	
}

结果:

第二种方式,MyBatis分页插件PageHelper的使用

一、pom加入PageHelper依赖关系

<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper -->
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>5.1.8</version>
</dependency>

二、配置PageHelper

    配置PageHelper有在MyBatis配置文件中配置和在Spring配置文件中配置两种方式,详情请参考官方说明:

https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/en/HowToUse.md

本次采用Mybatis配置文件mybatis-config.xml中配置的方式,只须要在mybatis配置文件中加入PageInterceptor,具体以下:

<?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>
  <settings>
    <setting name="mapUnderscoreToCamelCase" value="true"/>
  </settings>
  <typeAliases>
    <package name="com.lzy.bean"/>
  </typeAliases>
  <plugins>
  	<plugin interceptor="com.github.pagehelper.PageInterceptor">
  		<!-- 详细配置项 -->
  	</plugin>
  </plugins>
</configuration>

没有特殊要求如上便可,具体配置参考官方地址:

https://pagehelper.github.io/docs/howtouse/

三、使用

PageHelper.startPage(pageNum, pageSize)方法后的第一个查询方法就会进行分页查询,故这里只须要将调用查询的方法放到PageHelper.startPage(pageNum, pageSize)方法以后就行。例以下在controller层使用PageHelper.startPage(pageNum, pageSize)对调用service层的查询方法进行分页查询:

package com.lzy.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.lzy.bean.User;
import com.lzy.service.TPQService;

@Controller
public class TPQController {
	
	@Autowired
	TPQService tService;
	
	@ResponseBody
	@RequestMapping("/tpq")
	public PageInfo<User> Tpq() {
		PageHelper.startPage(10, 2);
		List<User> list = tService.selectPQ();
		System.out.println(list);
		PageInfo<User> pu=new PageInfo<>(list);
		System.out.println(pu);
		return pu;
	}
	
}
package com.lzy.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.lzy.bean.User;
import com.lzy.bean.UserExample;
import com.lzy.dao.UserMapper;

@Service
public class TPQService {

	@Autowired
	UserMapper uMapper;
	
	public List<User> selectPQ() {
		UserExample example=new UserExample();
		return uMapper.selectByExample(example);
	}

}

查询结果:

下方PageInfo具体结果以下:

PageInfo{pageNum=10, pageSize=2, size=2, startRow=19, endRow=20, total=99, pages=50, list=Page{count=true, pageNum=10, pageSize=2, startRow=18, endRow=20, total=99, pages=50, reasonable=false, pageSizeZero=false}[User [id=19, name=user19], User [id=20, name=user20]], prePage=9, nextPage=11, isFirstPage=false, isLastPage=false, hasPreviousPage=true, hasNextPage=true, navigatePages=8, navigateFirstPage=6, navigateLastPage=13, navigatepageNums=[6, 7, 8, 9, 10, 11, 12, 13]}

说明:

PageHelper.startPage(10, 2);//分页插件应用
List<User> list = tService.selectPQ();//查询数据

 

PageInfo<User> pu=new PageInfo<>(list);//转为分页结果对象

PageInfo属性说明:

pageNum				当前页码
pageSize			当前页码条数
startRow			查询结果开始记录位置,即结果是第startRow条记录开始
endRow				查询结果结束记录位置,即结果到第endRow条记录结束
pages				全部记录总共分为pages页
prePage				上一页页码
nextPage			下一页页码
isFirstPage			是不是第一页
isLastPage			是不是最后一页
hasPreviousPage		是否有前一页
hasNextPage			是否有后一页
navigatePages		导航条显示页码数目navigatePages,即navigatepageNums的个数
navigatepageNums	导航条显示具体页码的值
navigateFirstPage	导航条开始页码
navigateLastPage	导航条结束页码
total				总数据条数
list				查询结果

注意:

(1)根据官方建议,mybatis配置方式和spring配置方式最好二选其一。

(2)编辑代码时要注意分页时机,以下给出一段官方的不安全代码:

PageHelper.startPage(1, 10);
List<Country> list;
if(param1 != null){
    list = countryMapper.selectIf(param1);
} else {
    list = new ArrayList<Country>();
}

根据官方说明,PageHelper使用静态的ThreadLocal参数(据说:ThreadLocal用于保存某个线程共享变量:对于同一个static ThreadLocal,不一样线程只能从中get,set,remove本身的变量,而不会影响其余线程的变量),分页参数和现场是绑定的。故上述代码中param1参数为null时,分页线程已经产生,可是没有被利用,也没有被释放(PageHelper在finally代码中自动清除了ThreadLocal存储对象),当这个线程再次被使用时就会致使分页结果与预期结果不同的状况。而将上述代码改成以下代码就能保证安全:

List<Country> list;
if(param1 != null){
    PageHelper.startPage(1, 10);
    list = countryMapper.selectIf(param1);
} else {
    list = new ArrayList<Country>();
}

固然也能够调用PageHelper.clearPage();方法来清除ThreadLocal,但官方认为没有必要,嗯,不必。

相关文章
相关标签/搜索