标签:boolean 利用 加载 auto sql sys 数据库名 rom oracl
目的:作用通用的分页查询方法
它主要实现的就是通用,将普通查询方法进行反射优化,转变成一个可以被所有实体类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页面通用分页。谢谢观看!!!
标签:boolean 利用 加载 auto sql sys 数据库名 rom oracl
原文地址:https://www.cnblogs.com/ly-0919/p/11058942.html