BaseDao封装JavaWeb的增删改查

目录

什么是BaseDao?

为什么需要BaseDao?

BaseDao的实现逻辑

什么是BaseDao?

Basedao 是一种基于数据访问对象(Data Access Object)模式的设计方法。它是一个用于处理数据库操作的基础类,负责封装数据库访问的底层操作,提供通用的数据库访问方法。

Basedao 主要用于简化数据库操作的代码开发,并提供一致性可维护性。它通常包含有对数据库的增加、删除、修改和查询等操作方法,以及一些基本的事务处理功能。

Basedao 可以通过继承来扩展具体的数据库操作方法,使得在具体的业务实现中可以更加专注于业务逻辑的实现,而不需要关注底层数据库的细节。

通过使用 Basedao,开发人员可以更加高效地进行数据库操作的开发,减少了重复的代码编写,提高了代码的可维护性可读性

为什么需要BaseDao?

BaseDao 的优点包括:

  1. 代码复用(共性抽取):BaseDao 封装了常见的数据库操作方法,可以被不同的业务逻辑类多次调用,避免了重复编写相同的数据库操作代码,提高了代码的复用性。
  2. 提高开发效率:BaseDao 提供了高级的数据库操作方法,开发人员可以直接调用这些方法,减少了重复的开发工作,提高了开发效率。
  3. 降低代码耦合度:BaseDao 封装了底层数据库的细节,通过调用 BaseDao 的方法,业务逻辑类可以和具体的数据库实现解耦,减少了业务逻辑类和数据库之间的直接依赖,提高了代码的可维护性和可扩展性。
  4. 提供事务支持:BaseDao 通常会提供事务处理的功能,可以保证数据库操作的一致性。开发人员可以通过 BaseDao 来处理事务,确保在一次操作中,要么全部成功,要么全部失败,避免了数据不一致的情况。

总的来说,BaseDao 通过封装数据库操作,提供高级的数据库操作方法,降低代码耦合度,提供事务支持等优点,可以提高开发效率,简化数据库操作,提高代码的可维护性和可扩展性。

BaseDao的实现逻辑

简单来说BaseDao就是对数据库底层操作业务进行共性抽取,下面就以学生信息为例~

1、在学生信息管理系统中,不论增删改查还是特殊业务都离不开每次访问数据库的配置驱动以及获取连接关闭连接,所以这两步是必然封装的

/*** 获取数据库连接对象*/
public Connection getConnection() throws Exception {  //获取连接对象方法//加载配置文件Properties properties = new Properties();properties.load(Files.newInputStream(Paths.get("D:\\druid.properties")));//创建一个指定参数的数据库连接池DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);return dataSource.getConnection();  //返回连接对象
}

因为当时博主访问数据库是采用Druid连接池,所以配置驱动就使用配置文件的方式,配置文件( .properties )代码如下:

driverClassName = com.mysql.cj.jdbc.Driver
url = jdbc:mysql://localhost:3306/student?useServerPrepStmts=true
username = root
password = root
initialSize = 10
maxActive = 30
maxWait = 1000

关闭连接方法封装代码如下:

