目录
通用分页的重点在于通用,今天我来给大家分享一下我对通用的理解,分页分前台和后台代码,今天带来的是后台代码
一、通用类BaseDao
1.获取全部的方法 executeQuery
在这个方法中定义了三个参数,分别是拿到原始sql语句和封装的分页类pageBean以及一个处理结果集的回掉函数接口callBack
在判断是否要分页,如果要分页的话就调用该类获取总记录数CountSQL和每页多少条数据的方法PageSQL,不分页就直接执行原有sql语句
public List<T> executeQuery( String sql,PageBean pagebean,CallBack<T> callBack) throws Exception{
/**
* 1.拿到数据库连接
* 2.拿到preparstatement
* 3.执行sql语句
*/
Connection con = DBAccess.getConnection();//重复代码1
PreparedStatement ps = con.prepareStatement(sql);//重复代码2
ResultSet rs = ps.executeQuery();//重复代码3
if(pagebean!=null&&pagebean.isPagination()) {
String countsql = getCountsql(sql);
con = DBAccess.getConnection();
ps = con.prepareStatement(countsql);
rs = ps.executeQuery();
if(rs.next()) {
pagebean.setTotal(rs.getString("n"));
}
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();
}
//查询不同的表必然要处理不同的结果集
return callBack.foreach(rs);
}
之所以通用:
集合里将具体的实体类替换为字母T就说明这里是通用的能放任何我们需要的实体类,其次返回的是回掉函数接口类Collback处理结果集的方法,谁调用这个接口类就谁处理结果集
2、获取总记录数CountSQL
这是一个通用的获取数据库中总数据的方法
/**
* 拼装符合条件总记录数的Sql
* @param sql
* @return
*/
private String getCountsql(String sql) {
// TODO Auto-generated method stub
return "select count(1) as n from ("+sql+") t";
}
3、每页多少条数据的方法PageSQL
得到原有的sql语句再拼接分页中获取下标和总行数的方法就得到了一个通用的第几页展示数据的方法
/**
* 拼接第N页数据的sql
* @param sql
* @param pagebean
* @return
*/
private String getpageSql(String sql, PageBean pagebean) {
return sql +"limit"+pagebean.getStartIndex()+","+pagebean.getRows();
}
二、具体类
以书籍类为例子,我们在书籍Dao里继承BaseDao,我们只需要在返回时返回BaseDao中获取全部的方法 executeQuery,同时我们得到了三个参数sql,pagebean,以及CallBack,我们只需要将CallBack替换为书籍的结果集,再遍历书籍结果集就可以了
public List<Book> list2(Book book,PageBean pagebean) throws Exception{
List<Book> ls = new ArrayList<Book>();
/**
* 1.拿到数据库连接
* 2.拿到preparstatement
* 3.执行sql语句
*/
String sql = "select * from t_mvc_book where 1=1";
String bname = book.getBname();
if(StringUtils.isNotBlank(bname)) {
sql +="and bname like'%"+bname+"%'";
}
int bid = book.getBid();
if(bid!=0) {
sql +=" and bid = " +bid;
}
return super.executeQuery(sql, pagebean, rs->{
List<Book> list = new ArrayList<>();
try {
while(rs.next()) {
ls.add(new Book(rs.getInt("bid"), rs.getString("bname"), rs.getFloat("price")));
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return list;
});
}
接下来我再分享一个不调用通用方法的方法,与我们调用通用方法作比较
public List<Book> list(Book book,PageBean pagebean) throws Exception{
List<Book> ls = new ArrayList<Book>();
/**
* 1.拿到数据库连接
* 2.拿到preparstatement
* 3.执行sql语句
*/
Connection con = DBAccess.getConnection();//重复代码1
String sql = "select * from t_mvc_book where 1=1";
String bname = book.getBname();
if(StringUtils.isNotBlank(bname)) {
sql +="and bname like'%"+bname+"%'";
}
int bid = book.getBid();
if(bid!=0) {
sql +=" and bid = " +bid;
}
PreparedStatement ps = con.prepareStatement(sql);//重复代码2
ResultSet rs = ps.executeQuery();//重复代码3
while(rs.next()) {
ls.add(new Book(rs.getInt("bid"), rs.getString("bname"), rs.getFloat("price")));
}
return ls;
}
肉眼可见里面有大量的重复代码,而我们调用通用方法很大程度上减少了重复代码,提高了我们的开发速度和效率,这就是通用的好处
三、测试
使用的是Junit,它能够根据单个方法进行测试,相对于main方法而言,耦合性降低了
有三个方法,测试前SetUP,测试后TearDown,以及一个我们在里面进行测试的TestList方法
在这里我们只需要实例化实体类和分页类,还可以自己设置页面和总行数,然后在调用我们的方法就可以了,简直太方便啦!里面有三个方法有打注释区分
package com.zjy.dao;
import static org.junit.Assert.*;
import java.util.ArrayList;
import java.util.List;
/**
* junit 能够根据单个方法进行测试
* 相较于main方法而言,耦合性降低了
*
*/
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.zjy.entity.Book;
import com.zjy.util.BaseDao;
import com.zjy.util.PageBean;
public class BookDaoTest {
@Before
public void setUp() throws Exception {
System.out.println("被测试方法执行之前调用");
}
@After
public void tearDown() throws Exception {
System.out.println("被测试方法执行之后调用");
}
/**
* 不使用通用方法也不分页
*/
@Test
public void testList() {
List<Book> list;
try {
list = new BookDao().list(new Book(), null);
for (Book book : list) {
System.out.println(book);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 使用通用方法但不分页
*/
@Test
public void testList2() {
List<Book> list;
try {
list = new BookDao().list2(new Book(), null);
for (Book book : list) {
System.out.println(book);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 使用通用方法并且分页
*/
@Test
public void testList3() {
List<Book> list;
try {
Book b = new Book();
PageBean pageBean = new PageBean();
pageBean.setPage(2);
pageBean.setRows(20);
list = new BookDao().list2(b, pageBean);
for (Book book : list) {
System.out.println(book);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}