JDBC与数据库之间的操作(增删改查、获取主键、业务逻辑分离、属性文件配置)

参考视频哔哩哔哩

1、Service和Servicelmpl的概念

java中service和servicelmpl是常见的代码组织方式

  • Service是指业务逻辑的接口,定义了系统对外提供的功能。Servicelmpl是Service接口的具体实现,实现了具体的业务逻辑。

Service和Servicelmpl的好处
使用Service和Servicelmpl的方式可以带来以下好处:

  1. 代码分层清晰:通过将业务逻辑抽象为接口和实现类的方式,可以将不同层次的代码分离,提高代码的可读性和可维护性

  2. 便于扩展和测试:由于业务逻辑被封装在Service中,当需要添加新的功能时,只需要在Service接口中添加方法,并在Servicelmpl中实现即可。同时,由于业务逻辑和其他层解耦,可以方便地进行单元测试。

  3. 支持事务管理:在实际开发中,往往需要对一组操作进行事务管理。Service的设计可以方便地实现对一组操作的事务管理,保证数据的一致性。

2、DAO(Data Access Object Layer)

DAO层(Data Access Object Layer)是软件开发中的一种设计模式,主要用于将应用程序的业务逻辑与数据访问逻辑分离。DAO层提供了一种抽象的方式来处理数据库操作,使得数据存取和业务逻辑之间的解耦更为清晰。

2、1 DAO层的特点

  1. 职责明确:DAO层专注于数据的持久化与访问,不涉及业务逻辑。
  2. 抽象化:通过接口或类对数据访问进行封装,隐藏具体的数据访问实现细节,比如使用何种数据库、如何执行SQL语句等。
  3. 重用性:可以在多个地方复用相同的数据库访问代码,提高代码的一致性和可维护性。
  4. 易于测试:由于数据访问逻辑被封装,可以方便地使用模拟对象进行单元测试。

2、2 DAO层的组成

  • DAO接口:定义了数据访问的方法,如增、删、改、查等。
  • DAO实现类:实现具体的DAO接口,并包含与数据库交互的代码。
  • VO(Value Object)/DTO(Data Transfer Object):用于在DAO层与其他层之间传递数据的对象。

3、相关代码的实现:

3、1 链接数据库(逻辑和界面未分离):

1、加载驱动
2、创建连接
3、sql预编译
4、执行sql语句
5、关闭连接

package DBtest;import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.*;public class jdbctext {private static String URL;private static String USER;private static String PASSWORD;private static String DRIVER;static {try {InputStream in = DbUutil.class.getResourceAsStream("DbUtil.properties");Properties prop = new Properties();prop.load(in);DRIVER = prop.getProperty("driver");URL = prop.getProperty("url");USER = prop.getProperty("user");PASSWORD = prop.getProperty("password");} catch (IOException e) {e.printStackTrace();}}public static Connection getConn() throws SQLException {Connection conn = null;try {conn = DriverManager.getConnection(URL, USER, PASSWORD);} catch (SQLException e) {e.printStackTrace();}return conn;}public static int update(String sql, Object... params) throws SQLException {Connection conn = getConn();PreparedStatement ps = null;try {ps = conn.prepareStatement(sql);setParams(ps, params);return ps.executeUpdate();} catch (SQLException e) {e.printStackTrace();} finally {closeAll(conn, ps, null);}return -1;}public static void closeAll(Connection conn, PreparedStatement ps, ResultSet rs) {try {if (ps != null) {ps.close();}if (rs != null) {rs.close();}if (conn != null) {conn.close();}} catch (SQLException e) {e.printStackTrace();}}public static void setParams(PreparedStatement ps, Object... params) throws SQLException {if (params != null && params.length > 0) {for (int i = 0; i < params.length; i++) {ps.setObject(i + 1, params[i]);}}}public static List<List> queryList(String sql, Object... params) throws SQLException {Connection conn = getConn();PreparedStatement ps = null;ResultSet rs = null;List<List> lists = new ArrayList<>();try {ps = conn.prepareStatement(sql);setParams(ps, params);rs = ps.executeQuery();ResultSetMetaData metaData = rs.getMetaData();while (rs.next()) {List<Object> list = new ArrayList<>();for (int i = 0; i < metaData.getColumnCount(); i++) {list.add(rs.getObject(i + 1));}lists.add(list);}return lists;} catch (SQLException e) {e.printStackTrace();} finally {closeAll(conn, ps, rs);}return null;}public static List<Map<String, Object>> queryMap(String sql, Object... params) throws SQLException {Connection conn = getConn();PreparedStatement ps = null;ResultSet rs = null;List<Map<String, Object>> maps = new ArrayList<>();try {ps = conn.prepareStatement(sql);setParams(ps, params);rs = ps.executeQuery();ResultSetMetaData metaData = rs.getMetaData();while (rs.next()) {Map<String, Object> map = new HashMap<>();for (int i = 0; i < metaData.getColumnCount(); i++) {map.put(metaData.getColumnLabel(i + 1), rs.getObject(i + 1));}maps.add(map);}return maps;} catch (SQLException e) {e.printStackTrace();} finally {closeAll(conn, ps, rs);}return null;}public static int getPrimaryKey(String sql, Object... params) throws SQLException {Connection conn = getConn();PreparedStatement ps = null;ResultSet rs = null;try {ps = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);setParams(ps, params);ps.executeUpdate();rs = ps.getGeneratedKeys();if (rs.next()) {return rs.getInt(1);}} catch (SQLException e) {e.printStackTrace();} finally {closeAll(conn, ps, rs);}return -1;}
}