/*** 关闭数据库连接* @param conn 数据库连接* @param stmt PreparedStatement预处理对象* @param rs 结果集*/
public void closeAll(Connection conn, PreparedStatement stmt, ResultSet rs) {  //关闭连接方法// 若结果集对象(RresuleSet)不为空,则关闭if (rs != null) {try {rs.close();} catch (Exception e) {e.printStackTrace();}}// 若预处理对象(PreparedStatement)不为空,则关闭if (stmt != null) {try {stmt.close();} catch (Exception e) {e.printStackTrace();}}// 若数据库连接对象(Connection)不为空,则关闭if (conn != null) {try {conn.close();} catch (Exception e) {e.printStackTrace();}}}

2、通过第一步的调用能够返回一个连接对象,那么接下来就可以进行基本的增删改查操作, 增删改都属于对数据做更新,所以先做增删改

/*** 增、删、改的操作* @param preparedSql 预编译的 SQL 语句* @param param 参数的字符串数组* @return 影响的行数*/
public int updateRow (String preparedSql, Object[] param) throws Exception {  //增删改操作的方法PreparedStatement preparedStatement = null;  //创建预处理对象并初始为空(通过预处理可以防止SQL恶意注入)int row = 0;  //初始受影响行数(当受影响行数大于0时,说明执行成功数据则更新)Connection connection = getConnection();  //调用getConnection()方法获取数据库连接try {preparedStatement = connection.prepareStatement(preparedSql);  //对sql形参预处理if (param != null) {  //形参数组(注入参数)不为空时,循环遍历对预处理sql注入参数for (int i = 0; i < param.length; i++) {//为预编译sql设置参数preparedStatement.setObject(i + 1, param[i]);}}row = preparedStatement.executeUpdate();  //执行sql语句并得到受影响的行数closeAll(connection,preparedStatement,null);  //调用closeAll()方法关闭资源,因为执行操作不含查询,则将结果集的实参传空} catch (SQLException e) {e.printStackTrace();}return row;  //返回受影响行数
}

因为sql语句中需要的参数类型是不确定的,则用Object类型数组作为容器

3、至此就剩查询操作了,在封装前需要创建一个实体类,以至于后续每个实体类都可以代表为一行数据,代码如下:

public class Student {//初始字段private int id;private String name;private int age;public Student(int id, String name, int age) {  //构造函数this.id = id;this.name = name;this.age = age;}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {  //toString方法return "Student{" +"id=" + id +", name='" + name + '\'' +", age=" + age +'}';}
}

实体对象有了,那么走你:

public List<Student> queryData (String sql, Object[] param) throws Exception {  //查询操作的方法PreparedStatement preparedStatement = null;  //创建预处理对象并初始为空(通过预处理可以防止SQL恶意注入)Connection connection = getConnection();  //调用getConnection()方法获取数据库连接preparedStatement = connection.prepareStatement(sql);  //调用getConnection()方法获取数据库连接if (param != null) {  //形参数组(注入参数)不为空时,循环遍历对预处理sql注入参数for (int i = 0; i < param.length; i++) {//为预编译sql设置参数preparedStatement.setObject(i + 1, param[i]);}}ResultSet resultSet = preparedStatement.executeQuery();  //得到返回的结果集List<Student> list = new ArrayList<Student>();  //创建List接口对象,泛型为指定Student对象类型,代表每个实体对象都是一行数据while (resultSet.next()) {  //循环遍历结果集,将每行数据封装成Student对象,并添加到List集合中Student student= new Student(resultSet.getInt(1), resultSet.getString(2), resultSet.getInt(3));  //获取结果集中的数据存入Student对象中list.add(student);  //将Student对象存入list接口中}closeAll(connection,preparedStatement,resultSet);  //调用closeAll()方法关闭数据库连接return list;  //返回List集合对象 
}

接下来创建一个测试类进行检查:

1、增删改测试

//增删改测试
BaseDao baseDao = new BaseDao();  //创建BaseDao对象
String sql = "insert into student(id,name,age) values(?,?,?)";  //定义预处理sql
Object[] list = {6, "老八", 35};  //将sql需要的参数存入至Object类型的数组
int add = baseDao.updateRow(sql, list); //调用增删改的方法并接收返回的受影响行数
if (add > 0) {  //受影响行数大于0则说明数据更新成功System.out.println("新增成功!受影响行数:" + add);
}
/* 删除、修改也是一样 */

控制台:

2、查询测试 

//查询测试
BaseDao baseDao = new BaseDao();  //创建BaseDao对象
String sql = "select * from student";  //定义预处理sql
List<Student> list = baseDao.queryData(sql, null);  //创建List接口,泛型为Student对象类型,用于存储查询返回的数据
for (Student student : list) {System.out.println(student.getId() + "\t\t" + student.getName() + "\t\t" + student.getAge());  //输出数据
}

控制台:

这么一来,JavaWeb中的每次增删改查都可以简明的实现,增删改查以外的特殊性业务功能可在BaseDao对象中具体实现方法

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/288636.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Adobe推出20多个,企业版生成式AI定制、微调服务

3月27日&#xff0c;全球多媒体领导者Adobe在拉斯维加斯召开“Summit 2024”大会&#xff0c;重磅推出了Firefly Services。 Firefly Services提供了20 多个生成式AI和创意API服务&#xff0c;支持企业自有数据对模型进行定制、微调&#xff0c;同时可以与PS、Illustrator、Ex…

高级DBA带你处理MySQL客户端程序频繁访问MYSQL数据库并错误链接不释放导致连接数爆满事故实战

高级DBA带你处理MySQL客户端程序频繁访问MYSQL数据库并错误链接不释放导致连接数爆满事故实战 一、生产事故描述 Mysql生产数据库最大连接数爆满&#xff0c;其余客户端也同样拿不到数据库连接&#xff0c;生产异常&#xff0c;数据传输失败&#xff01; 报错如下&#xff1a…

架构师之路--Docker的技术学习路径

Docker 的技术学习路径 一、引言 Docker 是一个开源的应用容器引擎&#xff0c;它可以让开发者将应用程序及其依赖包打包成一个可移植的容器&#xff0c;然后在任何支持 Docker 的操作系统上运行。Docker 具有轻量级、快速部署、可移植性强等优点&#xff0c;因此在现代软件开…

解决kubesphere流水线docker登陆错误http: server gave HTTP response to HTTPS client

kubesphere DevOps流水线中&#xff0c;在登录私有的harbor仓库时&#xff0c;报以下错误 docker login 111.230.19.120:80 -u admin -p test123. WARNING! Using --password via the CLI is insecure. Use --password-stdin. Error response from daemon: Get "https://…

使用vue构建一个简单实用的春节红包插件!

摘要&#xff1a;本文将介绍如何使用Vue.js构建一个简单实用的春节红包插件。该插件通过模拟红包的打开和关闭过程&#xff0c;以及金额的随机分配&#xff0c;为春节红包活动提供了一个有趣且互动的体验。 一、引言 在春节这个充满欢乐和祝福的时刻&#xff0c;红包成为了传递…

pt-archiver的实践分享,及为何要用 ob-archiver 归档数据的探讨

作者简介&#xff1a;肖杨&#xff0c;软件开发工程师 在数据密集型业务场景中&#xff0c;数据管理策略是否有效至关重要&#xff0c;它直接关系到系统性能与存储效率的提升。数据归档作为该策略的关键环节&#xff0c;不仅有助于优化数据库性能&#xff0c;还能有效降低存储成…

11.2024

插入排序 代码&#xff1a; public class 第十一题 {public static void main(String[] args) {int a[]{2,2,1,6,4,9,7,6,8};for (int k1;k<a.length;k){int sk-1;//排好序的最后一位int sssa[k];//记录哨兵的值while (s>0&&sss<a[s]){a[s1]a[s];s--;}a[s1]…

Python中的变量与常量

变量&#xff1a;在程序运行过程中&#xff0c;值会发生变化的量&#xff0c; 常量&#xff1a;在程序运行过程中&#xff0c;值不会发生变化的量。 无论是变量还是常量&#xff0c;在创建时都会在内存中开辟一块空间&#xff0c;用于保存它的值。 Python 中的变量不需要声明…

数仓建设实践——58用户画像数仓建设

目录 一、数据仓库&用户画像简介 1.1 数据仓库简介 1.2 数据仓库的价值 1.3 用户画像简介 1.4 用户画像—标签体系 二、用户画像数仓建设过程 2.1 画像数仓—背景&现状 2.2 画像数仓—整体架构 2.3 画像数仓—研发流程 2.4 画像数仓—指标定义 2.5 画像数仓…

基于大语言模型的云故障根因分析|顶会EuroSys24论文

*马明华 微软主管研究员 2021年CCF国际AIOps挑战赛程序委员会主席&#xff08;第四届&#xff09; 2021年博士毕业于清华大学&#xff0c;2020年在佐治亚理工学院做访问学者。主要研究方向是智能运维&#xff08;AIOps&#xff09;、软件可靠性。近年来在ICSE、FSE、ATC、EuroS…

【b站李炎恢】Vue.js Element UI | 十天技能课堂 | 更新中... | 李炎恢

课程地址&#xff1a;【Vue.js Element UI | 十天技能课堂 | 更新中... | 李炎恢】 https://www.bilibili.com/video/BV1U54y127GB/?share_sourcecopy_web&vd_sourceb1cb921b73fe3808550eaf2224d1c155 备注&#xff1a;虽然标题声明还在更新中&#xff0c;但是看一些常用…

一键换脸的facefusion

FaceFusion 一个开源换脸软件&#xff0c;提供UI界面&#xff0c;启动后可直接在浏览器上面上传图片进行换脸操作。 电脑环境win10&#xff0c;软件pycharm&#xff0c;需要提前安装好python环境&#xff0c;推荐使用Anaconda3。关注文章下方公共号发送 “ 软件安装包 ”可以获…

Docker搭建LNMP环境实战(06):Docker及Docker-compose常用命令

Docker搭建LNMP环境实战&#xff08;06&#xff09;&#xff1a;Docker及Docker-compose常用命令 此处列举了docker及docker-compose的常用命令&#xff0c;一方面可以做个了解&#xff0c;另一方面可以在需要的时候进行查阅。不一定要强行记忆&#xff0c;用多了就熟悉了。 1、…

sheng的学习笔记-AI-YOLO算法,目标检测

AI目录&#xff1a;sheng的学习笔记-AI目录-CSDN博客 目录 目标定位&#xff08;Object localization&#xff09; 定义 原理图 具体做法&#xff1a; 输出向量 图片中没有检测对象的样例 损失函数 ​编辑 特征点检测&#xff08;Landmark detection&#xff09; 定义&a…

Day23:事务管理、显示评论、添加评论

事务管理 事务的定义 什么是事务 事务是由N步数据库操作序列组成的逻辑执行单元&#xff0c;这系列操作要么全执行&#xff0c;要么全放弃执行。 事务的特性(ACID) 原子性(Atomicity):事务是应用中不可再分的最小执行体&#xff08;事务中部分执行失败就会回滚 。一致性(C…

R语言 for循环问题

今天偶然发现在R的for循环中&#xff0c;作为循环计次的i&#xff0c; 并不会因为在循环体中的赋值变化而变化。 记录一下&#xff0c;还没有找到相关的解释。

设计模式——行为型——策略模式Strategy

Q&#xff1a;策略模式的特点 A&#xff1a; 具体算法从具体的业务方法中独立出来策略模式是同行为的不同实现 Q&#xff1a;什么时候使用策略模式 A&#xff1a;多个if-else使用策略模式 收费对象类 public class CashContext {private CashStrategy cashStrategy;public…

R: 网状Meta分析进行模型构建及图形绘制

网状meta分析的制作步骤主要包括&#xff1a; 1. 绘制网状证据图 2. 普通Meta分析&#xff08;两两之间的直接比较&#xff09; 3. 网状Meta分析&#xff08;整合直接比较和间接比较的结果&#xff0c;绘制相关图形&#xff09; 4. 绘制累积概率排序图 5. 三个假设的检验…

【LeetCode: 2580. 统计将重叠区间合并成组的方案数 + 合并区间】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…

用搜索引擎收集信息-常用方式

1&#xff0c;site csdn.net &#xff08;下图表示只在csdn网站里搜索java&#xff09; 2&#xff0c;filetype:pdf &#xff08;表示只检索某pdf文件类型&#xff09; 表示在浏览器里面查找有关java的pdf文件 3&#xff0c;intitle:花花 &#xff08;表示搜索网页标题里面有花…