一,通用分页
1.1 概述:
通用分页是指在不同数据源和不同数据类型的情况下,使用相同的接口和方法实现分页的方法。通用分页通常用于需要处理多种数据源和数据类型的应用程序中。
1.2 为什么要使用?(4点)
1. 可以减少重复代码。在不同的应用场景下需要分页显示的内容可能不同,但实现分页的方式往往相似。使用通用分页可以将分页逻辑封装起来,避免编写大量重复的代码。
2. 提高代码的可重用性。不同的数据源和数据类型需要使用不同的分页方法,如果每次都需要重新编写分页逻辑,会浪费很多时间和精力。使用通用分页可以将分页逻辑封装起来,在需要时直接调用,提高代码的可重用性。
3. 提高代码的可维护性。将分页逻辑封装起来之后,如果需要修改分页方法,只需要修改通用分页方法即可,避免了在多个地方修改代码的麻烦。
4. 提高代码的可移植性。使用通用分页方法,无论在哪个应用中需要分页显示内容,都可以使用相同的分页方法,提高代码的可移植性。
1.3 该怎么使用?
- 根据需要实现通用的分页方法,可以使用存储过程、SQL语句、框架插件等方式实现。
- 在需要分页显示的页面中调用通用分页方法,将分页参数传递给分页方法。
- 分页方法根据传递的分页参数从数据源中查询出对应的数据,然后将查询结果返回给页面。
- 页面根据分页方法返回的结果,显示相应的分页信息和数据。
二,查询数据
要分页首先要获取数据库所有数据再进行一个分页查询,以下案例是查询所有及模糊查询案例一起实现的案例
需要定义数据库相对应的属性
定义实体类代码:
package com.LiuBing.text; public class Book { private int bid; private String bname; private float price; @Override public String toString() { return "Book [bid=" + bid + ", bname=" + bname + ", price=" + price + "]"; } public int getBid() { return bid; } public void setBid(int bid) { this.bid = bid; } public String getBname() { return bname; } public void setBname(String bname) { this.bname = bname; } public float getPrice() { return price; } public void setPrice(float price) { this.price = price; } }
通用分页封装代码:
package com.LiuBing.util; /** * 分页工具类 * */ public class PageBean { private int page = 1;// 页码 private int rows = 10;// 页大小 private int total = 0;// 总记录数 private boolean pagination = true;// 是否分页 public PageBean() { super(); } public int getPage() { return page; } public void setPage(int page) { this.page = page; } public int getRows() { return rows; } public void setRows(int rows) { this.rows = rows; } public int getTotal() { return total; } public void setTotal(int total) { this.total = total; } public void setTotal(String total) { this.total = Integer.parseInt(total); } public boolean isPagination() { return pagination; } public void setPagination(boolean pagination) { this.pagination = pagination; } /** * 获得起始记录的下标 * * @return */ public int getStartIndex() { return (this.page - 1) * this.rows; } @Override public String toString() { return "PageBean [page=" + page + ", rows=" + rows + ", total=" + total + ", pagination=" + pagination + "]"; } }
以下dao方法,参数为实体和页码,实体集合拿数据,页码PageBean是封装类封装分页的工具类(如上代码)以便写通用分页的时候调用,再定义查询sql语句,模糊查询根据name查询,从实体获取name进行一个判断name是否为空,不为空就将模糊查询语句拼接到查询所有中(如下代码)
package com.LiuBing.dao; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import javax.websocket.Decoder.Text; import org.junit.Test; import com.LiuBing.text.Book; import com.LiuBing.util.BookDao2; import com.LiuBing.util.DBAccess; import com.LiuBing.util.PageBean; import com.LiuBing.util.StringUtils; public class BookDao extends BookDao2<Book>{ public List<Book> List(Book book,PageBean pagebean) throws Exception{ List<Book> list= new ArrayList<Book>(); //获取连接对象 Connection con = DBAccess.getConnection(); //编写sql语句 String sql ="select * from t_mvc_book where 1=1 ";//查询所有 where定义1意思就是后面也许要用到拼接先定为1 String bname = book.getBname();//获取实体中的name if(StringUtils.isNotBlank(bname)) {//判断name是否为空 sql+="and bname like '%"+bname+"%'";//不为空 将模糊查询的语句name拼接到查询所有语句里面 } //执行sql语句 PreparedStatement ps = con.prepareStatement(sql); //执行结果集 ResultSet rs= ps.executeQuery(); //遍历结果集 while(rs.next()) { //数据库字段放进实体类 Book bk = new Book(); bk.setBid(rs.getInt("bid")); bk.setBname(rs.getString("bname")); bk.setPrice(rs.getFloat("price")); //将实体放入集合 list.add(bk); } return list; } public static void main(String[] args) throws Exception { BookDao Bookdao = new BookDao(); Book book = new Book(); //模糊查询关键字 book.setBname("圣墟"); PageBean pagebean = new PageBean(); List<Book> list = Bookdao.List(book, pagebean); for (Book book2 : list) { System.out.println(book2); } } }
最后查询所有运行结果如下:
模糊查询,在测试中调用实体book属性name查询即可(如下图)
模糊查询运行图:
三,反射查询所有
3.1 大致步骤:
反射完成查询所有,定义类的时候中指定泛型,在while循环中,获取类类反射,再通过反射getDeclaredFields获取所有的对象,遍历对象获取name对象,name等同于获取所有的类中的所有的属性,最后将反射加到集合中
代码展示:
package com.LiuBing.util; import java.lang.reflect.Field; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import com.LiuBing.text.Book; import com.LiuBing.util.DBAccess; import com.LiuBing.util.PageBean; import com.LiuBing.util.StringUtils; public class BookDao2<T> { public List<T> executeQuery(String sql, Class clz, PageBean pagebean) throws Exception { List<T> list = new ArrayList<T>(); // 获取连接对象 Connection con = null; // 执行sql语句 PreparedStatement ps = null; // 执行结果集 ResultSet rs = null; // 遍历结果集 while (rs.next()) { // 反射 T t = (T) clz.newInstance(); // 获取clz中所有属性对象 Field[] field = clz.getDeclaredFields(); // 遍历 for (Field fields : field) { fields.setAccessible(true);// 打开权限 fields.set(t, rs.getObject(fields.getName()));// 获取所有属性 } list.add(t); } return list; } }
四,JUnit的使用
4.1概念
一种基于Java语言编写的开源的单元测试框架,它支持简单单元测试和复杂单元测试,被广泛应用于Java开发中,通过单元测试能够检验代码是否符合预期,提高代码可靠性、可维护性和可重用性。总的来说main运行方法一个类中只能定义一个,但在JUnit可以调用多次
4.2设置步骤(如下图)
6 选择JUnit,7最后将Junit5版本改成JUnit4,点击Finish即可
JUnit使用代码:
在方法上行代码写上@Test,void无返回关键字后text()方法
package com.LiuBing.dao; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import javax.websocket.Decoder.Text; import org.junit.Test; import com.LiuBing.text.Book; import com.LiuBing.util.BookDao2; import com.LiuBing.util.DBAccess; import com.LiuBing.util.PageBean; import com.LiuBing.util.StringUtils; public class BookDao extends BookDao2<Book>{ public List<Book> List(Book book,PageBean pagebean) throws Exception{ String sql ="select * from t_mvc_book where 1 "; String bname = book.getBname(); if(StringUtils.isNotBlank(bname)) { sql+=" and bname like '%"+bname+"%'"; } return super.executeQuery(sql, Book.class, pagebean); } //junit注解方式 可以运行多个main方法 @Test public void text1() throws Exception { System.out.println("text1..."); BookDao bookdao=new BookDao(); Book book = new Book(); book.setBname("圣墟"); PageBean pagebean= new PageBean(); List<Book> list = bookdao.List(book, pagebean); for (Book book2 : list) { System.out.println(book2); } } @Test public void text2() throws Exception { System.out.println("text2..."); BookDao bookdao=new BookDao(); Book book = new Book(); book.setBname("圣墟"); PageBean pagebean= new PageBean(); List<Book> list = bookdao.List(book, pagebean); for (Book book2 : list) { System.out.println(book2); } } }
五,通用分页的实现
定义一个类并指定泛型,以便在测试类中继承该类,参数根据sql语句及指定的类和PageBean分页工具类,如果想修改数据页面条数可以在PageBean分页工具类进行修改
package com.LiuBing.util; import java.lang.reflect.Field; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import com.LiuBing.text.Book; import com.LiuBing.util.DBAccess; import com.LiuBing.util.PageBean; import com.LiuBing.util.StringUtils; public class BookDao2<T> { public List<T> executeQuery(String sql, Class clz, PageBean pagebean) throws Exception { List<T> list = new ArrayList<T>(); // 获取连接对象 Connection con = null; // 执行sql语句 PreparedStatement ps = null; // 执行结果集 ResultSet rs = null; if (pagebean != null && pagebean.isPagination()) { String countsql = getCount(sql); con = DBAccess.getConnection(); ps = con.prepareStatement(countsql); rs = ps.executeQuery(); if (rs.next()) { pagebean.setTotal(rs.getObject("n").toString()); } String Pagesql = getpagesql(sql, pagebean); con = DBAccess.getConnection(); ps = con.prepareStatement(Pagesql); rs = ps.executeQuery(); } else { con = DBAccess.getConnection(); ps = con.prepareStatement(sql); rs = ps.executeQuery(); } // 遍历结果集 while (rs.next()) { // 反射 T t = (T) clz.newInstance(); // 获取clz中所有属性对象 Field[] field = clz.getDeclaredFields(); // 遍历 for (Field fields : field) { fields.setAccessible(true);// 打开权限 fields.set(t, rs.getObject(fields.getName()));// 获取所有属性 } list.add(t); } return list; } private String getpagesql(String sql, PageBean pagebean) { // TODO Auto-generated method stub return sql + " limit " + pagebean.getStartIndex() + "," + pagebean.getRows(); } private String getCount(String sql) { // TODO Auto-generated method stub return "SELECT count(1) as n from (" + sql + ") t"; } }
测试类运行结果: