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,但官方認爲沒有必要,嗯,不必。

相關文章
相關標籤/搜索