通用分页后台显示

Posted ly-0919

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了通用分页后台显示相关的知识,希望对你有一定的参考价值。

通用分页

目的:作用通用的分页查询方法

     它主要实现的就是通用,将普通查询方法进行反射优化,转变成一个可以被所有实体类dao层所继承的通用查询方法。

 

实例一

普通分页:

首先我们写一个普通的分页方法,然后再将其进行反射优化,之后就可以看出通用分页的优势了,

1、连接(关闭数据库),使用的是mysql数据库

package com.yuan.util;

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.jdbc.Driver".equals(driver);
    

    public static void main(String[] args) 
        Connection conn = DBAccess.getConnection();
        DBAccess.close(conn);
        System.out.println("isOracle:" + isOracle());
        System.out.println("isSQLServer:" + isSQLServer());
        System.out.println("isMysql:" + isMysql());
        System.out.println("数据库连接(关闭)成功");
    

上面是连接的方法,用到了一个帮助类config.properties,

#mysql5
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/*1?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT
user=*2
pwd=*3

url 里面的*1代表的是你要用到的数据库名称,下面*2和*3分别代表的是连接数据库时用到的用户名和密码。

 2、分页工具实体类 PageBean

   分页三要素
   page        页码        视图层传递过来
   rows        页大小      视图层传递过来
   total       总记录数    后台查出来

package com.yuan.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 + "]";
    

 

3、查询的实体类信息

package com.yuan.entity;

public class Book 
    private int bid;
    private String bname;
    private float 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;
    

    public Book(int bid, String bname, float price) 
        super();
        this.bid = bid;
        this.bname = bname;
        this.price = price;
    

    public Book() 
        super();
        // TODO Auto-generated constructor stub
    

    @Override
    public String toString() 
        return "Book [bid=" + bid + ", bname=" + bname + ", price=" + price + "]";
    

    
    

因为写的是后台显示的代码,所以没有jsp页面代码,就直接在dao层方法里输出了。

4、dao方法

package com.yuan.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 com.yuan.entity.Book;
import com.yuan.util.DBAccess;
import com.yuan.util.PageBean;
import com.yuan.util.StringUtils;



public class BookDao 

    /**
     * 
     * @param book   封装jsp传递过来的查询参数
     * @param pageBean  决定dao层的list调用时是否分页
     * @return
     */
    
    public List<Book> list(Book book,PageBean pageBean)throws SQLException 
        String sql= "SELECT * FROM t_mvc_book WHERE TRUE";
        String bname= book.getBname();
        if(StringUtils.isNotBlank(bname)) 
            sql+=" AND bname LIKE ‘%"+bname+"%‘";
        
        Connection con = DBAccess.getConnection();
        PreparedStatement ps = con.prepareStatement(sql);
        ResultSet rs = ps.executeQuery();
        List<Book> list= new ArrayList<>();
        while(rs.next()) 
            list.add(new Book(rs.getInt("bid"), rs.getString("bname"), rs.getFloat("price")));
        
        DBAccess.close(con, ps, rs);
        return list;
        
    
    
    public static void main(String[] args) throws Exception 
        BookDao b=new BookDao();
        Book book=new Book();
        List<Book> list = b.list(book, null);
        for (Book books : list) 
            System.out.println(books);
        
    
    

数据库数据信息:

技术图片

输出结果:

Book [bid=11, bname=圣墟第11章, price=11.0]
Book [bid=12, bname=圣墟第12章, price=12.0]
Book [bid=16, bname=圣墟第16章, price=16.0]
Book [bid=18, bname=圣墟第18章, price=18.0]
Book [bid=19, bname=圣墟第19章, price=19.0]
Book [bid=20, bname=圣墟第20章, price=20.0]
Book [bid=21, bname=圣墟第21章, price=21.0]
Book [bid=22, bname=圣墟第22章, price=22.0]
Book [bid=24, bname=圣墟第24章, price=24.0]
Book [bid=26, bname=圣墟第26章, price=26.0]
Book [bid=27, bname=圣墟第27章, price=27.0]
Book [bid=28, bname=圣墟第28章, price=28.0]

  普通的分页一个只可用于一个实体类,有多个实体类需要实现分页的话上面的代码就需要多次,非常的需要时间。