4、业务逻辑分离

4、1 加载配置文件

在这里插入图片描述

public class jdbctext {//   Connection con;private static String URL;private static String USER;private static String PASSWORD;private static String DRIVER;static {try {InputStream in = DbUutil.class.getResourceAsStream("DbUtil.properties");Properties prop = new Properties();prop.load(in);DRIVER  =prop.getProperty("driver");URL = prop.getProperty("url");USER = prop.getProperty("user");PASSWORD = prop.getProperty("password");} catch (IOException e) {e.printStackTrace();}}
}

配置文件DbUtil.properties

driver  = com.mysql.cj.jdbc.Driver
url = jdbc:mysql://127.0.0.1:3306/contact?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8
user = root
password = 123456

4、2 封装创建连接的方法

/**
1、方法名:getConn();
2、参数列表  不需要
3、返回值 Connection conn
*/
public static Connection getConn() throws SQLException {Connection conn = null;try {conn = DriverManager.getConnection(URL, USER, PASSWORD);} catch (SQLException e) {e.printStackTrace();// throw new RuntimeException(e); // Uncomment if you want to rethrow the exception}return conn;
}

4、3 通用增删改查操作

1、方法名:update()
2、参数列表:
(1)sql语句 参数
(2)sql ?的占位符,所代表的参数
3、返回值:返回增删改查的结果,成功还是失败,返回值是成功改变数据的行数。

public static int update(String sql, Object... params) throws SQLException {// 调用上面封装好的,得到conn连接Connection conn = getConn();PreparedStatement ps = null;try {ps = conn.prepareStatement(sql);// 调用通用的设置sql语句的方法,向sql中设置参数setParams(ps, params);// 执行sql语句int i = ps.executeUpdate();return i;} catch (SQLException e) {e.printStackTrace();} finally {// 调用通用的关闭方法closeAll(conn, ps, null);}return -1; // 在异常情况下返回 -1
}

4、4 封装通用的关闭的方法:

1、方法名 closeAll()
2、参数列表:
ResultSet set;PrearedlStatement ps;Connection conn
3、返回值 :不需要返回值

public static void closeAll(Connection conn, PreparedStatement ps, ResultSet rs) {// Close PreparedStatementtry {if (ps != null) {ps.close();}} catch (SQLException e) {e.printStackTrace();}// Close ResultSettry {if (rs != null) {rs.close();}} catch (SQLException e) {e.printStackTrace();}// Close Connectiontry {if (conn != null) {conn.close();}} catch (SQLException e) {e.printStackTrace();}
}

4、5 封装通用查询方法(List)

/**
*封装通用的查询方法
*需要做数据的转储:目的是能够把查询的出的数据 在程序中别的地方使用。
*可以转储两种形式:
* List
* List
* 方法名 queryList()
* 参数列表 sql,Object…params :传入参数不定个数相当于数组,在传递参时,不传也不会报错
* 返回值 查询到的结果
*/

public static List<List> queryList(String sql, Object... params) throws SQLException {// Establish the connectionConnection conn = getConn();PreparedStatement ps = null;ResultSet rs = null;try {// Prepare the SQL statementps = conn.prepareStatement(sql);// Set parameters for the prepared statementsetParams(ps, params);// Execute the SQL queryrs = ps.executeQuery();// Retrieve metadata about the result setResultSetMetaData metaData = rs.getMetaData();// Create a list to hold all rows of dataList<List<Object>> lists = new ArrayList<>();// Process each row in the result setwhile (rs.next()) {// Create a list to hold data for the current rowList<Object> list = new ArrayList<>();// Populate the row list with data from the result setfor (int i = 0; i < metaData.getColumnCount(); i++) {list.add(rs.getObject(i + 1));}// Add the current row list to the main listlists.add(list);}return lists;} catch (SQLException e) {e.printStackTrace();} finally {// Ensure all resources are closedcloseAll(conn, ps, rs);}return null;
}

4、6 封装通用查询方法(Map)

/**
* 封装List<>map<String,Object>类型
* 方法的三要素:
* 1、方法名 queryMap()
* 2、参数列表 sql,Object …
* 3、返回值 如果没有查到数据 就返回NUll
*/

public static List<Map<String, Object>> queryMap(String sql, Object... params) throws SQLException {// Establish the connectionConnection conn = getConn();PreparedStatement ps = null;ResultSet rs = null;try {// Prepare the SQL statementps = conn.prepareStatement(sql);// Set parameters for the prepared statementsetParams(ps, params);// Execute the SQL queryrs = ps.executeQuery();// Create a list to hold the maps of each rowList<Map<String, Object>> maps = new ArrayList<>();// Retrieve metadata about the result setResultSetMetaData metaData = rs.getMetaData();// Process each row in the result setwhile (rs.next()) {// Create a map to hold data for the current rowMap<String, Object> map = new HashMap<>();// Populate the map with column labels and values from the result setfor (int i = 0; i < metaData.getColumnCount(); i++) {map.put(metaData.getColumnLabel(i + 1), rs.getObject(i + 1));}// Add the current row map to the main listmaps.add(map);}return maps;} catch (SQLException e) {e.printStackTrace();// Optionally throw a runtime exception if needed// throw new RuntimeException(e);} finally {// Ensure all resources are closedcloseAll(conn, ps, rs);}return null;
}

4、7 新增时返回自增主键的方法

/**
* 新增时返回自增主键的方法
* 1、方法名 getParmaryKey()
* 2、参数列表 String sql, Object …params
* 3、返回值 int
*/

public static int getPrimaryKey(String sql, Object... params) throws SQLException {// Establish the connectionConnection conn = getConn();PreparedStatement ps = null;ResultSet rs = null;try {// Prepare the SQL statement to return generated keysps = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);// Set parameters for the prepared statementsetParams(ps, params);// Execute the update SQL statementps.executeUpdate();// Retrieve the generated keys (primary key)rs = ps.getGeneratedKeys();// Check if the result set has a row and return the primary keyif (rs.next()) {return rs.getInt(1);}} catch (SQLException e) {e.printStackTrace();} finally {// Ensure all resources are closedcloseAll(conn, ps, rs);}// Return -1 if no primary key was generatedreturn -1;
}

5、测试及结果:

在这里插入图片描述

package DBtest;import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import java.util.Objects;public class DBtext {public static void main(String[] args) throws SQLException {//测试封装的增删改方法String sql ="insert into text values(?,?,null)";//  String sql ="select *from text";//    List<Map<String, Object>> list= jdbctext.queryMap(sql);Object[] parms = { "活着","23"};//   Object[] parms=null; 这里是没传入参数// int i= jdbctext.update(sql,parms);int key= jdbctext.getParmaryKey(sql,parms);System.out.println(key);//  System.out.println(list);}
}

在这里插入图片描述

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

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

相关文章

SpinalHDL之数据类型(一)

本文作为SpinalHDL学习笔记第五十四篇,介绍SpinalHDL的Bool数据类型。 SpinalHDL技术交流QQ群: Note: 1.本群是个人技术交流群,不是什么官方答疑群; 2.提问是你的权利,但回答不是别人的义务; 3.可以潜水,不能灌水; 4.请文明交流,做这行的都算高层次人才,希望你…

黑神话悟空背后的技术揭秘与代码探秘

《重塑神话&#xff1a;黑神话悟空背后的技术揭秘与代码探秘》 引言 在国产游戏领域&#xff0c;《黑神话:悟空》无疑是一颗璀璨的明星&#xff0c;它不仅融合了深厚的中国文化元素&#xff0c;更在技术上实现了诸多突破&#xff0c;为玩家带来了前所未有的沉浸式体验。本文将…

sqli-lab靶场学习(一)——Less1-4

前言 最近一段时间想切入安全领域&#xff0c;因为本身有做数据库运维工作&#xff0c;就打算从sql注入方向切入。而sql注入除了学习日常书本上的概念外&#xff0c;需要有个实践的环境&#xff0c;刚好看到sqli-lab这个靶场&#xff0c;就打算先用这个来学习。 安装部署 网上…

HTTP“请求”和“响应”的报头及正文详解

目录 一、请求 "报头" (header) 二、请求 "正文" (body) 2.1 application/x-www-form-urlencoded 2.2 multipart/form-data 2.3 application/json 三、HTTP 响应状态码 四、响应 "报头" (header) 五、响应 "正文" (body) 5.1…

微信小程序实践案例

参考视频&#xff1a; https://www.bilibili.com/video/BV1834y1676P/?p36&spm_id_frompageDriver&vd_sourceb604c19516c17da30b6b1abb6c4e7ec0 前期准备 1、新建三个页面 "pages": ["pages/home/home","pages/message/message",&quo…

智慧交通基于yolov8的井盖异常检测系统python源码+onnx模型+评估指标曲线+精美GUI界面

【算法介绍】 智慧交通中的井盖异常检测系统&#xff0c;基于先进的YOLOv8算法&#xff0c;为城市基础设施的安全管理提供了强有力的技术支持。该系统通过集成YOLOv8的深度学习技术&#xff0c;实现了对道路井盖状态的实时、精准监测。 YOLOv8以其高效、准确的特点&#xff0…

为什么现在不建议去电力设计院?终于有人把电力设计院说清楚了!

作者&#xff1a;电气哥 最近电气哥收到了许多面临就业的同学特别是硕士同学有关于电力设计院的咨询&#xff0c;那么现在电力设计院到底还值不值得去&#xff1f;电气哥带你来分析一下电力设计院的前世今生。 01 电力设计院的前世今生 曾经&#xff0c;在我国的大基建时代&…

“Docker网络模式详解与应用“

目录 前言 Docker内置网络 bridge 基本概念 案例 工作原理 使用场景 host 基本概念 案例 工作原理 使用场景 none 基本概念 案例 &#xff01;&#xff01;&#xff01;大佬救命 container 基本概念 案例 自定义网络 自定义bridge 基本概念 案例 Docker…

如何操作可以有效的防止其他人修改Excel文件?

工作中&#xff0c;我们经常遇到同一份表格可能需要好多人共同去完成&#xff0c;但是当你整理好数据发给别的同事的时候&#xff0c;等表格再回来的时候&#xff0c;你可能发现你之前设置的资料格式内容等都被修改了&#xff0c;遇到这种情况时&#xff0c;如何操作可以有效的…

传统CV算法——基于Opencv的图像绘制

直线绘制 参数解析&#xff1a; &#xff08;图像矩阵&#xff0c;直线起始坐标&#xff0c; 直线终止坐标、颜色、线条厚度&#xff09; cv2.line()是OpenCV中用于绘制直线的函数。 参数说明&#xff1a;img&#xff1a;要绘制直线的图像矩阵。(100,30)&#xff1a;直线的起…

第二十三篇——地形篇:将领的四条职业道德准则

目录 一、背景介绍二、思路&方案三、过程1.思维导图2.文章中经典的句子理解3.学习之后对于投资市场的理解4.通过这篇文章结合我知道的东西我能想到什么&#xff1f; 四、总结五、升华 一、背景介绍 这一篇讲将领应该如何做&#xff0c;以及正反方面也讲到了职场人应该如何…

STM32CUBEIDE FreeRTOS操作教程(四):timer软件定时器

STM32CUBEIDE FreeRTOS操作教程&#xff08;四&#xff09;&#xff1a;timer软件定时器 STM32CUBE开发环境集成了STM32 HAL库进行FreeRTOS配置和开发的组件&#xff0c;不需要用户自己进行FreeRTOS的移植。这里介绍最简化的用户操作类应用教程。以STM32F401RCT6开发板为例&am…

oauth2 方式获取outlook邮箱收件箱(python)

1.在Azure 门户注册应用程序 微软文档地址 重定向的地址配置(微软地址)&#xff1a; https://login.microsoftonline.com/common/oauth2/nativeclient 注册应用地址 2.程序代码 #安装包以及需要的驱动 pip3 install playwrightplaywright install import base64 import jso…

MAT:一款针对MSSQL服务器的安全检测与审计工具

关于MAT MAT是一款针对MSSQL服务器的安全检测与审计工具&#xff0c;该工具使用C#开发&#xff0c;可以帮助广大研究人员快速识别和发现MSSQL 服务器中的安全问题&#xff0c;并实现安全检测与审计目的。 功能介绍 1、执行自动检查并识别安全问题&#xff1b; 2、允许通过 Win…

暑期档总结:哪部国漫年番表现更优?

“暑期档”可能是所有档期中绵延时间最长的&#xff0c;作为该时间段主力的学生人群&#xff0c;在学业压力较小的假期中&#xff0c;需要更多娱乐方式来填充生活。除了电影之外&#xff0c;动画番剧越来越成为这一群体的不二选择&#xff0c;各个动画制作公司也会选择把精彩剧…

Datawhle X 李宏毅苹果书AI夏令营深度学习笔记之——卷积神经网络的前世今生

一、卷积神经网络简介 卷积神经网络&#xff08;Convolutional Neural Network, CNN&#xff09;是一种深度学习模型&#xff0c;尤其擅长处理图像和视频等高维度的数据。CNN 通过模仿人类视觉系统的工作方式&#xff0c;自动学习数据中的空间层次结构&#xff0c;使得它在计算…

GDB 查看汇编

查看汇编 x disassemble

24秋开学考

文件上传 上传一个.php的格式&#xff0c;上面说是非法的文件格式。 2.传了一个phpinfo.gif&#xff0c;说什么在目录里。 3.有两个页面一个labs1一个labs2 &#xff0c;当在第一个页面上传1.jpg&#xff0c;在第二个页面上传1.jpg时&#xff0c;给了我们一个目录,在测试其他时…

Linux下的Makefile与进度条程序

目录 Linux下的Makefile与进度条程序 Makefile与make Makefile与make介绍 创建第一个Makefile并使用make Makefile文件基本格式介绍 Makefile依赖方法执行过程 Makefile通用写法 进度条程序 实现效果 前置知识 回车(\r)与换行(\n) 输出缓冲区 实现进度条 Linux下的…

15、Django Admin添加自定义字段功能

修改模型类HeroAdmin admin.register(Hero) class HeroAdmin(admin.ModelAdmin):change_list_template "entities/heroes_changelist.html"... # 此处原代码不动&#xff0c;只增加此前后代码def get_urls(self):urls super().get_urls()my_urls [path(immort…