前言
在一个项目中总会用到查询方法去到数据库里进行查找,这个时候,也许返回一个集合,那么在什么地方需要用到查询方法嘛,
-
第一
- 在查询一个主要列表并展示的时候(需要分页) 第二
- 在从数据库里查询一些选项并放入到下拉框的时候 (不需要分页)
欧克,那么我们能写出一个既可以用到分页,也可以不用分页的通用方法吗?
一般的查询方法
无分页
一般来说的话写的代码为普通查询方法:
如我待会写的代码
我会稍微讲一些难懂的地方:
if(StringUtils.isNotBlank(t.getTname())) {//可以进行模糊查询 ********重点的StringUtils.
sql+=" and tname like '%"+t.getTname()+"%' ";
}
这个是可以使得可以进行模糊查询
而StringUtils是一个类 ,isNotBlank是类部的方法
用来判断t是否为空,如果不为空,就将其进行模糊查
其他的都没什么区别
对了,有个地方:
lt.add(new teacher(rs.getInt("tid"), rs.getString("tname")));//加入到集合中
有些人之前是用rs.getInt(1) 之类的数字的,
其实你如果知道名字,也可以填String类型
通用的查询方法
无分页
要写一个通用的查询方法,我们就要写个泛型类来作为父类。
public class TeacherDao extends SelectBeanDao<teacher>{
Connection con = null;
PreparedStatement pst = null;
ResultSet rs = null;
public List<teacher> list(teacher t,PageBean page) throws SQLException{
List<teacher> lt = new ArrayList<>(); //创建个list集合
String sql = "select * from tb_teacher where 1=1 ";
if(StringUtils.isNotBlank(t.getTname())) {//可以进行模糊查询 ********重点的StringUtils.
sql+=" and tname like '%"+t.getTname()+"%' ";
}
try {
con = DBAccess.getConnection();//连接三部曲
pst = con.prepareStatement(sql);//连接三部曲
rs = pst.executeQuery();//连接三部曲
while (rs.next()) {
lt.add(new teacher(rs.getInt("tid"), rs.getString("tname")));//加入到集合中
}
} finally {
DBAccess.close(con, pst, rs);
}
return lt;
}
比如这个SelectBeanDao是我们写的一个专门用来进行查询的方法。
里面的基础不变,只不过在该给什么赋值的时候有了困惑。
看里面的参数:Class clz
对,我们可以用到反射的方法,来给传过来的
Field[] fields = clz.getDeclaredFields();//获取这个类里的所有属性
反射里有这个方法
不过多的去讲
那么一个通用方法就这样做好了
public List<teacher> list(teacher t,PageBean page) throws SQLException, InstantiationException, IllegalAccessException{
String sql = "select * from tb_teacher where 1 = 1";
if(StringUtils.isNotBlank(t.getTname())) {
sql+=" and tname like '%"+t.getTname()+"%' ";
}
return super.executeQuery(sql, teacher.class, page);//要传的东西:sql语句 | 要查询的类 | page类也就是要不要分页
}
调用就简单了,写好sql语句传过去就行。
有分页
这个也是需要用到一个泛型的父类方法的
public List<T> executeQuery(String sql ,Class clz ,PageBean page ) throws SQLException, InstantiationException, IllegalAccessException{
List<T> lt = new ArrayList<>();
try {
con = DBAccess.getConnection(); //连接三部曲
if(page!=null&&page.isPagination()) {//要进行分页的进这里
String countPage = countPage(sql);//获取这个类在数据库的总行数
pst = con.prepareStatement(countPage);
rs = pst.executeQuery();
if(rs.next()) {
page.setTotal(rs.getLong(1)+"");
}
String getPage = getPage(sql,page);//获取这个页面的页数
pst = con.prepareStatement(getPage);
rs = pst.executeQuery();
}
else {
pst = con.prepareStatement(sql);//连接三部曲
rs = pst.executeQuery(); //连接三部曲
}
while (rs.next()) {
T t = (T) clz.newInstance();//将传过来的class文件实列化,类型为实现本类的T参数
Field[] fields = clz.getDeclaredFields();//获取这个类里的所有属性
for (Field field : fields) { //遍历
field.setAccessible(true); //打开权限
field.set(t, rs.getObject(field.getName()));
}
lt.add(t);//加入到集合内部
}
} finally {
DBAccess.close(con, pst, rs);
}
return lt;
}
东西可能有点多可仔细看还是可以理解的
看这些代码:
if(page!=null&&page.isPagination()) {//要进行分页的进这里
String countPage = countPage(sql);//获取这个类在数据库的总行数
pst = con.prepareStatement(countPage);
rs = pst.executeQuery();
if(rs.next()) {
page.setTotal(rs.getLong(1)+"");
}
String getPage = getPage(sql,page);//获取这个页面的页数
pst = con.prepareStatement(getPage);
rs = pst.executeQuery();
}
else {
pst = con.prepareStatement(sql);//连接三部曲
rs = pst.executeQuery(); //连接三部曲
}
这个就是判断是否要分页,如果要分页要干些什么。
里面的getPage(sql,page) 和 countPage方法
就是一个sql语句的拼接而已。
看这个;
运用的话
public List<teacher> list(teacher t,PageBean page) throws SQLException, InstantiationException, IllegalAccessException{
String sql = "select * from tb_teacher where 1 = 1";
if(StringUtils.isNotBlank(t.getTname())) {
sql+=" and tname like '%"+t.getTname()+"%' ";
}
return super.executeQuery(sql, teacher.class, page);//要传的东西:sql语句 | 要查询的类 | page类也就是要不要分页
}
public static void main(String[] args) throws SQLException, InstantiationException, IllegalAccessException {
teacher t = new teacher();
TeacherDao td = new TeacherDao();
PageBean page = new PageBean();
page.setPagination(true);
List<teacher> list = td.list(t, page);
for (teacher tc : list) {
System.out.println(tc.toString());
}
}
结果:
junit测试分页代码
junit的配置
了解: JUnit是一个Java语言的单元测试框架。它由Kent Beck和Erich Gamma建立,逐渐成为源于Kent Beck的sUnit的xUnit家族中最为成功的一个JUnit有它自己的JUnit扩展生态圈。多数Java的开发环境都已经集成了JUnit作为单元测试的工具。
如何使用:
通常在用eclipse开发的话都有junit的包的所以只需要去导入就行
选中junit里面的build path
选中Add Library
点击next ,选择junit4就行
如果这有了就行了
用junit来测试
在上面已经写好了分页代码,在这个时候我们就要用到Junit来进行测试;
原来用来main的方法是这样的
public static void main(String[] args) throws SQLException, InstantiationException, IllegalAccessException {
TeacherDao td = new TeacherDao();//实列化方法类
teacher t = new teacher();
PageBean page = new PageBean();
List<teacher> list = td.list(t, page);//我们要调用的方法
for (teacher tc : list) {
System.out.println(tc.toString());
}
这个时候创建一个teacherTest来专门进行测试;
当然开头要有个注解:
-
@Test: 测试方法
a)(expected=XXException.class)如果程序的异常和XXException.class一样,则测试通过
b)(timeout=100)如果程序的执行能在100毫秒之内完成,则测试通过 -
@Ignore: 被忽略的测试方法:加上之后,暂时不运行此段代码
-
@Before: 每一个测试方法之前运行
-
@After: 每一个测试方法之后运行
-
@BeforeClass: 方法必须必须要是静态方法(static 声明),所有测试开始之前运行,注意区分before,是所有测试方法
-
@AfterClass: 方法必须要是静态方法(static 声明),所有测试结束之后运行,注意区分 @After
选择运行:
如果为绿色则没问题;
欧克,分页代码测试没问题;
总结
在理解了这方面的知识后,是不是感觉离源码越来越近了,对,这个自作通用方法的案例其实也就是简单的源码运用
方法的灵活运用,反射的动态调用。
Thanks♪(・ω・)ノ希望对大家有所帮助