下面是一个通用分页,一次代码可以实现多个实体类的分页功能。

 实列二

通用分页:

 

除了下面的几个类其他实体类跟上面一样的

1、优化后的dao层

package com.yuan.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 com.yuan.entity.Book;
import com.yuan.util.BaseDao;
import com.yuan.util.DBAccess;
import com.yuan.util.PageBean;
import com.yuan.util.StringUtils;



public class BookDao extends BaseDao<Book> 

    /**
     * 
     * @param book   封装jsp传递过来的查询参数
     * @param pageBean  决定dao层的list调用时是否分页
     * @return
     * @throws IllegalAccessException 
     * @throws InstantiationException 
     */
    
    public List<Book> list(Book book,PageBean pageBean)throws SQLException, InstantiationException, IllegalAccessException 
        String sql= "SELECT * FROM t_mvc_book";
        String bname= book.getBname();
        if(StringUtils.isNotBlank(bname)) 
            sql+=" WHERE bname LIKE ‘%"+bname+"%‘";
        
        
        return super.executeQuery(sql, Book.class, pageBean);
        
    
    
    public static void main(String[] args) throws Exception 
        BookDao b=new BookDao();
        Book book=new Book();
        book.setBname("圣墟");
        PageBean bean = new PageBean();
        bean.setPage(2);
        List<Book> list = b.list(book, bean);
        for (Book books : list) 
            System.out.println(books);
        
    
    

 

dao方法调用了一个泛型类,

2、BaseDao<T>信息如下:

package com.yuan.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.sun.corba.se.spi.legacy.connection.GetEndPointInfoAgainException;
import com.yuan.dao.BookDao;
import com.yuan.entity.Book;

/**
 * 代表你要对哪个实体类对应的表进行分页查询
 * @author **
 *
 * @param <T>
 */
public class BaseDao<T> 

    /**
     * 
     * @param sql  查询不同的实体类,对应的sql语句不同所以需要传递
     * @param clz  生产出不同的实体类对应的实列,然后装进list容器中返回
     * @param pageBean  决定是否分页
     * @return
     * @throws SQLException
     * @throws IllegalAccessException 
     * @throws InstantiationException 
     */
    public List<T> executeQuery(String sql,Class clz,PageBean pageBean)throws SQLException, InstantiationException, IllegalAccessException 
        Connection con = DBAccess.getConnection();
        PreparedStatement ps =null;
        ResultSet rs = null;
        
        if(pageBean!=null && pageBean.isPagination()) 
            //需要分页
            //计算总记录数
            String consql= getCountsql(sql);
            ps = con.prepareStatement(consql);
            rs=ps.executeQuery();
            if(rs.next()) 
                pageBean.setTotal(rs.getLong(1)+"");
            
            //查询出符合条件的结果集
            String pagesql = getPageSql(sql,pageBean);
            ps = con.prepareStatement(pagesql);
            rs = ps.executeQuery();
            
            
        else 
            ps = con.prepareStatement(sql);
            rs = ps.executeQuery();
        
        List<T> list= new ArrayList<>();
        T t;
        while(rs.next()) 
            /**
             *1、实例化一个book对象(该对象为空)
             *2、取book的所有属性,然后给器赋值
             *  2.1获取所有属性对象
             *  2.2给属性赋值
             *3、赋值之后的book对象装进list容器中
             */
//            list.add(new Book(rs.getInt("bid"), rs.getString("bname"), rs.getFloat("price")));
            
            t =(T) clz.newInstance();
            Field[] fields = clz.getDeclaredFields();
            for (Field field : fields) 
                field.setAccessible(true);
                field.set(t, rs.getObject(field.getName()));
            
            list.add(t);
        
        DBAccess.close(con, ps, rs);
        return list;
        
    
    
    /**
     * 利用原生sql拼接出符合条件的结果集的查询sql
     * @param sql
     * @param pageBean
     * @return
     */
    private String getPageSql(String sql, PageBean pageBean) 
        // TODO Auto-generated method stub
        return sql+" LIMIT "+pageBean.getStartIndex()+","+pageBean.getRows()+"";
    

    /**
     * 
     * @param sql
     * @return
     */
    private String getCountsql(String sql) 
        
        return "SELECT COUNT(1) FROM ("+sql+")t";
    
    
    

 

 查询出结果跟上面是一样的

