【JDBC系列】- jdbc的概念以及与数据库的交互流程

news2024/11/25 7:01:51

【JDBC系列】- jdbc的概念以及与数据库的交互流程

😄生命不息,写作不止
🔥 继续踏上学习之路,学之分享笔记
👊 总有一天我也能像各位大佬一样
🏆 博客首页   @怒放吧德德  To记录领地
🌝分享学习心得,欢迎指正,大家一起学习成长!

在这里插入图片描述

文章目录

  • 【JDBC系列】- jdbc的概念以及与数据库的交互流程
    • 引言
    • JDBC的概念
      • 1、jdbc与数据的交互
      • 2、jdbc的一些概念
    • 使用核心API - statement
      • 1、jdbc是如何进行与数据库通信的呢?
      • 2、用代码实现jdbc与数据库通信步骤
        • 准备数据
        • 代码如下
        • 执行结果
    • 详细介绍使用核心API - statement
      • 1、注册驱动
        • 驱动重复注册的解决
      • 2、获取连接
        • 1)、getConnection(String url, String user, String password)
        • 2)、getConnection(String url, java.util.Properties info)
        • 3)、getConnection(String url)
      • 3、创建Statement对象
      • 4、发送SQL语句
      • 5、解析结果集
      • 6、关闭资源
    • 总结

引言

人总是向前走的,目标是更上一层楼。原本笔者奔着一颗炙热的心去学习mybatis底层原理,无奈看了一章感觉我还是太菜了,没有对jdbc有个基础的了解,看起来就比较吃力,因此这次就来学习一下jdbc。本次所学习的大致内容是jdbc的概念与理解,以及如何去使用jdbc来实现Java程序和数据库进行打交道。

JDBC的概念

JDBC(Java Database Connectivity),它是Java编程语言中用于连接和操作数据库的API。JDBC提供了一组类和接口,允许Java应用程序与各种关系型数据库进行通信。它提供了一种标准化的方式来与数据库交互。

1、jdbc与数据的交互

Java程序通过jdbc这个规范(接口)来与第三方数据库厂商进行交互,根据jdbc规范根据具体的实现驱动代码,不同厂商数据库的驱动代码不同,但是方法是相同的。jdbc是一组接口,最终实现是由各个数据库厂商(jar)来实现的,是一种面向接口编程。无论是MySQL、Oracle、SQL Server还是其他关系型数据库系统,只需要切换对应的数据库驱动jar包。

在这里插入图片描述

2、jdbc的一些概念

接下来就了解一些主要的概念,包括驱动、连接、语句、结果集等。

  1. 数据库驱动程序(Database Driver):数据库驱动程序是实现JDBC接口的软件组件,它允许Java应用程序与特定类型的数据库进行通信。不同的数据库供应商提供不同的驱动程序实现。
  2. 连接(Connection):连接是通过JDBC与数据库建立的会话。它表示Java应用程序与数据库之间的通信通道。使用连接,应用程序可以执行SQL语句并获取结果。
  3. 语句(Statement):语句是在数据库上执行的SQL命令。JDBC提供了多种语句类型,包括普通语句(Statement)、预编译语句(PreparedStatement)和可调用语句(CallableStatement)等。应用程序可以使用这些语句来执行查询、更新、插入和删除等操作。
  4. 结果集(ResultSet):结果集是从数据库检索到的数据集合。它是通过执行查询语句获得的,并且提供了一种迭代的方式来遍历和访问结果。
  5. 批处理(Batch Processing):JDBC支持批处理操作,它允许一次执行多个SQL语句。这对于批量插入、更新或删除数据非常有用,可以提高性能和效率。
  6. 事务(Transaction):事务是一组数据库操作,它们要么全部成功执行,要么全部回滚(撤销)。JDBC支持事务管理,可以通过开始事务、提交事务或回滚事务来确保数据的一致性和完整性。

使用核心API - statement

