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

news2024/9/19 10:46:35

参考视频哔哩哔哩

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 PreparedStatement
    try {
        if (ps != null) {
            ps.close();
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }

    // Close ResultSet
    try {
        if (rs != null) {
            rs.close();
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }

    // Close Connection
    try {
        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 connection
    Connection conn = getConn();
    PreparedStatement ps = null;
    ResultSet rs = null;

    try {
        // Prepare the SQL statement
        ps = conn.prepareStatement(sql);
        
        // Set parameters for the prepared statement
        setParams(ps, params);
        
        // Execute the SQL query
        rs = ps.executeQuery();
        
        // Retrieve metadata about the result set
        ResultSetMetaData metaData = rs.getMetaData();

        // Create a list to hold all rows of data
        List<List<Object>> lists = new ArrayList<>();

        // Process each row in the result set
        while (rs.next()) {
            // Create a list to hold data for the current row
            List<Object> list = new ArrayList<>();

            // Populate the row list with data from the result set
            for (int i = 0; i < metaData.getColumnCount(); i++) {
                list.add(rs.getObject(i + 1));
            }

            // Add the current row list to the main list
            lists.add(list);
        }

        return lists;
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        // Ensure all resources are closed
        closeAll(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 connection
    Connection conn = getConn();
    PreparedStatement ps = null;
    ResultSet rs = null;

    try {
        // Prepare the SQL statement
        ps = conn.prepareStatement(sql);
        
        // Set parameters for the prepared statement
        setParams(ps, params);
        
        // Execute the SQL query
        rs = ps.executeQuery();

        // Create a list to hold the maps of each row
        List<Map<String, Object>> maps = new ArrayList<>();
        
        // Retrieve metadata about the result set
        ResultSetMetaData metaData = rs.getMetaData();

        // Process each row in the result set
        while (rs.next()) {
            // Create a map to hold data for the current row
            Map<String, Object> map = new HashMap<>();

            // Populate the map with column labels and values from the result set
            for (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 list
            maps.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 closed
        closeAll(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 connection
    Connection conn = getConn();
    PreparedStatement ps = null;
    ResultSet rs = null;

    try {
        // Prepare the SQL statement to return generated keys
        ps = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
        
        // Set parameters for the prepared statement
        setParams(ps, params);
        
        // Execute the update SQL statement
        ps.executeUpdate();
        
        // Retrieve the generated keys (primary key)
        rs = ps.getGeneratedKeys();
        
        // Check if the result set has a row and return the primary key
        if (rs.next()) {
            return rs.getInt(1);
        }
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        // Ensure all resources are closed
        closeAll(conn, ps, rs);
    }

    // Return -1 if no primary key was generated
    return -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.coloradmin.cn/o/2095884.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Android自定义View实现不同朝向字体变色

实现效果&#xff1a; 1.一个文字两种颜色 2.实现不同朝向 3.结合ViewPager 思路&#xff1a;TextView可行&#xff1f;系统提供的只能够显示一种颜色&#xff0c;需要自定义View extends TextView&#xff1a;onMeasure()不需要实现 textColor颜色&#xff0c;textSize字体大小…

OpenAI Whisper API (InvalidRequestError)

题意: OpenAI Whisper API&#xff08;无效请求错误&#xff09; 问题背景&#xff1a; Im trying to use OpenAI Whisper API to transcribe my audio files. When I run it by opening my local audio files from disk, it worked perfectly. Now Im developing a FastAPI e…

学习WebGl基础知识(二)

学习目标&#xff1a; 掌握WebGl基础知识 学习内容&#xff1a; 创建一个Webgl程序 创建三维上下文对象创建顶点着色器和片元着色器创建和编译顶点着色器和片元着色器创建着色器程序对象绘制图元 创建一个Webgl程序 1.第一步获取画布&#xff0c;创建三维上下文对象 <ca…

一些硬件知识(十七)

电源芯片选型&#xff1a; 1.考虑拓扑结构 2.考虑功率&#xff0c;从而决定自行搭建电路还是选择芯片 3.对于低功耗产品&#xff0c;静态电流是非常重要的因素&#xff0c;一定重要考虑&#xff1a; 同步buck省去了续流二极管&#xff0c;效率比异步的高。 如果真的比耐压值…

ESP32小车:1.硬件模块与连接

一、硬件模块 总的元器件清单:亚克力板(三轮),两个普通减速电机,一个开关模块,一个 首先,需要一块亚克力单层底板,推荐随便在淘宝上买一块2WD亚克力单层板,比如: 最好亚克力板自带电机,买一套也不过15块。如果没有需另外购买两个普通TT直流减速电机和轮子。…

基于yolov8的102种昆虫检测系统python源码+onnx模型+评估指标曲线+精美GUI界面

【算法介绍】 基于YOLOv8的102种昆虫检测系统是一款高效、准确的昆虫识别工具&#xff0c;它利用YOLOv8这一先进的目标检测算法&#xff0c;实现了对102种不同昆虫的实时检测与识别。该系统在农业、生态研究、生物多样性保护等多个领域具有广泛的应用价值。 YOLOv8算法以其高…

HTML沙漏爱心

目录 写在前面 完整代码 下载代码 代码分析 系列文章 写在最后 写在前面 教你用HTML语言实现炫酷的沙漏爱心,该代码不仅可以用电脑运行,手机、平板也可以直接运行哦。 完整代码 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><…

【Linux】:文件IO

目录 1.C文件接口 1.1 当前路径是什么&#xff1f; 1.2 "w"和"a"​编辑 2.系统文件I/O 2.1 "比特宏"标识符的实现: 2.2 open 1.系统默认创建文件的权限只写 2.设置新建文件的权限 3. 覆盖写/清空写/追加写 3.访问文件的本质 3.1 文件…

茴香豆Web实践

茴香豆 是由书生浦语团队开发的一款开源、专门针对国内企业级使用场景设计并优化的知识问答工具。 茴香豆特点&#xff1a; 三阶段 Pipeline &#xff08;前处理、拒答、响应&#xff09;&#xff0c;提高相应准确率和安全性 打通微信和飞书群聊天&#xff0c;适合国内知识问…

提高工作效益方法(一)

目录 如何提高工作效率? 如何提高工作效率?&#xff08;每日工作安排&#xff09; 怎么在职场做好时间管理&#xff1f; 如何提高工作效率? 提高工作效率的关键在于采用一系列策略和方法&#xff0c;以确保工作能够高效、有序地进行。通过这些方法&#xff0c;可以有效地提…

【whisper】使用whisper实现语音转文字

whisper需要ffmpeg支持 官网下载ffmpeg https://www.gyan.dev/ffmpeg/builds/下载完毕后解压放到合适的位置 添加环境变量 在cmd中输入以下 ffmpeg -version出现下面结果代表成功 安装whisper pip install openai-whisper在vscode中运行 测试代码 import whisperif __n…

【c++】cout打印char * 或者char[]的细节详解

目录 char* 类型 1.打印指向的字符串 2.打印指针指向的地址 问题描述 解决方法 char型数组 1. 想要输出字符串 2. 想输出字符数组的地址 printf 和cout 的对比 1.打印首字符 2.打印字符串 3.打印字符串首地址 &#x1f497;感谢阅读&#xff01;&#x1f497; char*…

新火种AI|减脂增肌没捷径?对不起,那是AI 出现以前的事情了...

作者&#xff1a;小岩 编辑&#xff1a;彩云 对于很多人来说&#xff0c;“拥有完美的身材”是人生的重要目标之一&#xff0c;练出好身材的人也会以此为傲&#xff0c;会把自己的好身材po到社交媒体上。换个角度来说&#xff0c;为了让自己社交媒体上的形象足够完美&#xf…

Axure RP下载+详细安装步骤资源百度云盘分享

众所周知&#xff0c;Axure全称“axure rp”&#xff0c;是一款专业的快速原型设计工具。 它能帮助网站需求设计者&#xff0c;快捷而简便的创建基于网站构架图的带注释页面示意图、操作流程图、以及交互设计&#xff0c;并可自动生成用于演示的网页文件和规格文件&#xff0c…

小琳python课堂:Python核心概念 类和对象

大家好&#xff0c;这里是小琳python课堂&#xff01;今天我们来聊聊Python中的类&#xff08;Class&#xff09;和对象&#xff08;Object&#xff09;&#xff0c;这是面向对象编程&#xff08;OOP&#xff09;的核心概念哦&#xff01;&#x1f31f; 面向对象编程就像是用“…

基于 INFINI Pizza 为 Hugo 静态站点添加搜索功能

INFINI Pizza 是 INFINI Labs 即将发布的一个基于 Rust 编写的搜索引擎&#xff08;即将完全开源&#xff09;&#xff0c;目前已经完成基本的搜索能力&#xff0c;并且基于 INFINI Pizza 的核心引擎&#xff0c;提供了一个 WASM 版本的超轻量级内核&#xff0c;可以很方便的嵌…

MicroNet关键代码解读(Micro-block与Dynamic Shift-Max的实现代码)

论文地址&#xff1a;https://arxiv.org/pdf/2011.12289 中文翻译&#xff1a;https://hpg123.blog.csdn.net/article/details/141772832?spm1001.2014.3001.5502 发表时间&#xff1a;2022 项目地址&#xff1a;https://github.com/liyunsheng13/micronet 在MicroNet论文中提…

查文献技巧,数模国赛必须掌握!

参加数学建模竞赛&#xff0c;拿到题目后第一件事就是去查文献&#xff0c;把题目的背景知识看懂。本文介绍查文献的一些技巧。 先看硕博士论文 硕博论文会对研究的问题有详细的背景和基础知识介绍&#xff0c;可帮助我们快速理解题目。 有个经典段子&#xff1a;学士、硕士…

对字符、字符串的研究

每日一背 C的字符串很特殊 //返回字符 char test2() {return p; } //返回整数 int test2() {return 90; } 其实字符串本就是很特殊的存在。字符型、整数算一类&#xff0c;但是字符串型区别前两个类。整数、字符都返回的是一个值&#xff0c;所以可以直接在主函数里面cout不…

《黑神话:悟空》火出圈儿,揭秘幕后实时渲染技术

游戏一度因被贴上“不务正业”、“虚度光阴”的标签而备受争议&#xff0c;然而随着该产业的蓬勃发展&#xff0c;一些游戏被纳入体育竞技项目&#xff0c;如今游戏领域吸引越来越多人的目光。当下火爆全网的《黑神话&#xff1a;悟空》&#xff0c;凭借炫酷逼真的3D效果和独特…