Book [bid=11, bname=圣墟第11章, price=11.0]
Book [bid=12, bname=圣墟第12章, price=12.0]
Book [bid=16, bname=圣墟第16章, price=16.0]
Book [bid=18, bname=圣墟第18章, price=18.0]
Book [bid=19, bname=圣墟第19章, price=19.0]
Book [bid=20, bname=圣墟第20章, price=20.0]
Book [bid=21, bname=圣墟第21章, price=21.0]
Book [bid=22, bname=圣墟第22章, price=22.0]
Book [bid=24, bname=圣墟第24章, price=24.0]
Book [bid=26, bname=圣墟第26章, price=26.0]
Book [bid=27, bname=圣墟第27章, price=27.0]
Book [bid=28, bname=圣墟第28章, price=28.0]

 注:实现另一个实体类的分页功能只需要将dao方法的一些跟数据库相关的信息修改一下就可以了,还需要注意的就是你实体类的属性在dao层从数据库获取时需要修改。

使用通用分页代码实现另一个实体类的分页功能。

1、dao层 BlogDao    (dao层继承了BaseDao)

package com.yuan.dao;

import java.sql.SQLException;
import java.util.List;

import com.yuan.entity.Bookxyj;
import com.yuan.entity.Book;
import com.yuan.util.BaseDao;
import com.yuan.util.PageBean;
import com.yuan.util.StringUtils;

public class BlogDao extends BaseDao<Bookxyj> 

    public List<Bookxyj> list(Bookxyj book,PageBean pageBean)throws SQLException, InstantiationException, IllegalAccessException 
        String sql= "SELECT * FROM book WHERE TRUE";
        String bname= book.getBookName();
        if(StringUtils.isNotBlank(bname)) 
            sql+=" AND WHERE bookName LIKE ‘%"+bname+"%‘";
        
        
        return super.executeQuery(sql, Bookxyj.class, pageBean);
        
    
    
    public static void main(String[] args) 
        BlogDao blogDao = new BlogDao();
        PageBean pageBean = new PageBean();
        Bookxyj book = new Bookxyj();
        try 
            List<Bookxyj> z = blogDao.list(book, pageBean);
            for (Bookxyj b : z) 
                System.out.println(b);
            
         catch (InstantiationException | IllegalAccessException | SQLException e) 
            // TODO Auto-generated catch block
            e.printStackTrace();
        
    
    
    

 

2、实体类 (BookXyj)

package com.yuan.entity;

public class BookXyj 

    
    private int id;
    private String bookName;
    public int getId() 
        return id;
    
    public void setId(int id) 
        this.id = id;
    
    public String getBookName() 
        return bookName;
    
    public void setBookName(String bookName) 
        this.bookName = bookName;
    
    @Override
    public String toString() 
        return "Blog [id=" + id + ", title=" + bookName + "]";
    
    
    
    
    

 

 3、数据库数据信息

技术图片

4、查询结果

Blog [id=1, title=西游记1回]
Blog [id=2, title=西游记2回]
Blog [id=3, title=西游记3回]
Blog [id=4, title=西游记4回]
Blog [id=5, title=西游记5回]
Blog [id=6, title=西游记6回]
Blog [id=7, title=西游记7回]
Blog [id=8, title=西游记8回]
Blog [id=9, title=西游记9回]
Blog [id=10, title=西游记10回]

 

 

总结:

如果只对一个实体类实现分页功能的活普通分页占据代码量少的优势,

但如果是实现多个实体类分页功能的话普通分页就没有那个优势了,反而会很浪费时间,而通用分页只需要在dao方法修改部分代码就可以了。

 

 

关注下次实现JSP页面通用分页。谢谢观看!!!

以上是关于通用分页后台显示的主要内容,如果未能解决你的问题,请参考以下文章

根据后台返回的数据写一个分页,通用

通用分页

通用分页

前端Vue+Element UI案例:通用后台管理系统-用户管理:Table表格增删查改Pagination分页搜索框

PHP通用分页类

.net通用CMS快速开发框架——问题:Dapper通用的多表联合分页查询怎么破?