jdbc DAO封裝及BaseDAO工具類

DAO概念

DAO:Data Access Object,數據訪問對象。

Java是面向對象語言,數據在Java中通常以對象的形式存在。一張表對應一個實體類,一張表的操作對應一個DAO對象!

在Java操作數據庫時,我們會將對同一張表的增刪改查操作統一維護起來,維護的這個類就是DAO層。

DAO層只關注對數據庫的操作,供業務層Service調用,將職責劃分清楚!

還是有user為例

面向接口開發,這邊先提供dao接口

package com.qayrup.dao;import com.qayrup.pojo.User;/*** @author qayrup* @version 1.0* @date-time 2025/9/12-10:20* @belongs-project qayrup-study* @belongs-package com.qayrup.dao* @description*/public interface UserDao {User queryUserByNameAndPassword(String name, String password);int insertUser(User user);
}

實現這個接口

package com.qayrup.dao.impl;import com.qayrup.dao.UserDao;
import com.qayrup.pojo.User;
import com.qayrup.utils.JDBCTools;import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;/*** @author qayrup* @version 1.0* @date-time 2025/9/12-10:21* @belongs-project qayrup-study* @belongs-package com.qayrup.dao.impl* @description*/public class UserDaoImpl implements UserDao {@Override/*** 根據用戶名和密碼查詢用戶信息* @param name 用戶名* @param password 密碼* @return 查詢到的User對象,如果未找到則返回空的User對象* @throws Exception 數據庫操作異常*/public User queryUserByNameAndPassword(String name, String password) throws Exception {// 從JDBCTools工具類中獲取數據庫連接Connection connection = JDBCTools.getConnection();// 定義SQL查詢語句,使用占位符防止SQL注入String sql = "select * from user where name = ? and password = ?";// 創建PreparedStatement對象,用于執行預編譯SQL語句PreparedStatement preparedStatement = connection.prepareStatement(sql);// 設置第一個占位符的值為傳入的用戶名preparedStatement.setString(1, name);// 設置第二個占位符的值為傳入的密碼preparedStatement.setString(2, password);// 執行查詢操作,獲取結果集ResultSet resultSet = preparedStatement.executeQuery();// 創建一個新的User對象用于存儲查詢結果User user = new User();// 遍歷結果集,通常只會有一條記錄匹配while (resultSet.next()){// 從結果集中獲取id字段值并設置到user對象user.setId(resultSet.getLong("id"));// 從結果集中獲取name字段值并設置到user對象user.setName(resultSet.getString("name"));// 從結果集中獲取password字段值并設置到user對象user.setPassword(resultSet.getString("password"));// 從結果集中獲取type字段值并設置到user對象user.setType(resultSet.getInt("type"));// 從結果集中獲取status字段值并設置到user對象user.setStatus(resultSet.getInt("status"));// 從結果集中獲取created_at字段值并設置到user對象user.setCreated_at(resultSet.getDate("created_at"));// 從結果集中獲取created_by字段值并設置到user對象user.setCreated_by(resultSet.getLong("created_by"));// 從結果集中獲取updated_at字段值并設置到user對象user.setUpdated_at(resultSet.getDate("updated_at"));// 從結果集中獲取updated_by字段值并設置到user對象user.setUpdated_by(resultSet.getLong("updated_by"));}// 關閉PreparedStatement資源preparedStatement.close();// 返回封裝了查詢結果的User對象return user;}/*** 插入新的用戶信息到數據庫* @param user 要插入的User對象* @return 受影響的行數,成功插入返回1* @throws Exception 數據庫操作異常*/@Overridepublic int insertUser(User user) throws Exception {// 從JDBCTools工具類中獲取數據庫連接Connection connection = JDBCTools.getConnection();// 定義SQL插入語句,使用占位符防止SQL注入String sql = "insert into user(name,password,type,status,created_at,created_by,updated_at,updated_by) values(?,?,?,?,?,?,?,?)";// 創建PreparedStatement對象,用于執行預編譯SQL語句PreparedStatement preparedStatement = connection.prepareStatement(sql);// 設置第一個占位符的值為用戶姓名preparedStatement.setString(1, user.getName());// 設置第二個占位符的值為用戶密碼preparedStatement.setString(2, user.getPassword());// 設置第三個占位符的值為用戶類型preparedStatement.setInt(3, user.getType());// 設置第四個占位符的值為用戶狀態preparedStatement.setInt(4, user.getStatus());// 設置第五個占位符的值為創建時間,將java.util.Date轉換為java.sql.DatepreparedStatement.setDate(5, new java.sql.Date(user.getCreated_at().getTime()));// 設置第六個占位符的值為創建者IDpreparedStatement.setLong(6, user.getCreated_by());// 設置第七個占位符的值為更新時間,將java.util.Date轉換為java.sql.DatepreparedStatement.setDate(7, new java.sql.Date(user.getUpdated_at().getTime()));// 設置第八個占位符的值為更新者IDpreparedStatement.setLong(8, user.getUpdated_by());// 執行插入操作,返回受影響的行數// 返回插入操作的結果return preparedStatement.executeUpdate();}
}

外部調用

@Testpublic void daoSelect() throws Exception {UserDao userDao = new UserDaoImpl();User user = userDao.queryUserByNameAndPassword("admin", "admin");System.out.println("user = " + user);}

在這里插入圖片描述
這樣有個壞處,那就是每有一張表,就得寫一個這種查詢,
所以這邊將這種基礎查詢封裝

package com.qayrup.dao;import com.qayrup.utils.JDBCTools;import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;/*** @author qayrup* @version 1.0* @date-time 2025/9/12-09:58* @belongs-project qayrup-study* @belongs-package com.qayrup.dao* @description*/public class BaseDao {protected int update(String sql, Object... args) throws Exception {Connection connection = JDBCTools.getConnection();PreparedStatement preparedStatement = connection.prepareStatement(sql);if(args != null && args.length>0){for(int i=0; i<args.length; i++) {preparedStatement.setObject(i+1,args[i]);//?的編號從1開始,不是從0開始,數組的下標是從0開始}}int count = preparedStatement.executeUpdate();preparedStatement.close();if (!connection.getAutoCommit())  return count;//回收JDBCTools.release();return count;}/*通用的查詢多個Javabean對象的方法,例如:多個員工對象,多個部門對象等這里的clazz接收的是T類型的Class對象,如果查詢員工信息,clazz代表Employee.class,如果查詢部門信息,clazz代表Department.class,返回List<T> list*/protected <T> ArrayList<T> query(Class<T> clazz, String sql, Object... args) throws Exception {//        創建PreparedStatement對象,對sql預編譯Connection connection = JDBCTools.getConnection();PreparedStatement ps = connection.prepareStatement(sql);//設置?的值if(args != null && args.length>0){for(int i=0; i<args.length; i++) {ps.setObject(i+1, args[i]);//?的編號從1開始,不是從0開始,數組的下標是從0開始}}ArrayList<T> list = new ArrayList<>();ResultSet res = ps.executeQuery();/*獲取結果集的元數據對象。元數據對象中有該結果集一共有幾列、列名稱是什么等信息*/ResultSetMetaData metaData = res.getMetaData();int columnCount = metaData.getColumnCount();//獲取結果集列數//遍歷結果集ResultSet,把查詢結果中的一條一條記錄,變成一個一個T 對象,放到list中。while(res.next()){//循環一次代表有一行,代表有一個T對象T t = clazz.newInstance();//要求這個類型必須有公共的無參構造//把這條記錄的每一個單元格的值取出來,設置到t對象對應的屬性中。for(int i=1; i<=columnCount; i++){//for循環一次,代表取某一行的1個單元格的值Object value = res.getObject(i);//這個值應該是t對象的某個屬性值//獲取該屬性對應的Field對象//String columnName = metaData.getColumnName(i);//獲取第i列的字段名//這里再取別名可能沒辦法對應上String columnName = metaData.getColumnLabel(i);//獲取第i列的字段名或字段的別名//通過反射將屬性的值設置到t對象中Field field = clazz.getDeclaredField(columnName);//開啟暴力反射field.setAccessible(true);//這么做可以操作private的屬性//將值設置給t對象field.set(t,value);}list.add(t);}res.close();ps.close();//這里檢查下是否開啟事務,開啟不關閉連接,業務方法關閉!//沒有開啟事務的話,直接回收關閉即可!if (connection.getAutoCommit()) {//回收JDBCTools.release();}return list;}/*** 通用的查詢單個JavaBean對象的方法* @param clazz 指定要查詢的JavaBean類型* @param sql 查詢SQL語句* @param args SQL中的參數值* @return 返回查詢到的第一個對象,如果沒有查詢到則返回null* @throws Exception 拋出異常*/protected <T> T queryBean(Class<T> clazz,String sql, Object... args) throws Exception {// 調用query方法獲取查詢結果列表ArrayList<T> list = query(clazz, sql,args);// 如果查詢結果為空或者沒有數據,則返回nullif(list == null || list.size() == 0){return null;}// 返回查詢結果中的第一個對象return list.get(0);}
}

讓實現類繼承這個封裝類
在這里插入圖片描述

結果
在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/923632.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/923632.shtml
英文地址,請注明出處:http://en.pswp.cn/news/923632.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

大模型應用開發2-SpringAI實戰

SpringAI整合了大多數大模型&#xff0c;而且對于大模型開發的三種技術架構都有比較好的封裝和支持&#xff0c;開發起來非常方便。不同的模型能夠接收的輸入類型、輸出類型不一定相同。SpringAI根據模型的輸入和輸出類型不同對模型進行了分類&#xff1a; 大模型應用開發大多…

TDengine 時序函數 DIFF 用戶手冊

DIFF 函數用戶手冊 函數概述 DIFF 函數用于計算數據列中相鄰兩行數據的差值&#xff0c;通常用于分析數據的變化趨勢和增量。該函數特別適用于監控智能電表數據的變化模式。 語法 SELECT DIFF(column_name [, ignore_negative]) FROM table_name;參數說明 column_name: 數…

清除gradle緩存的某個依賴

要清除 Gradle 緩存中的某個特定依賴&#xff0c;可以按照以下步驟操作&#xff1a;找到依賴在緩存中的路徑 Gradle 緩存的默認位置&#xff1a; Windows: C:\Users\<用戶名>\.gradle\caches\modules-2\files-2.1 macOS/Linux: ~/.gradle/caches/modules-2/files-2.1 路徑…

機器人控制器開發(驅動層——伺服驅動canopen的sdo和pdo)

文章總覽 一、核心區別&#xff1a;一句話概括 ? ??SDO&#xff08;服務數據對象&#xff09;??&#xff1a;像 ??“問詢/設置”??。用于??點對點、非周期??的參數配置和讀取。例如&#xff0c;設置電機增益、讀取當前位置等。??速度慢&#xff0c;但確保數據準…

返利APP排行榜數據實時更新:基于 WebSocket 與 Redis 的高并發數據推送技術

返利APP排行榜數據實時更新&#xff1a;基于 WebSocket 與 Redis 的高并發數據推送技術 大家好&#xff0c;我是阿可&#xff0c;微賺淘客系統及省賺客APP創始人&#xff0c;是個冬天不穿秋褲&#xff0c;天冷也要風度的程序猿&#xff01; 在返利APP運營中&#xff0c;用戶對排…

[論文閱讀] 人工智能 + 軟件工程 | 告別冗余HTML與高算力消耗:EfficientUICoder如何破解UI2Code的token難題

告別冗余HTML與高算力消耗&#xff1a;EfficientUICoder如何破解UI2Code的token難題 論文信息信息類別具體內容論文原標題EfficientUICoder: A Dual-Modal Token Compression Framework for UI-to-Code Generation with Multimodal Large Language Models論文鏈接https://arxiv…

【STM32項目開源】STM32單片機智能語音風扇控制系統

目錄 一、設計背景和意義 1.1設計背景&#xff1a; 1.2設計意義&#xff1a; 二、實物展示 三、硬件功能介紹 2.1 硬件清單&#xff1a; 2.2 功能介紹&#xff1a; 四、軟件設計流程圖 五、硬件PCB展示 六、軟件主函序展示 七、單片機實物資料 資料獲取 查看主頁介…

git clone vllm

這個錯誤不是 vLLM 本身的問題&#xff0c;而是 pip 在 clone GitHub 倉庫時失敗了&#xff1a; error: RPC failed; curl 16 Error in the HTTP2 framing layer fatal: expected flush after ref listing根因通常是&#xff1a; 網絡問題&#xff08;訪問 GitHub 被中斷 / 代理…

光譜相機的新興領域應用

光譜相機在?新興領域?的應用正快速拓展&#xff0c;結合?AI、納米技術、量子傳感?等前沿科技&#xff0c;突破傳統檢測極限。以下是六大最具潛力的新興應用方向及技術突破點&#xff1a;?1. 元宇宙與數字孿生??應用場景?&#xff1a;?虛擬材質建模?&#xff1a;通過高…

深入理解數據結構之復雜度

文章目錄1.數據結構前言1.1 數據結構1.2 算法2.算法效率2.1 復雜度的概念2.2 復雜度的重要性3.1 大O的漸進表式法3.2 時間復雜度計算示例3.2.1 示例13.2.2 示例23.2.3 示例33.2.4 示例43.2.5 示例53.2.6 示例63.2.7 示例74.空間復雜度4.1 空間復雜度計算示例4.1.1 示例14.1.2 示…

【Vue3】10-編寫vue項目時,ref的應用(2)

合集篇&#xff1a; 1.【Vue3】創建并運行一個簡易的Vue3項目 2.【Vue3】編寫vue實現一個簡單效果&#xff0c;并使用setup糖簡化代碼 目錄refref 定義對象類型的響應式數據1. 概念理解a. 概念b. 分析2. 代碼實操代碼場景步驟一&#xff1a;導入ref步驟二&#xff1a;修改數據形…

clickhouse 中SUM(CASE WHEN ...) 返回什么類型?

文章目錄clickhouse 中SUM(CASE WHEN ...) 返回什么類型&#xff1f;CASE WHENSUM(CASE WHEN ...) 返回什么類型&#xff1f;clickhouse 中SUM(CASE WHEN …) 返回什么類型&#xff1f; CASE WHEN ClickHouse中的CASE WHEN用法與SQL標準中的用法基本相同&#xff0c;用于實現…

【算法】C語言多組輸入輸出模板

在 C語言 里&#xff0c;“多組輸入輸出”是很多在線評測系統&#xff08;OJ&#xff09;常見的模式&#xff0c;通常有兩種情況&#xff1a;1. 輸入到文件結束&#xff08;EOF&#xff09;比如題目沒有告訴有多少組數據&#xff0c;就需要一直讀直到輸入結束。#include <st…

【Ubuntu】sudo apt update出現E :倉庫***沒有Release文件

【Ubuntu】sudo apt update出現E &#xff1a;倉庫***沒有Release文件 1 問題描述 在執行sudo apt update更新一下軟件包時出現了如下報錯 E: 倉庫***沒有Release 文件。 N: 無法安全地用該源進行更新&#xff0c;所以默認禁用該源。 N:參見apt-secure&#xff08;8&#xf…

全球后量子遷移進展:區域特色與產業落地差異

一、量子威脅具象化&#xff1a;從技術風險到產業沖擊量子計算對傳統密碼體系的威脅已從理論走向現實&#xff0c;其破壞性不僅體現在算法破解效率的飛躍&#xff0c;更滲透到數據全生命周期的安全防護中。以金融領域為例&#xff0c;2024 年國際安全機構模擬實驗顯示&#xff…

貪心算法應用:決策樹(ID3/C4.5)詳解

Java中的貪心算法應用&#xff1a;決策樹&#xff08;ID3/C4.5&#xff09;詳解 決策樹是一種常用的機器學習算法&#xff0c;它通過遞歸地將數據集分割成更小的子集來構建樹形結構。ID3和C4.5是兩種經典的決策樹算法&#xff0c;它們都使用了貪心算法來選擇最優的特征進行分割…

華為任旭東:開源協作,激發創新,共創智能世界 | GOSIM HANGZHOU 2025

GOSIM HANGZHOU 2025峰會盛大開幕&#xff0c;華為首席開源聯絡官、CNCF基金會董事任旭東以《開源協作&#xff0c;激發創新&#xff0c;共創智能世界》為題發表Keynote演講。顛覆性技術到工業應用的轉換時間越來越短&#xff0c;AI技術正在推動傳統軟件產業的演進&#xff0c;…

本地部署 GPS 跟蹤系統 Traccar 并實現外部訪問

Traccar 是一款集成了強大的 java 后端服務的 GPS 跟蹤系統 。它支持在多種設備使用&#xff0c;在物流運輸、資產管理和個人安全等領域應用。本文將詳細的介紹如何利用 Docker 在本地部署 Traccar 并結合路由俠實現外網訪問本地部署的 Traccar 。 第一步&#xff0c;本地部署…

【開題答辯全過程】以 “川趣玩”旅行團預定微信小程序為例,包含答辯的問題和答案

個人簡介一名14年經驗的資深畢設內行人&#xff0c;語言擅長Java、php、微信小程序、Python、Golang、安卓Android等開發項目包括大數據、深度學習、網站、小程序、安卓、算法。平常會做一些項目定制化開發、代碼講解、答辯教學、文檔編寫、也懂一些降重方面的技巧。感謝大家的…

Android Doze低電耗休眠模式 與 WorkManager

1. Doze模式下&#xff0c;WorkManager setInitialDelay設置小于15分鐘&#xff0c;被系統強制到15分鐘執行&#xff0c;怎么辦 ? Android 擁有兩項省電功能&#xff0c;通過管理設備未連接電源時應用的行為來延長用戶電池續航時間&#xff1a;低電耗模式 (Doze) 和應用待機模…