在JDBC中,statement(语句)是用于执行SQL命令的接口之一。它用于执行静态SQL语句[1],即在编译时已经确定的SQL语句,不允许参数化。

[1] 静态SQL语句是在编译时已经确定的SQL语句,其结构和内容在程序运行时不会改变。它是指那些SQL查询或数据操作语句的文本内容在编译时就已经确定,并且不需要在运行时进行参数化或动态修改的语句。

1、jdbc是如何进行与数据库通信的呢?

jdbc是Java程序与数据库交互的一个桥梁,完成通信需要通过六个步骤:

①、加载驱动程序,需要加载适用于特定数据库的驱动程序,本次是使用mysql8.0,所以需要加载mysql-connector-java-8.0.27.jar包。
②、建立连接,通过驱动去建立连接,可以理解为这样就会有一条与数据库服务器交互的管道。实际上就是使用数据库连接URL指定数据库的地址、端口和其他连接参数,通过TCP/IP协议建立与数据库服务器的连接。
③、创建Statement或PreparedStatement对象,这个对象是存储sql语句,可以理解为是一个搭载sql语句的盒子,需要被送到数据库服务器中执行。
④、执行SQL语句,需要将statement对象通过连接通道送到数据库服务器执行sql语句并且返回结果集。
⑤、处理结果,将返回的结果集resultSet进行解析处理。
⑥、关闭资源,使用完Statement、PreparedStatement、ResultSet和连接等资源后,需要调用它们的close()方法来关闭资源。关闭资源可以释放数据库连接和相关的系统资源。
在这里插入图片描述

以上这张图简单的画出了jdbc与数据库通信的流程步骤。

2、用代码实现jdbc与数据库通信步骤

接下来就简单使用一个demo来实现以上jdbc与数据的通信步骤,主要是通过驱动管理器DriverManager来注册驱动和建立连接,在建立连接的时候需要传入数据库服务器url和用户名、密码、数据库信息,与navicat的连接是差不多的,只是使用java代码来实现,然后创建statement对象去执行sql语句,并且能获得一个ResultSet对象的结果集,里面有next()方法用来移动游标输出数据,当开始是指向第一行数据之前,next()将游标往下移动一行,接着通过getString(columnLabel)等方法获取每行的列数据。

准备数据

需要准备数据库,这里用一张tb_user的表来做测试,里面就只有id、name、address三个字段。
在这里插入图片描述

代码如下

package cn.lyd.jdbc;
import com.mysql.cj.jdbc.Driver;
import java.sql.*;
/**
 * @Author: lyd
 * @Description: Jdbc - statement使用
 * @Date: 2023/7/15
 */
public class JdbcDemo {
    /**
     * DriverManager
     * Connection
     * Statement
     * ResultSet
     * @param args
     */
    public static void main(String[] args) throws SQLException {
        // 1、注册驱动
        /**
         * 注册驱动,如果是8.0+就使用com.mysql.cj.jdbc.Driver
         */
        DriverManager.registerDriver(new Driver());
        // 2、获取连接
        /**
         * 连接数据库需要填入数据库ip地址,端口号,用户名,密码,连接的数据库名称
         */
        Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/cloud_user", "root", "12356");

        // 3、创建statement
        Statement statement = connection.createStatement();

        // 4、发送sql语句并执行
        String sql = "select * from tb_user;";
        ResultSet resultSet = statement.executeQuery(sql);
        // 5、解析结果集
        /**
         * 有没有下行数据
         */
        while (resultSet.next()) { // 最开始指定的是数据的上一行即起始位置,并无数据,.next方法会将游标往下移动一行。
            long id = resultSet.getLong("id");
            String username = resultSet.getString("username");
            String address = resultSet.getString("address");
            System.out.println(id + " - " + username + " - " + address);
        }

        // 6、关闭资源
        resultSet.close();
        statement.close();
        connection.close();
    }
}

执行结果

通过控制台输出获取得到的数据
在这里插入图片描述

