分页策略
数据表记录按页取出,只显示当前页的数据
pageSize = 10,共105条
第一页:1-10
第二页:11-20
第N页:begin(n-1)*pageSize+1
end:n * pageSize
第一种方式:基于缓存的分页策略
1)数据库从中全部取出,只显示当前页
2)只访问数据库一次,内存有压力.
3)用户只关心一小部分数据,浪费
4)好处是用户切换页面速度快,只有第一次取出时有延迟.
5)适合:数据量不大,用户每页都会查看.比如:审批作业
第二种方式:基于查询的分页策略
1)每次从数据库中只取一页的数据.
2)每次换页都要连接数据库,重新取数据.内存无压力
3)每页取数据时间都差不多.
4)适合:数据量大,但用户只查看小部分数据,比如:淘宝
例子3:基于缓存的分页策略
main: getData(3,10);//21-30
rs必须具备的功能;
1.跳到指定位置.
absolute(row); 指定绝对位置
relative(row); 指定相对位置;
2.不仅限于向前,可以向前或向后滚动.
next() 向后移动
previous() 向前移动
默认结果集:单向/单步
stmt = conn.createStatement();
rs = stmt.executeQuery(sql);
如果希望可滚动的结果集
stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
getDate(int page,int pageSize){
begin = (page-1) * pageSize +1 ;
rs = stmt.exectueQuery(select * from mytemp_hqr);
//指针指向begin
rs.absolte(begin);
while(遍历){
rs.getInt("id");
if(pageSize次) break;
}
}
容错:
1.如果用户输入负数或0, page =1
2.如果用户输入"abc", page =1
3.如果用户输入数字大于最大页,page =最后一页;
取数据的方式
rs = ...(selet id,name,salary from emp);
while(rs.next()){
rs.getString(1);//列的索引
rs.getString("id");//用列名代替列的索引,建议
}
其中用到的ConnectionUtils.java
1 package day1; 2 import java.io.*; 3 import java.sql.*; 4 import java.util.*; 5 /** 6 * 工具类,负责读入属性文件中的参数 7 * 注册驱动,获得连接,关闭资源 8 * @author soft01 9 * 10 */ 11 public class ConnectionUtils { 12 private static String driver="oracle.jdbc.driver.OracleDriver"; 13 private static String url="jdbc:oracle:thin:@192.168.2.205:1521:hqr"; 14 private static String dbUser="openlab"; 15 private static String dbPwd ="open123"; 16 17 /** 18 * 根据四个全局变量参数构造连接对象并返回 19 * @return Connection对象 20 */ 21 public static Connection getConnection(){ 22 Connection conn = null; 23 try { 24 Class.forName(driver); 25 conn = DriverManager.getConnection(url, dbUser, dbPwd); 26 } catch (Exception e) { 27 e.printStackTrace(); 28 } 29 return conn; 30 31 } 32 public static void close(ResultSet rs){ 33 if(rs != null){ 34 try { 35 rs.close(); 36 } catch (SQLException e) { 37 e.printStackTrace(); 38 } 39 } 40 } 41 public static void close(Statement stmt){ 42 if(stmt != null){ 43 try { 44 stmt.close(); 45 } catch (SQLException e) { 46 e.printStackTrace(); 47 } 48 } 49 } 50 public static void close(Connection conn){ 51 if(conn != null){ 52 try { 53 conn.close(); 54 } catch (SQLException e) { 55 e.printStackTrace(); 56 } 57 } 58 } 59 60 }
源代码
1 package day2; 2 import java.sql.*; 3 4 import day1.ConnectionUtils; 5 public class BufferPageDemo { 6 public static void main(String[] args) { 7 //getData("-3",10);//21-30 8 getTotalCount(); 9 } 10 /** 11 * 打印出第page页的数据 12 * @param page 要查询第几页 13 * @param pageSize 每页多少条 14 */ 15 private static void getData(int page,int pageSize){ 16 String sql = "select * from mytemp_hqr"; 17 int begin = (page-1)*pageSize + 1 ; 18 19 Connection conn = ConnectionUtils.getConnection(); 20 Statement stmt = null; 21 ResultSet rs = null; 22 try{ 23 //获得支持可滚动结果集的语句对象 24 stmt = conn.createStatement( 25 ResultSet.TYPE_SCROLL_INSENSITIVE, 26 ResultSet.CONCUR_READ_ONLY); 27 //指针指向beforeFirst 28 rs = stmt.executeQuery(sql); 29 //指针不能超过现有的记录数,结果集不能<=0.绝对位置的起点是1 30 31 //显示第page页的pageSize条记录 32 //指针指向当页的起点 33 rs.absolute(begin); 34 for(int i = 0;i < pageSize; i++){ 35 System.out.println(rs.getInt("id")); 36 //rs.next(); 37 if(!rs.next()){ 38 break; 39 } 40 } 41 42 } catch(Exception e){ 43 e.printStackTrace(); 44 } finally{ 45 ConnectionUtils.close(rs); 46 ConnectionUtils.close(stmt); 47 ConnectionUtils.close(conn); 48 } 49 } 50 51 //增加容错功能 52 public static void getData(String page,int pageSize){ 53 int intPage =1; 54 //解决用户输入的是字符串问题 55 try{ 56 intPage = Integer.parseInt(page);; 57 }catch(Exception e){ 58 } 59 //解决用户输入的是负数问题 60 if(intPage < 1){ 61 intPage = 1; 62 } 63 //解决用户输入的页数大于最大页 64 //getTotalPage(pageSize)用来计算总页数 65 int totalPages = getTotalPage(pageSize); 66 if(intPage > totalPages){ 67 intPage = totalPages; 68 } 69 getData(intPage,pageSize); 70 } 71 private static int getTotalPage(int pageSize) { 72 int totalCount = getTotalCount(); 73 int totalPage = 0; 74 if(totalCount % pageSize == 0){ 75 totalPage = totalCount / pageSize; 76 }else 77 totalPage = totalCount / pageSize+1; 78 return totalPage; 79 } 80 /** 81 * 计算数据表的总记录数 82 * @return 总记录数 83 */ 84 private static int getTotalCount() { 85 int totalCount = 0; 86 String sql = "select count(*) from mytemp_hqr"; 87 Connection conn = ConnectionUtils.getConnection(); 88 Statement stmt = null; 89 ResultSet rs = null; 90 try { 91 stmt = conn.createStatement(); 92 rs = stmt.executeQuery(sql); 93 rs.next(); 94 totalCount = rs.getInt(1); 95 } catch (SQLException e) { 96 e.printStackTrace(); 97 } finally{ 98 ConnectionUtils.close(rs); 99 ConnectionUtils.close(stmt); 100 ConnectionUtils.close(conn); 101 } 102 return totalCount; 103 } 104 }
例子4:基于查询的分页策略
每次只向数据库获取一页的数据
String sql = "selet * from my temp_hqr
where 第11条到20条";
Connection conn = ...;
Statement stmt = conn...;
ResultSet rs = stmt ...(sql)
while(rs.next()){
}
Oracle取出第begin到end条记录的方式:
select * from
(select rownum rn,id from mytemp_hqr)
where rn between 11 and 20;
MYSQL中取出第begin到end条记录的方式:
select * from mytemp_hqr
limit 11,10; ----limit begin,pageSize
源代码
1 package day2; 2 import day1.ConnectionUtils; 3 import java.sql.*; 4 /** 5 * 基于查询的分页策略 6 * @author soft01 7 * 8 */ 9 public class SelectPageDemo { 10 public static void main(String[] args) { 11 getData(3,10);//21-30 12 } 13 /** 14 * 显示指定页的数据 15 * @param page 要显示的第几页 16 * @param pageSize 每页显示多少条 17 */ 18 public static void getData(int page,int pageSize){ 19 String sql = "select * from" + 20 " (select rownum rn,id from mytemp_hqr)" + 21 " where rn between ? and ?"; 22 int begin = (page-1)*pageSize +1; 23 int end = page * pageSize; 24 Connection conn = ConnectionUtils.getConnection(); 25 PreparedStatement stmt = null; 26 ResultSet rs = null; 27 try{ 28 stmt = conn.prepareStatement(sql); 29 stmt.setInt(1, begin); 30 stmt.setInt(2, end); 31 rs = stmt.executeQuery(); 32 while(rs.next()){ 33 System.out.println(rs.getString("id")); 34 } 35 } catch (Exception e){ 36 e.printStackTrace(); 37 } finally{ 38 ConnectionUtils.close(rs); 39 ConnectionUtils.close(stmt); 40 ConnectionUtils.close(conn); 41 } 42 } 43 } 44 45