Java -- JDBC学习笔记7、DaoUtils
2021/5/5 20:27:15
本文主要是介绍Java -- JDBC学习笔记7、DaoUtils,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
1、为什么要封装Dao层工具类?
在Dao层中,每次对数据库的增、删、改、查操作存在代码冗余,可以将共有代码抽取封装。
2、哪些代码需要封装?
- 在修改、删除、添加等操作方法中,每次都需要获取连接对象、获取PreparedStatement、给占位符赋值,释放连接等等。
- 在查询操作方法中(查询全部和查询所有),也需要获取连接对象,PreparedStatement、ResultSet等对象,还需要循环ResultSet,取值赋值等等。
3、DaoUtils具体实现
- 修改、删除、新增使用一个通用方法来实现。
- 查询单个和查询所有用一个通用方法来实现。
3.1、增删改通用方法commonsUpdate()
方法有两个参数,第一个是sql语句、第二个是参数列表。
- 第二个变量里存放的值是不固定的,因为增删改语句中的参数数量不同,比如:修改需要整张表,删除只需要一个,新增也需要整张表,所以使用Object... args、也就是可变参数。
- 调用者在调用通用函数、要事先将参数列表定义好,每一个值和sql语句中那一个占位符相对应。
/** * 增删改通用方法 * @param sql 增删改sql语句 * @param args 参数列表 * @return 受影响行数 */ public int commonUpdate(String sql, Object... args) { Connection conn = null; PreparedStatement preparedStatement = null; try { conn = DBUtils.getConnection(); preparedStatement = conn.prepareStatement(sql); for (int i = 0; i < args.length; i++) { //第一个参数是设置的值下标,从1开始,第二个是从参数列表中取值的下标,所以从0开始 preparedStatement.setObject(i + 1, args[i]); } int result = preparedStatement.executeUpdate(); return result; } catch (SQLException sqlException) { sqlException.printStackTrace(); } finally { DBUtils.closeDb(null, preparedStatement, null); } return 0; }
- service层调用者、修改数据
public int update(Account account) { String sql = "update Account set pwd=?,balance=?,name=? where id=?"; Object[] arr = {account.getPwd(), account.getBalance(), account.getName(), account.getId()}; return daoUtils.commonUpdate(sql, arr); }
数组里的值和SQL语句中占位符一一对应。
3.2、查询通用方法commonsSelect()
查询通用方法相对比较麻烦,因为查询的是单个、还是多个不知道,取值时候也不清楚是哪张表、表中有哪些字段,取出来后赋值给谁、接收用什么类型接收等等。
- 首先、对于查询多个还是单个,可以使用集合,查询单个、集合中就一条数据,查询多个集合中就多条数据。
- 对于不知道是那张表、有哪些字段。遍历取值赋值给那个实体类,可以新建一个回调函数来赋值。
- 回调函数接收的参数就是在通用方法里传来的ResultSet,取出里边的值,给泛型里的实体类赋值,回调函数里的泛型类型就是调用者接收的类型,也就是某个实体类。这样、在通用方法里每循环一次,就调用一次回调函数,而回调函数里知道是那张表,赋值完成后返回,通用函数里使用泛型类型接收后、再添加到list即可。
- 回调函数要使用面向接口方式、定义接口、针对不同的类、实现接口,传入的泛型类型也是不同的实体类。
3.3、查询通用方法代码实现
- 新建一个泛型接口、RowMapper
public interface RowMapper<T> { public T getRow(ResultSet resultSet); }
- 实现该接口、要遍历那个类、就针对那个类传入对应的泛型类型,比如我这里要遍历Account表、所以:
public class AccountRowMapperImpl implements RowMapper<Account> { @Override public Account getRow(ResultSet resultSet) { Account account = null; try { int id = resultSet.getInt(1); String pwd = resultSet.getString(2); Double balance = resultSet.getDouble(3); String name = resultSet.getString(4); account = new Account(id,pwd,balance,name); return account; } catch (SQLException sqlException) { sqlException.printStackTrace(); } return null; } }
如果是其它表、比如User,那么就再新建一个实现类,泛型参数是User、返回类型也是User。
- 编写通用方法
/** * 查询通用方法 * @param sql 查询sql语句 * @param rowMapper 回调接口、调用者要传入接口实现类 * @param args 参数列表 * @return 返回值(集合) */ public List<T> commomSelect(String sql, RowMapper<T> rowMapper, Object... args) { Connection conn = null; PreparedStatement preparedStatement = null; ResultSet rs = null; List<T> list = new ArrayList<>(); try { conn = DBUtils.getConnection(); preparedStatement = conn.prepareStatement(sql); if (args != null) { for (int i = 0; i < args.length; i++) { preparedStatement.setObject(i + 1, args[i]); } rs = preparedStatement.executeQuery(); while (rs.next()) { T t = rowMapper.getRow(rs);//回调 -->调用者提供的一个封装方法ORM list.add(t); } } } catch (SQLException sqlException) { sqlException.printStackTrace(); } finally { DBUtils.closeDb(null, preparedStatement, rs); } return list; }
- service层调用者、因为这里是查询单个、所以直接list.get(0)即可。
public Account select(int id) { String sql = "select id,pwd,balance,name from Account where id=?"; List<Account> list = daoUtils.commomSelect(sql, new AccountRowMapperImpl(), id); if (!list.isEmpty()) { return list.get(0); } return null; }
概括来讲、增删改比较简单,返回的就只是受影响行数,而查询比较复杂,不知道查询的是那张表、有哪些字段、就更不知道用那个实体类来接收。添加一个回调函数、通过泛型传入相应的实体类,遍历赋值完成后返回给通用方法,通用方法只负责查询和返回,回调函数赋值取值和赋值。
这篇关于Java -- JDBC学习笔记7、DaoUtils的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-07-04TiDB 资源管控的对撞测试以及最佳实践架构
- 2024-07-03万字长文聊聊Web3的组成架构
- 2024-07-02springboot项目无法注册到nacos-icode9专业技术文章分享
- 2024-06-26结对编程到底难不难?答案在这里
- 2024-06-19《2023版Java工程师》课程升级公告
- 2024-06-15matplotlib作图不显示3D图,怎么办?
- 2024-06-1503-Loki 日志监控
- 2024-06-1504-让LLM理解知识 -Prompt
- 2024-06-05做软件测试需要懂代码吗?
- 2024-06-0514-ShardingSphere的分布式主键实现