详细介绍使用核心API - statement

接下来详细介绍以下流程步骤中的一些小问题与小细节。

1、注册驱动

注册驱动,可以通过驱动管理(DriverManager)的 DriverManager.registerDriver(new Driver());方法来实现。这样的注册驱动就会出现驱动被注册了两次,我们看一下DriverManager.registerDriver()方法内容

public static synchronized void registerDriver(java.sql.Driver driver)
    throws SQLException {

    registerDriver(driver, null);
}

再看一下new Driver()的时候,在Driver.class里面的静态代码块也是会注册一次驱动。

public class Driver extends NonRegisteringDriver implements java.sql.Driver {
    public Driver() throws SQLException {
    }

    static {
        try {
            DriverManager.registerDriver(new Driver());
        } catch (SQLException var1) {
            throw new RuntimeException("Can't register driver!");
        }
    }
}

对于这个问题,我们只要让Driver的静态代码块执行就行了。这里我们就要先了解以下静态代码块是何时触发的呢?

静态代码块的执行时期:

类的加载机制:在类的加载的时候会执行静态代码块。简单的介绍一下步骤:

​ 1、加载(Loading):将类的字节码文件加载到内存中。

​ 2、链接(Linking):链接又分了三个阶段,验证(Verification):对加载的字节码进行验证,确保其符合Java虚拟机规范,不会造成安全或运行时错误;准备(Preparation):为类的静态变量分配内存空间,并设置默认初始值;解析(Resolution):将符号引用(Symbolic References)解析为直接引用(Direct References),即将类、方法、字段等符号引用解析为内存中的实际数据。

​ 3、初始化(Initialization):对类进行初始化,包括静态变量的赋值和静态代码块的执行。

触发类加载:

​ 1、通过new关键字;2、调用了静态方法;3、调用了静态属性;4、jdk1.8的接口加上了default关键字;5、反射;6、子类触发父类;7、程序的入口main。

驱动重复注册的解决

显然我们就不能直接使用DriverManager.registerDriver(new Driver()); 来直接注册驱动,我们如果想不使它重复注册,可以让他只是执行一次静态代码块直接new Driver() ,当然这样做的也有弊端,如果我们使用的不是mysql我们就要导入对应的包,就显得不太灵活。
在这里插入图片描述

换种方式,我们可以使用反射的机制来实现。当使用不同的数据库,就只要更换一下驱动的全类名,这个字符串是可以提出来作为一种可配置的参数,这样就比较灵活了。

Class.forName("com.mysql.cj.jdbc.Driver");

2、获取连接

我们可以看到DriverManager.getconnection()重载了三个方法。三个方法的效果是一样的,只是携带的参数写法并不相同。
在这里插入图片描述

1)、getConnection(String url, String user, String password)

我们需要将数据库服务器的地址,用户名,密码传入就能建立连接。用户名和密码没什么可说的,就是登录凭证。就是这个url地址,这个地址的组成是:

jdbc:数据库管理软件名称://ip地址|主机名:port端口号/数据库?key=value&key=value,后面是可选参数。
如果是localhost:3306可以替换成  jdbc:数据库管理软件名称:///数据库

这个方法实现,传进来的用户名密码,最后也是放到了java.util.Properties这个对象之中。

@CallerSensitive
public static Connection getConnection(String url,
    String user, String password) throws SQLException {
    java.util.Properties info = new java.util.Properties();

    if (user != null) {
        info.put("user", user);
    }
    if (password != null) {
        info.put("password", password);
    }

    return (getConnection(url, info, Reflection.getCallerClass()));
}

2)、getConnection(String url, java.util.Properties info)

这个方法与上一个不一样的是,将用户和密码在调用的时候直接放入java.util.Properties这个对象之中,

Properties properties = new Properties();
properties.put("user", "root");
properties.put("password", "root");
DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/cloud_user", properties);

3)、getConnection(String url)

