三. 反射完成通用查询功能
使用反射实现通用查询功能是在运行时通过分析类的结构来构造查询的一种技术。通过反射,可以获取类的字段、方法、注解等信息,并根据这些信息动态构建查询条件、执行查询操作。
下面是一个简单示例,展示如何使用反射实现通用查询功能:
public class BookDao extends BaseDao<Book>{ public List<Book> list1(Book book, PageBean pageBean) throws Exception { // 实例化 List<Book> list = new ArrayList<Book>(); // 拿到连接对象 Connection conn = DBAccess.getConnection(); // 编写sql语句 String sql = "select * from t_mvc_book where 1=1"; String bname = book.getBname(); // 判断字符串是不是空 if (StringUtils.isNotBlank(bname)) { sql += "and bname like '%" + bname + "%' "; // 拿到预定义对象 PreparedStatement ps = conn.prepareStatement(sql); // 拿到结果集 ResultSet rs = ps.executeQuery(); // 创建表对应的实体类对象 // 将查询出来的结果集添加到实例化对象的属性中 // 已经被对象填充的实体对象加入到集合中 while (rs.next()) { list.add(new Book(rs.getInt("bid"), rs.getString("bname"), rs.getFloat("price"))); } } return list; } public List<Book> list2(Book book, PageBean pageBean) throws Exception { // 编写sql语句 String sql = "select * from t_mvc_book where 1=1"; String bname = book.getBname(); // 判断字符串是不是空 if (StringUtils.isNotBlank(bname)) { sql += "and bname like '%" + bname + "%' "; } return super.executeQuery(sql, Book.class, pageBean); } public static void main(String[] args) throws Exception { BookDao bookDao = new BookDao(); Book book = new Book(); PageBean pageBean = new PageBean(); List<Book> list = bookDao.list1(book, pageBean); for (Book b : list) { System.out.println(b); } } }
效果图:
要注意的是,这只是一个简单示例,实际应用中,可能需要根据具体的查询需求和数据访问框架进行更复杂的构建和操作。同时,使用反射的效率较低,因此在性能要求较高的场景中,应慎重使用。
四.junit单元测试
4.1.什么是junit
JUnit是一个用于Java编程语言的单元测试框架。单元测试是一种软件测试方法,旨在验证应用程序中最小可测试单元(通常是单个方法)的正确性。JUnit提供了一些工具和注解,使得编写和执行单元测试变得更加容易和自动化。
4.2.JUnit的特点和优势包括:
- 简单易用:JUnit提供了一组易于理解和使用的API,使得编写单元测试变得简单和直观。
- 自动化执行:JUnit测试用例可以被自动执行,无需人工干预,从而提高了测试的效率和准确性。
- 快速反馈:通过JUnit可以快速运行单元测试,并及时获得测试结果和报告,帮助开发人员快速发现和调试代码中的问题。
- 可重复性:JUnit测试用例具有高度的可重复性,测试结果在不同的环境和条件下都应该保持一致。
4.3常见的JUnit注解包括:
- @Test:用于标记测试用例方法。
- @Before:在每个测试方法之前执行,用于初始化测试数据。
- @After:在每个测试方法之后执行,用于清理测试数据。
- @BeforeClass:在类中的所有测试方法之前执行,通常用于准备资源或加载数据。
- @AfterClass:在类中的所有测试方法之后执行,通常用于释放资源或清理数据。
JUnit还提供了一些常用的断言方法,用于验证测试结果的正确性,例如assertEquals、assertTrue、assertFalse等。
以下是一个JUnit测试用例示例:
@Test public void text1() throws Exception { System.out.println("text1....."); BookDao bookDao = new BookDao(); Book book = new Book(); PageBean pageBean = new PageBean(); List<Book> list = bookDao.list1(book, pageBean); for (Book b : list) { System.out.println(b); } }
这里需要注意的是:如果我们在写代码时@Test快捷键出不来的话,就需要进行配置。
配置如下:
首先点击你写的项目如图:
再点击Libraries,再点击如图:
到这就结束了,恭喜你配置成功
通过JUnit可以对应用程序的各个单元进行快速且自动化的测试,并能够提供可靠的测试结果和报告。这种单元测试方法有助于发现和解决代码中的问题,提高软件质量和开发效率。
4.4.通用查询带分页
通用查询带分页是指在数据查询操作中,通过一种通用的方法实现查询结果的分页显示。这种方法可以用于各种查询场景,无论是关系型数据库、NoSQL数据库还是其他数据存储方式。
通用查询带分页的实现通常包含以下几个关键步骤:
- 构建查询条件:根据查询需求,构建查询条件,可以根据实体类的属性进行查询条件的设定。
- 执行查询:根据设定的查询条件,执行相应的查询操作,获取满足条件的查询结果。
- 分页处理:根据传入的页码和每页记录数,计算出查询结果的起始索引和结束索引,然后截取查询结果中的指定范围的数据作为分页结果。
- 返回分页结果:将分页结果返回给调用者,一般以列表形式或其他适当的数据结构进行返回。
在实际实现中,可以使用各种数据库访问框架或持久化工具来执行查询操作。例如,使用JDBC执行SQL查询,使用ORM框架(如Hibernate或MyBatis)进行对象关系映射查询等。
以下是一个通用查询带分页的示例代码:
BaseDao类:
package com.junlinyi.dao; 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; import com.junlinyi.util.DBAccess; import com.junlinyi.util.PageBean; public class BaseDao<T> { /** * * @param sql * @param cls Book.class * @param pageBean * @return * @throws Exception */ public List<T> executeQuery(String sql,Class cls, 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 = getCounSQL(sql); conn = DBAccess.getConnection(); ps = conn.prepareStatement(countSQL); rs = ps.executeQuery(); if(rs.next()) { pageBean.setTotal(rs.getObject("n").toString()); } String pageSQL = getPageSQL(sql,pageBean); conn = DBAccess.getConnection(); ps = conn.prepareStatement(pageSQL); rs = ps.executeQuery(); }else { conn = DBAccess.getConnection(); ps = conn.prepareStatement(sql); rs = ps.executeQuery(); } // 创建表对应的实体类对象 // 将查询出来的结果集添加到实例化对象的属性中 // 已经被对象填充的实体对象加入到集合中 while (rs.next()) { T t=(T) cls.newInstance(); // 拿到cls对应的所有属性 Field[] fields = cls.getDeclaredFields(); for (Field f : fields) { f.setAccessible(true); // System.out.println(f.getName()); f.set(t,rs.getObject(f.getName())); } // list.add(new Book(rs.getInt("bid"), rs.getString("bname"), rs.getFloat("price"))); list.add(t); } return list; } /** * 拼接出最终展示出的数据sql * @param sql 原生SQL * @param pageBean * @return */ private String getPageSQL(String sql, PageBean pageBean) { return sql+"limit "+pageBean.getStartIndex()+","+pageBean.getRows(); } /** * 拼接出查询符合条件的总及记录数 * @param sql * @return */ private String getCounSQL(String sql) { return "SELECT count(1) as n from ("+sql+") t"; } }
Dao类 :
@Test public void test3() throws Exception { System.out.println("test3..."); BookDao bookDao = new BookDao(); Book book = new Book(); book.setBname("圣墟"); PageBean pageBean = new PageBean(); pageBean.setPage(2); List<Book> list = bookDao.list2(book, pageBean); for (Book b : list) { System.out.println(b); }