一通用分页介绍
1.什么是通用分页?
通用分页是一种可以应用于多种数据类型和数据源的分页机制。通常情况下,分页是指从数据库中获取特定数量的记录,并将其按照某种标准划分成一页一页的数据。通用分页可以应用于不同类型的数据集合,如数组、列表、集合等,并且可以支持不同类型的数据源,如数据库、文件、缓存等。
通用分页的主要目的是提高代码的复用性和可维护性,避免在不同情况下重复编写分页逻辑。通用分页通常会定义一个分页参数对象,用于描述分页的基本信息,如每页记录数、当前页码、总记录数等。然后,针对某个具体的数据类型或数据源,可以编写通用的分页逻辑,根据分页参数对象和具体数据源,返回分页结果。
通用分页可以应用于任何需要分页查询的场景,例如Web开发中的分页查询、数据分析中的分页取数、移动端中的分页展示等。通用分页可以帮助我们更快速、更方便地实现分页功能,以及将分页逻辑从具体的业务代码中解耦出来,提高代码的复用性和可维护性。
2.在企业中通用分页的作用
1. 方便复用
企业中的数据处理往往涉及到很多的分页功能,如果每个地方都单独编写分页逻辑,将会增加代码量和维护难度。如果使用通用分页,将分页逻辑抽象出来,封装成通用的分页模块,可以方便复用,减少代码量和维护难度。
2. 提高效率
数据量庞大的企业级应用场景中,通用分页可以通过减少需要处理的数据量,提高查询效率。通过通用分页,可以尽可能地减少数据的读取和传输,从而提高数据库的查询效率,使得企业级应用更加高效。
3. 提高代码可维护性
通用分页机制可以将分页逻辑解耦出来,降低代码的耦合性,提高代码的可维护性。同时,通用分页组件可以更好的处理分页操作中的异常情况,比如页码不合法等,避免代码中出现大量重复的逻辑代码。
4. 提高用户体验
通用分页可以在产品的可用性和易用性方面发挥不小的作用。它可以更好地适应不同的设备和屏幕分辨率,并支持更多的交互方式,例如定制每页显示多少条数据、切换到下一页、上一页、跳转到某一页等,以更好地满足用户的需求,提升用户体验。
3.说明
这是小编自己在学习中分享的一些技术,如果在使用中出现一些问题很抱歉奥!如果有什么问题的话可以私聊小编,小编都会去看的!
二. MySQL,前期准备工作
1.mysql数据库连接
package com.lz.utils; import java.io.InputStream; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.Properties; /** * 提供了一组获得或关闭数据库对象的方法 * */ public class DBAccess { private static String driver; private static String url; private static String user; private static String password; static {// 静态块执行一次,加载 驱动一次 try { InputStream is = DBAccess.class .getResourceAsStream("config.properties"); Properties properties = new Properties(); properties.load(is); driver = properties.getProperty("driver"); url = properties.getProperty("url"); user = properties.getProperty("user"); password = properties.getProperty("pwd"); Class.forName(driver); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException(e); } } /** * 获得数据连接对象 * * @return */ public static Connection getConnection() { try { Connection conn = DriverManager.getConnection(url, user, password); return conn; } catch (SQLException e) { e.printStackTrace(); throw new RuntimeException(e); } } public static void close(ResultSet rs) { if (null != rs) { try { rs.close(); } catch (SQLException e) { e.printStackTrace(); throw new RuntimeException(e); } } } public static void close(Statement stmt) { if (null != stmt) { try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); throw new RuntimeException(e); } } } public static void close(Connection conn) { if (null != conn) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); throw new RuntimeException(e); } } } public static void close(Connection conn, Statement stmt, ResultSet rs) { close(rs); close(stmt); close(conn); } public static boolean isOracle() { return "oracle.jdbc.driver.OracleDriver".equals(driver); } public static boolean isSQLServer() { return "com.microsoft.sqlserver.jdbc.SQLServerDriver".equals(driver); } public static boolean isMysql() { return "com.mysql.cj.jdbc.Driver".equals(driver); } public static void main(String[] args) { Connection conn = DBAccess.getConnection(); System.out.println(conn); DBAccess.close(conn); System.out.println("isOracle:" + isOracle()); System.out.println("isSQLServer:" + isSQLServer()); System.out.println("isMysql:" + isMysql()); System.out.println("数据库连接(关闭)成功"); } }
注意在实现mysql数据库连接时:要开启mysql服务,就算时自动开启还是要去检查避免数据库启动不了!
1.1.1 数据库连接配置文件
#oracle9i #driver=oracle.jdbc.driver.OracleDriver #url=jdbc:oracle:thin:@localhost:1521:orcl #user=scott #pwd=123 #sql2005 #driver=com.microsoft.sqlserver.jdbc.SQLServerDriver #url=jdbc:sqlserver://localhost:1433;DatabaseName=test1 #user=sa #pwd=123 #sql2000 #driver=com.microsoft.jdbc.sqlserver.SQLServerDriver #url=jdbc:microsoft:sqlserver://localhost:1433;databaseName=unit6DB #user=sa #pwd=888888 #mysql driver=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/mybatis_ssm?useUnicode=true&characterEncoding=UTF-8&useSSL=false user=root pwd=123456
注意:这个文件和数据库连接在同一个包里,并且在使用这两个文件使用连接数据库时可以1根据自己的需求来进行不同的数据库连接,在这里我连接的是MySQL,
1.1.2 实体类
注意:在创建实体时要注意是否和数据库的类型,名字一致,不然在后续的操作中会影响,还可能产生一些错误
package com.lz.entity; 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; } }
2.过滤器
作用:解决中文乱码,以及编码的不同从而进行筛选
package com.lz.utils; import java.io.IOException; import java.util.Iterator; import java.util.Map; import java.util.Set; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * 中文乱码处理 * */ public class EncodingFiter implements Filter { private String encoding = "UTF-8";// 默认字符集 public EncodingFiter() { super(); } public void destroy() { } public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; HttpServletResponse res = (HttpServletResponse) response; // 中文处理必须放到 chain.doFilter(request, response)方法前面 res.setContentType("text/html;charset=" + this.encoding); if (req.getMethod().equalsIgnoreCase("post")) { req.setCharacterEncoding(this.encoding); } else { Map map = req.getParameterMap();// 保存所有参数名=参数值(数组)的Map集合 Set set = map.keySet();// 取出所有参数名 Iterator it = set.iterator(); while (it.hasNext()) { String name = (String) it.next(); String[] values = (String[]) map.get(name);// 取出参数值[注:参数值为一个数组] for (int i = 0; i < values.length; i++) { values[i] = new String(values[i].getBytes("ISO-8859-1"), this.encoding); } } } chain.doFilter(request, response); } public void init(FilterConfig filterConfig) throws ServletException { String s = filterConfig.getInitParameter("encoding");// 读取web.xml文件中配置的字符集 if (null != s && !s.trim().equals("")) { this.encoding = s.trim(); } } }
3.分页代码前期准备
当前页:page
显示记录数:rows
总记录数:total
start =(page-1)*rows
是否分页:pagination
根据需求来判断
package com.lz.utils; /** * 分页工具类 * */ 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和新版Dao
1.老版普通Dao
* public List<Book> list(Book bk, PageBean pageBean) throws Exception { List<Book> list = new ArrayList<Book>(); Connection conn = DBAccess.getConnection(); String sql = "select *from t_mvc_book where 1=1"; String bname = bk.getBname(); if (StringUtils.isNotBlank(bname)) { sql += " and bname like '%" + bname + "%' "; } PreparedStatement ps = conn.prepareStatement(sql); ResultSet rs = ps.executeQuery(sql); while (rs.next()) { Book b = new Book(); b.setBid(rs.getInt("bid")); b.setBname(rs.getString("bname")); b.setPrice(rs.getFloat("price")); list.add(b); }return list; }
2.通用查询Dao
2.1创建BaseDao
package com.lz.utils; import java.lang.reflect.Field; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.util.ArrayList; import java.util.List; public class BaseDao<T> { public List<T> executeQuery(String sql, Class clz, PageBean pageBean) throws Exception { List<T> list = new ArrayList<T>(); Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; if (pageBean != null && pageBean.isPagination()) { String countSql = getCountSql(sql); conn = DBAccess.getConnection(); ps = conn.prepareStatement(countSql); rs = ps.executeQuery(countSql); if (rs.next()) { pageBean.setTotal(rs.getObject("n").toString()); } String pageSql = getPageSql(sql, pageBean); conn = DBAccess.getConnection(); ps = conn.prepareStatement(pageSql ); rs = ps.executeQuery(pageSql ); } else { conn = DBAccess.getConnection(); ps = conn.prepareStatement(sql); rs = ps.executeQuery(sql); } while (rs.next()) { // 通过泛型来代替 Book b = new Book(); T t = (T) clz.newInstance(); Field[] fields = clz.getDeclaredFields(); for (Field f : fields) { f.setAccessible(true); // System.out.println(f.getName()); f.set(t, rs.getObject(f.getName())); list.add(t); } } return list; } /** * sql bookdao的sql 最终sql * * @param sql * @param pageBean * @return */ private String getPageSql(String sql, PageBean pageBean) { return sql + " LIMIT " + pageBean.getStartIndex() + "," + pageBean.getRows(); } /** * 查询 总记录数 * * @param sql * @return */ private String getCountSql(String sql) { return "SELECT COUNT(1) as n from (" + sql + ") t "; } }
2.2通用查询Dao
public List<Book> list(Book bk, PageBean pageBean) throws Exception { String sql = "select *from t_mvc_book where 1=1"; String bname = bk.getBname(); if (StringUtils.isNotBlank(bname)) { sql += " and bname like '%" + bname + "%' "; } return super.executeQuery(sql, Book.class, pageBean); }
3.二者区别
新版本:在就版本的基础上将
代码重复
Connection conn = DBAccess.getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet rs = ps.executeQuery(sql);
流程重复
1.创建表相对应的实体对象
2.查询 的结果天加到实例化对象属性中
3被添加的实体对象,加入集合中
while (rs.next()) {
Book b = new Book();
b.setBid(rs.getInt("bid"));
b.setBname(rs.getString("bname"));
b.setPrice(rs.getFloat("price"));
list.add(b);
}
通过使用basedao将其封装起来,在使用泛型,反射来调用实体,来替换while包裹的那一段代码
hile (rs.next()) {
// 通过泛型来代替 Book b = new Book();
T t = (T) clz.newInstance();
Field[] fields = clz.getDeclaredFields();
for (Field f : fields) {
f.setAccessible(true);
// System.out.println(f.getName());
f.set(t, rs.getObject(f.getName()));
list.add(t);
}
最后通过将那些重复的代码,过程进行合并,从而减少代码量
四.Juint使用
1.为什么要使用.Juint
以下是使用JUnit的好处:
1. 自动化测试
使用JUnit自动化测试的好处是可以节省大量的时间和精力,同时可以保证测试正常,减少手工测试产生的错误和疏漏。
2. 易于维护
使用JUnit测试代码可以使代码更易于维护。单元测试代码类似于使用注释和文档,为代码提供说明和提示。因此,单元测试代码使得代码更易于理解和修改,减少引入潜在错误的风险。
3. 及时反馈
使用JUnit测试代码可以及时反馈代码更改可能带来的影响和错误,这样有利于在代码构建周期早期发现并修复问题。JUnit测试框架总是能够迅速地指出程序的问题所在,这其中可以包括难以重现的问题、处理边角情况的错误以及健壮性方面的缺陷。
4. 持续集成
JUnit在持续集成流程中发挥了很大的作用。持续集成是一种软件开发流程,在这个过程中,会自动化执行不同的测试,因此,JUnit是持续集成流程的重要组成部分。
5. 可靠性和稳定性
代码的质量和可靠性至关重要,JUnit可以帮助我们验证自己的代码功能,并使其具有更高的可靠性和稳定性。始终检查和验证代码的行为,可确保开发人员不会疏忽或忽略任何关键的或边缘情况,提供了一种稳定和可靠的实现方式。
2.在企业中.Juint有什么用
在企业中,JUnit具有以下用途:
1. 保证代码质量
在企业级应用中,代码的质量至关重要。JUnit提供了一种简单、快速、可重复的方式来检查代码的行为和逻辑。通过运行自动化的JUnit测试套件,企业可以确保代码始终具有良好的质量。
2. 检查代码更改
在企业中,任何一次代码更改都有可能引入新的错误或破坏代码的功能性。JUnit自动化测试可以检测出这些错误并及时修复,这有助于保持代码的稳定性和质量。
3. 方便持续集成
在企业中,持续集成是一种流行的开发方式。JUnit测试套件可以与持续集成工具集成,例如Jenkins,以确保每次提交都会运行测试,并在出现错误时立即发布警告。
4. 提高代码可维护性
在企业中的长期运维中,代码必须具有良好的可维护性。JUnit测试使得代码更容易理解和维护,因为它可以提示代码的问题所在,从而更容易识别和修复代码的缺陷。
5. 降低错误和缺陷
JUnit是一种强大的测试工具,在应用中广泛使用。使用JUnit测试你的代码可以降低新错误的出现几率,通过检测错误,他可以帮助测试人员或开发人员更加容易地了解错误的来源和出现方式,从而提高代码质量和产品可靠性。
3.使用操作
1.选择项目,build path然后直接点下去
2.点击右侧的 add libary
3.选择,Junit ,next,finish
4输出@Test 就可以
为什么要使用?
可以同时测试多个方法,节省效率
@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 b : list) { System.out.println(b); } } @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 b : list) { System.out.println(b); } }
五.分页实际效果实现
1.sql语句编写
1.1在最开始的sql语句
public List<Book> list(Book bk, PageBean pageBean) throws Exception { String sql = "select *from t_mvc_book where 1=1"; String bname = bk.getBname(); if (StringUtils.isNotBlank(bname)) { sql += " and bname like '%" + bname + "%' "; } return super.executeQuery(sql, Book.class, pageBean); }
1.2拼接的sql语句
在basedao封装的通用查询的基础上进行拼接,然后在进行重现方法。
在进行拼接时判断是否需要拼接,和条数
public List<T> executeQuery(String sql, Class clz, PageBean pageBean) throws Exception { List<T> list = new ArrayList<T>(); Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; if (pageBean != null && pageBean.isPagination()) { String countSql = getCountSql(sql); conn = DBAccess.getConnection(); ps = conn.prepareStatement(countSql); rs = ps.executeQuery(countSql); if (rs.next()) { pageBean.setTotal(rs.getObject("n").toString()); } String pageSql = getPageSql(sql, pageBean); conn = DBAccess.getConnection(); ps = conn.prepareStatement(pageSql); rs = ps.executeQuery(pageSql); } else { conn = DBAccess.getConnection(); ps = conn.prepareStatement(sql); rs = ps.executeQuery(sql); } while (rs.next()) { // 通过泛型来代替 Book b = new Book(); T t = (T) clz.newInstance(); Field[] fields = clz.getDeclaredFields(); for (Field f : fields) { f.setAccessible(true); // System.out.println(f.getName()); f.set(t, rs.getObject(f.getName())); list.add(t); } } return list; }
/** * sql bookdao的sql 最终sql * * @param sql * @param pageBean * @return */ private String getPageSql(String sql, PageBean pageBean) { return sql + " LIMIT " + pageBean.getStartIndex() + "," + pageBean.getRows(); } /** * 查询 总记录数 * * @param sql * @return */ private String getCountSql(String sql) { return "SELECT COUNT(1) as n from (" + sql + ") t "; }
1.3得到完整的效果
public List<Book> list(Book bk, PageBean pageBean) throws Exception { String sql = "select *from t_mvc_book where 1=1"; String bname = bk.getBname(); if (StringUtils.isNotBlank(bname)) { sql += " and bname like '%" + bname + "%' "; } return super.executeQuery(sql, Book.class, pageBean); }
2.MySQL中 limit使用
limit(0,10) 作用: 其始下标 ,显示页数
SELECT *FROM t_mvc_book WHERE bname LIKE '%圣墟%' LIMIT 0,10 SELECT *FROM t_mvc_book WHERE bname LIKE '%圣墟%' LIMIT 10,10
3.所有你学废了嘛?