这个方法就是把所有的需要的参数都放在这个url里头了,其组成如下:

jdbc:数据库管理软件名称://ip地址|主机名:port端口号/数据库?user=value&password=value

3、创建Statement对象

通过连接connection去创建,就能够获得一个statement对象。并且需要一条sql语句的字符串。

Statement statement = connection.createStatement();

4、发送SQL语句

String sql = "SELECT * FROM tb_user WHERE username = 'lyd';";
int i = statement.executeUpdate(sql);
ResultSet resultSet = statement.executeQuery(sql);

当使用的是executeUpdate就会返回一个int数值,使用executeQuery将会返回一个结果集。

我们需要根据不用的SQL类型去使用对应的方法,在statement接口中已经标明了注释。

使用executeQuery:如果发送的sql语句是静态sql SELECT语句,返回的结果就是包含给定查询产生的数据的ResultSet对象,如果是没有数据,那就返回为null。

使用executeUpdate:如果语句是SQL数据操作语言(DML)语句,(INSERT、UPDATE或DELETE);或者是不返回任何结果的SQL语句,比如DDL语句。返回的结果就是数据操作语言(DML)语句的行数,没有就是返回0。

在这里插入图片描述

学习一下SQL主要的分类:

  • 数据定义语言(Data Definition Language,DDL):DDL用于创建和管理数据库对象,如表、视图、索引等。常见的DDL语句包括CREATE(创建)、ALTER(修改)、DROP(删除)等。

  • 数据操作语言(Data Manipulation Language,DML):DML用于查询和操作数据库中的数据记录。它包括SELECT(查询)、INSERT(插入)、UPDATE(更新)、DELETE(删除)等语句,用于从数据库中检索、插入、更新和删除数据。

  • 数据控制语言(Data Control Language,DCL):DCL用于管理数据库的访问权限和安全性。它包括GRANT(授权)和REVOKE(撤销授权)等语句,用于控制用户对数据库对象的访问权限。

  • 事务控制语言(Transaction Control Language,TCL):TCL用于控制数据库中的事务处理。它包括BEGIN TRANSACTION(开始事务)、COMMIT(提交事务)、ROLLBACK(回滚事务)等语句,用于确保数据库操作的原子性、一致性、隔离性和持久性。

  • 除了上述常见的分类,SQL还可以根据具体的数据库系统和实现方式进行进一步分类,如存储过程语言(Stored Procedure Language)、游标语言(Cursor Language)等。每种类型的SQL语句都有其特定的语法和功能,开发人员可以根据需要选择合适的语句来进行数据库操作。

5、解析结果集

当查询找到了所需要的数据,就会将找到的数据封装到ResultSet对象,结果集ResultSet对象维护一个指向其当前数据行的游标。最初,游标位于第一行之前。next方法将光标移动到下一行,因为当ResultSet对象中没有更多的行时,它返回false,所以可以在while循环中使用它来遍历结果集。

我们通过断点可以看到,刚开始结果集指向的当前行是-1,代表是具体数据的上一行。
在这里插入图片描述

我们通过while循环去遍历数据,并且使用next将游标移动到下行,如果有数据,此时结果集就指向了数据行。

通过 resultSet.getLong(columnIndex|columnLabel) 来获取对应类型的数据,这个get属性可以使用两种方式来获取:

①、通过列数据的下标,这个下标是从1开始。

②、通过列标签,这里的列标签可以是列名也可以是别名,当sql语句中使用了AS 给字段取别名时,这就需要使用别名了。

while (resultSet.next()) {
    long aLong = resultSet.getLong(1);
    String username = resultSet.getString("username");

    System.out.println("id: " + aLong + ", username: " + username);
}

6、关闭资源

当使用完之后就需要将资源进行销毁

// 6、关闭资源
resultSet.close();
statement.close();
connection.close();

总结

使用jdbc与数据库进行通信,简单来说就只有6个步骤,首先需要注册驱动,获取连接,接着创建statement对象,用来存放sql语句并且执行,然后将获得到的数据进行解析,最后就是要把资源进行销毁。这里只是基本的使用jdbc,像mybatis、jpa、ibatis等持久层框架,都是对jdbc进行封装,万变不离其宗,想要学习底层知识,就需要把这学基础知识给学好!

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

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

相关文章

oc UITableView 列表

// // ViewController.m // OcDemoTest // // Created by Mac on 2023/7/14. //#import "ViewController.h" // 添加协议 interface ViewController ()<UITableViewDataSource> property (weak, nonatomic) IBOutlet UITableView *tableView;endimplementat…

Node中的的util.promisify()方法的介绍和基本实现

异步编程解决方案 我们知道&#xff0c;在JS中实现异步编程主要是通过以下几种方案&#xff1a; 回调函数&#xff1a;也是在ES6之前用的最多的方式&#xff0c;缺点是容易造成callback hell&#xff0c;可读性很差观察者模式&#xff1a;在NodeJS中的很多模块都继承了EventE…

二分搜索树节点删除

本小节介绍二分搜索树节点的删除之前&#xff0c;先介绍如何查找最小值和最大值&#xff0c;以及删除最小值和最大值。 以最小值为例&#xff08;最大值同理&#xff09;&#xff1a; 查找最小 key 值代码逻辑&#xff0c;往左子节点递归查找下去&#xff1a; ... // 返回以…

3.4 Bootstrap 按钮下拉菜单

文章目录 Bootstrap 按钮下拉菜单分割的按钮下拉菜单按钮下拉菜单的大小按钮上拉菜单 Bootstrap 按钮下拉菜单 本章将讲解如何使用 Bootstrap class 向按钮添加下拉菜单。如需向按钮添加下拉菜单&#xff0c;只需要简单地在在一个 .btn-group 中放置按钮和下拉菜单即可。您也可…

❤️创意网页:如何用HTML制作菜单栏?制作好看的菜单栏样式网页

✨博主&#xff1a;命运之光 &#x1f338;专栏&#xff1a;Python星辰秘典 &#x1f433;专栏&#xff1a;web开发&#xff08;简单好用又好看&#xff09; ❤️专栏&#xff1a;Java经典程序设计 ☀️博主的其他文章&#xff1a;点击进入博主的主页 前言&#xff1a;欢迎踏入…

ChatGPT流量下降?原因竟是学生放暑假,秋季或将回暖

ChatGPT是一款由OpenAI开发的人工智能聊天机器人&#xff0c;它能够进行自然语言对话&#xff0c;并支持用户在写作业、进行研究等方面提供帮助。许多人认为它是历史上增长最快的科技产品之一&#xff0c;但近期却观察到其流量下降的现象。 根据Similarweb和其他机构在本月初发…

el-image-viewer图片预览组件使用

只需要安装了element-plus即可使用 <template><div class"preview-box"><!-- 第一种: 使用el-image - 通过点击小图, 然后预览大图, 这是官方文档提供的方法 --><el-image :preview-src-list"[/api/file/getImage/202307/3178033358P0KiZ…

基于Javaweb实现ATM机系统开发实战(十三)交易记录查看实现

老规矩&#xff0c;先看前端传递怎样的数据&#xff0c;已经把要展示数据的变量名都改了&#xff1a; <% page language"java" contentType"text/html; charsetUTF-8" pageEncoding"UTF-8"%> <% taglib prefix"c" uri"…

7、网络层(地址管理和路由选择)IP31

网络层&#xff1a;负责地址管理和路由选择 IP协议&#xff0c;路由器 一、IP协议 4位协议版本号&#xff1a;4/6 -ipv4、ipv6 4位报头长度&#xff1a;以4B为单位描述报头大小&#xff0c;IP报头最大60B最小20B 8位服务类型&#xff1a;3位优先权字段弃用&#xff0c;1位保留…

Circular lollipop | 哇咔咔!!!环形棒棒糖图好吃又好玩!~

1写在前面 今天不想废话了&#xff0c;直接看图吧。&#x1f447; 复现代码step by step&#xff0c;自己看吧。&#x1f92a; 2用到的包 rm(list ls())library(tidyverse)library(ggtext)library(patchwork) 3示例数据 df_pw <- read.csv("./passwords.csv",row…

浅析 Io 处理

文件流&#xff1a; 在Java 中&#xff0c;文件流负责操作文件&#xff0c;包括读取和写入&#xff1b; FileInputStream // 文件的字节输入流&#xff1b; FileOutputStream // 文件的字节输出流&#xff1b; FileReader // 文件的字符输入流&#xff1b; FileWriter // 文…

Python基于百度智能云平台股票资讯情感分析

Python基于百度智能云平台股票资讯情感分析 全部代码和数据地址如下&#xff1a;Python基于百度智能云平台股票资讯情感分析 本文章详细内容如下&#xff1a; 文章目录 Python基于百度智能云平台股票资讯情感分析导入相应的包1.引入库2.设置账户秘钥3.导入数据4.数据合并5.百度…

10年测试老鸟总结,性能测试-性能内存瓶颈分析(超详细)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 性能测试-内存瓶颈…

【2023 年第三届长三角高校数学建模竞赛】B 题 长三角新能源汽车发展与双碳关系研究 18页论文、数据和代码

【2023 年第三届长三角高校数学建模竞赛】B 题 长三角新能源汽车发展与双碳关系研究 18页论文、数据和代码 1 题目 《节能与新能源汽车技术路线图 2.0》提出至 2035 年&#xff0c;新能源汽车市场占比超过 50%&#xff0c;燃料电池汽车保有量达到 100 万辆&#xff0c;节能汽车…

windows11 安装cuda和cudnn深度学习开发环境

首先先要确认自己的显卡最高能支持到cuda的版本&#xff0c;一般是不限制版本号的。 然后在官网地址下载&#xff1a; cuDNN的官网下载地址&#xff1a;cuDNN Archive | NVIDIA Developer CUDA 的下载地址&#xff1a;CUDA Toolkit Archive | NVIDIA Developer 有一点需要注…

Jetpack:DataBinding

目录 一、DataBinding简介 设置 Data Binding 数据绑定表达式 双向绑定 二、例子 MainActivity &#xff1a; Food: activity_main: build.gradle: 运行结果&#xff1a; 三、总结 一、DataBinding简介 DataBinding 是一种用于在安卓应用中实现简洁、高效的数据绑定的…

SpringMVC中的@RequestMapping注解的详细介绍过程~

RequestMapping注解的功能&#xff1a; 从注解名称上我们可以看出&#xff0c;RequestMapping注解的作用就是将请求和处理请求的控制器方法关联起来&#xff0c;建立映射关系&#xff0c;SpringMVC接收到指定的请求&#xff0c;就会来找到在映射关系中对应的控制方法来处理这个…

备战秋招 | 笔试强训7

目录 一、选择题 二、编程题 三、选择题题解 四、编程题题解 一、选择题 1、在&#xff08;&#xff09;情况下适宜采用 inline 定义内联函数 A. 函数体含有循环语句 B. 函数体含有递归语句 C. 函数代码少、频繁调用 D. 函数代码多&#xff0c;不常调用 2、在 C 语言中&a…

数据结构(王道)——队列的应用

对树的层次遍历&#xff1a; 图的广度优先遍历 队列在操作系统的应用

composer的劈坑

现在是php8盛行的天下&#xff0c;安装php8我就不多说了&#xff0c;宝塔、小出面板一大堆&#xff0c;一键安装。真心说方便。&#xff08;好吧&#xff0c;不打广告了&#xff09;&#xff0c;以下是针对 linux 系统 1、安装composer 安装composer之前&#xff0c;需要要先在…