JDBC从入门到精通-笔记(一):JDBC基本概念与开发基础

news2024/11/16 19:46:26

  视频资源:JDBC从入门到精通视频教程-JDBC实战精讲_哔哩哔哩_bilibili

JDBC定义与本质

概念

什么是JDBC:Java DataBase Connectivity

JDBC本质:SUN公司制定的一套接口(interface),java.sql.*。

                    面向接口调用,面向接口写实现类,都属于面向接口编程

                    接口相当于一种协议,调用者和使用者一般要遵守同一个接口的规则。

                    面向接口编程好处:解耦合-降低程序耦合度,提高程序扩展力。

                    多态机制是典型的面向抽象编程,使用时一般用父类引用对象,但调用子类方法。

                

JDBC接口的意义

为什么需要制定JDBC接口:因为每一个数据库的底层实现原理都不一样,如果没有接口,每连接一个新的数据库,都需要不同的代码实现。

数据库厂家编写JDBC接口的实现类,生成一组class文件,这组class文件称为驱动。所有的数据库驱动都是以jar包的形式存在,不是SUN公司提供,而是由各大数据库厂家提供,需要去各家官网下载。

数据库厂家编写JDBC接口的实现类,程序员调用这些类即可。

模拟JDBC本质

SUN公司 

/*
  SUN公司
*/
public interface JDBC {
    
    void getConnection(){}

}

 数据库厂家

        MySQL 

/*
    MySQL数据库厂家负责实现JDBC实现类
*/

public class MySQL implements JDBC {

    public void getConnection() {
        // 具体由MySQL实现
        System.out.println("连接MySQL数据库成功");
    }
}
// 实现类为MySQL驱动

        Oracle 

/*
    Oracle数据库厂家负责实现JDBC实现类
*/

public class Oracle implements JDBC {

    public void getConnection() {
        // 具体由Oracle实现
        System.out.println("连接Oracle数据库成功");
    }
}
// 实现类为Oracle驱动

 Java程序员

/*
    Java程序员
    只需要面向JDBC写代码,不用在意数据库是哪个品牌
*/
public class JavaProgrammer {
    public void static main(String[] args) throws Exception{
        // JDBC jdbc = new MySQL();
        // JDBC jdbc = new Oracle();
        // 通过反射创建对象
        Class c = Class.forName("Oracle");
        JDBC jdbc = (JDBC) c.newInstance();
        // 以下代码都是面向接口调用,不用修改
        jdbc.getConnection();
    }
}

 用反射机制就可以把数据库信息放在配置文件中,分离数据。

jdbc.properties

className = Oracle

然后调用

/*
    Java程序员
    只需要面向JDBC写代码,不用在意数据库是哪个品牌
*/
import java.util.*;

public class JavaProgrammer {
    public void static main(String[] args) throws Exception{
        // JDBC jdbc = new MySQL();
        // JDBC jdbc = new Oracle();
        // 通过反射创建对象
        // Class c = Class.forName("Oracle");
        ResourceBundle bundle = ResourceBundle.getBundle("jdbc");
        String className = bundle.getString("className");
        JDBC jdbc = (JDBC) c.newInstance();
        // 以下代码都是面向接口调用,不用修改
        jdbc.getConnection();
    }
}

这样,以后只要改配置文件就可以运行连接。

运行JavaProgrammer

java JavaProgrammer
> 连接Oracle数据库成功

 如果没有驱动的class文件直接运行,虽然编译能通过,但会报找不到类的错误,因为底层的实现类不存在。驱动非常重要。

使用JDBC进行开发

准备工作

从官网下载对应的驱动jar包,然后将其配置到环境变量中。

编程六步曲

  1. 注册驱动:告诉Java程序即将要连接的数据库是哪个
  2. 获取连接:表示JVM进程与数据库进程的通道打开,属于进程间通信,使用完后要关闭
  3. 获取数据库操作对象(执行sql语句的对象)
  4. 执行SQL语句:DQL DML
  5. 处理查询结果集:执行select语句后处理
  6. 释放资源:用完资源后一定要关闭资源

参考Java API 文档 - java.sql:Java Platform SE 8

注册驱动

        方法一:registerDriver(Driver driver) in class DriverManager

        注意点:

  • registerDriver是静态方法,可以直接用类名调用
  • 调用registerDriver时,其参数类型为Driver,但是在java.sql中,Driver只是一个接口,因此调用时必须使用对应驱动的实现类
  • 注意registerDriver可能存在异常,因此需要做异常处理。由于SqlException继承Exception,是受检异常,适合用try catch处理

public static void main(String[] args) {
        try {
            // 1、注册驱动
            Driver driver = new com.mysql.jdbc.Driver();// 多态,父类型引用指向子类型
            DriverManager.registerDriver(driver); // 不能直接new Driver,因为Driver是接口,需要new的Driver是实现类中的Driver
            // 2、获取数据库连接
            // 3、获取数据库操作对象
            // 4、执行sql
            // 5、处理查询结果集
            // 6、释放资源
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

        方法二:注意mysql的Driver实现类中,有静态代码块,会在类加载的时候执行一次。

 因此可以用反射机制调用该方法,方便将数据库驱动写到配置文件中去,此方法不需要接收返回值,更常用。

// 1、注册驱动
            // DriverManager.registerDriver(new com.mysql.cj.jdbc.Driver());
            Class.forName("com.mysql.jdbc.Driver"); 

获取数据库连接

         方法:getConnection(String url, String user, String password) in DriverManager

        注意点:

  • getConnection为静态方法,可以直接用类名调用
  • url是数据库地址,由 协议:// ip地址:端口号/数据库名称   组成
    • url拓展:url是统一资源定位符,其中通信协议表示规定好的数据传输格式,ip地址表示计算机地址,端口号表示app代号,资源名表示要访问的资源是什么。

  • 如果不是用mysql而是oracle数据库,其格式为jdbc:oracle:thin:@127.0.0.1:1521/数据库名称,相应的,调用时Driver也需要指向oracle的driver实现类。其余也是类似的,都有指定的协议,资源
  • 返回的数据库对象com.mysql.cj.jdbc.JDBC4Connection@xxxxx中,@之前的表示类名。实际使用发现com.mysql.jdbc.Driver已经过时,被com.mysql.cj.jdbc.Driver替代,所以得到的返回对象类名是com.mysql.jdbc.ConnectionImpl。
// 2、获取数据库连接
            String url = "jdbc:mysql://127.0.0.1:3306";
            String user = "root";
            String password = "333";
            Connection connection = DriverManager.getConnection(url, user, password);// 此时connection指向的是子类对象
            System.out.println("数据库连接对象:" + connection); // 返回数据库连接对象:com.mysql.cj.jdbc.ConnectionImpl@xxxxx

获取数据库操作对象

        方法:createStatement() in Connection

// 3、获取数据库操作对象
       Statement statement= connection.createStatement();

执行sql

        如果是增删改语句,使用Statement类中的executeUpdate(String sql)方法 

        JDBC中的sql语句不用写分号

// 4、执行sql
            // String sql = "select * from tableA";
            // 专门执行DML语句 - insert, update, delete
            // 返回值为影响数据库中的记录条数
            String sql = "insert into tableA ('USER_ACCOUNT', 'TEAM') VALUES ('abc@mail.com', 'IT')";
            int count = statement.executeUpdate(sql);

        如果是查询语句,使用Statement类中的executeQuery(String sql)方法,并把结果存储到ResultSet类中,保存结果集

//4、执行sql
            String sql = "select * from tableA";
            // int executeUpdate(delete/insert/update)
            // ResultSet executeQuery(select)
            set = statement.executeQuery(sql); // executeQuery专门用于处理查询语句

处理结果集

         ResultSet中存在方法next(),是用于遍历结果集的迭代器,返回bool值。如果存在数据返回true,否则返回false。

 用rs.next()取出一行数据后,还需要通过rs中的get方法取出具体字段的value。

get方法有:getString(), getInt(),getDate()等。

getString()方法取出的数据无论在数据库是什么类型,返回的就是String类型。取数据时,可以通过列的下标(下标从1开始),也可以通过列名。推荐用列名,因为下标可能因为取顺序的数据发生改变。如果查询的时候对列名重命名了,必须用新的列名获取数据,否则会返回列不存在的错误。

getInt(),getDate()等方法不能随便使用,必须是数据库的底层数据类型与之相同的时候,才能正确执行,否则会返回数据类型无法转换的错误。

            //4、执行sql
            String sql = "select id, name a, salary b from tableA";
            // int executeUpdate(delete/insert/update)
            // ResultSet executeQuery(select)
            rs = statement.executeQuery(sql); // executeQuery专门用于处理查询语句
            //5、处理结果集
            while (rs.next()) {
                // getString()方法:不管数据库数据类型是什么,都以String类型返回
//                String flow = rs.getString(2); // jdbc中所有下标从1开始, 2表示第二列
//                String scenario = rs.getString(3); // 第三列
                // 以查询结果的列名获取(因为查询结果可以给列名重命名)
                // 除了getString, 还可以用getInt, getDate等特定类型取出数据,但必须与数据库中的数据类型对应
                int id = rs.getInt("id");
                String name = rs.getString("a");
                String salary = rs.getDouble("b");
                System.out.println("id: " + (id+200) + " - name is '" + name + "' with salary '" + salry+ "'");
                // 返回 id: 1 - name is 'Jack' with salary '5000'

关闭资源

        写在finally中,需要释放的资源提前定义,否则finally中无法调用。 

        如果是查询语句,需要先关闭ResultSet。

public static void main(String[] args) {
        Connection connection = null;
        Statement statement = null;
        ResultSet rs = null;
        try {
            /*
            precondition
            */
            connection = DriverManager.getConnection(url, user, password);// 此时connection指向的是子类对象
            System.out.println("数据库连接对象:" + connection);
            // 3、获取数据库操作对象
            statement= connection.createStatement();
            // 4、执行sql
            // do sth
            // 5、处理查询结果集
            // do sth
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            // 6、释放资源
            // 在finally中释放资源,从小到大关闭,关闭时分别对其try catch
            // 为了能关闭资源,定义的时候就要把需要释放的资源放在try外面定义
            try {
                if (rs != null) {
                    rs.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                if (statement != null) {
                    statement.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                if (connection != null) {
                    connection.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

 将连接信息放入配置文件中

jdbc.properties

driver = com.mysql.cj.jdbc.Driver
url = jdbc:mysql://127.0.0.1:3306/xxx
user = root
password = 333

用ResourceBundle调用数据 

package JDBCTest;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ResourceBundle;

// 将连接数据库的所有信息放到配置文件中
/*
实际开发不建议把连接数据库信息写死到程序中
 */
public class JDBCTest04 {
    public static void main(String[] args) {
        // 使用资源绑定器绑定配置文件
        ResourceBundle bundle = ResourceBundle.getBundle("jdbc");
        String driver = bundle.getString("driver");
        String url = bundle.getString("url");
        String user = bundle.getString("user");
        String password = bundle.getString("password");
        Connection connection = null;
        Statement statement = null;
        try {
            // 1、注册驱动
            Class.forName(driver);
            // 2、获取数据库连接
            connection = DriverManager.getConnection(url, user, password);
            System.out.println("数据库连接对象:" + connection);
            // 3、获取数据库操作对象
            statement= connection.createStatement();
            // 4、执行sql
            // 专门执行DML语句 - insert, update, delete
            // 返回值为影响数据库中的记录条数
            String sql = "delete from users where id = '200'";
            // String sql = "update users set TEAM = 'a' where id = '200'";
            int count = statement.executeUpdate(sql);
            System.out.println(count == 1 ? "删除成功":"删除失败");
            // 5、处理查询结果集

        } catch (SQLException | ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            // 6、释放资源
            // 在finally中释放资源,从小到大关闭,关闭时分别对其try catch
            // 为了能关闭资源,定义的时候就要把需要释放的资源放在try外面定义
            try {
                if (statement != null) {
                    statement.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                if (connection != null) {
                    connection.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

但实际开发不建议把连接数据库信息写死到程序中,用户体验很差。

注意:properties文件不能放错位置,否则会出现"Can't find bundle for base name jdbc, locale en_US" 的错误。要确保 jdbc.properties 文件位于类路径下。如果是标准的 Java 项目,将.properties 文件放在 src 目录下。对于 Maven 项目,应该放在 src/main/resources 目录下。

使用IDEA进行JDBC配置

新建Project后,File->Project Structure->Project Settings->Libraries

点击加号, 添加Java,选择数据库的jar包

 选择要导入的模块,如果有其他新模块新建的话,需要再导入一次。否则运行时会报类找不到错误。

然后就能在External libraries里看到了

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

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

相关文章

【progressBar-js】优雅的 前端进度条 构建!

progressBar-js JS 前端进度条小工具 您可以通过此工具来构建一个有效的工具条&#xff0c;接下来就是一个示例&#xff01; 使用示例 引入 progressBar-js 库 直接在这里将 css 和 js 文件引入进来就算是成功导入了哦&#xff01;&#xff01;&#xff01; <link href&…

SVN学习(001 svn安装)

尚硅谷SVN高级教程(svn操作详解) 总时长 4:53:00 共72P 此文章包含第1p-第p19的内容 介绍 为什么使用版本控制工具 版本控制工具的功能 版本控制简介 客户端服务器结构 c/s结构 服务端的结构&#xff1a; 服务程序 、版本库(存放我们上传的文件) 客户端的三个基本操作&#…

高考填报志愿,选专业和选学校,哪个优先?

一、 专业优先&#xff0c;还是学校优先&#xff1f; 专业和学校都非常重要&#xff0c;好的学校可以给你提供较高的学习平台&#xff0c;好的专业能够给将来的职业生涯提供便利。高考报考&#xff0c;每一个学校的每一个专业的分数都会不同&#xff0c;热门的专业分数较高&am…

Swift 周报 第五十三期

文章目录 前言新闻和社区苹果公司取得基于波束组合的信道状态信息&#xff08;CSI&#xff09;反馈专利&#xff0c;为 5G 网络中的信道状态信息&#xff08;CSI&#xff09;报告提供新方案关于在欧盟分发 App 的最新信息公司快评&#xff5c;新广告引发不满&#xff0c;苹果也…

大模型揭秘:AI与CatGPT在实体识别中的创新应用

摘要 尽管大规模语言模型 (LLM) 在各种 NLP 任务上已经取得了 SOTA 性能&#xff0c;但它在 NER 上的性能仍然明显低于监督基线。这是由于 NER 和 LLMs 这两个任务之间的差距&#xff1a;前者本质上是序列标记任务&#xff0c;而后者是文本生成模型。在本文中&#xff0c;我们…

被年轻人买爆的转运能量石,戴一天竟等于拍千次胸片?

离谱的事年年有&#xff0c;这几年可以说非常多&#xff01;‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍ 尤其是这届年轻人&#xff0c;不知道什么时候开始&#xff0c;越来越迷信了&#xff01; 比如去年很…

基于在校学习平台MOOC的选课推荐系统

基于在校学习平台MOOC的选课推荐系统 1、效果 在线demo&#xff0c;点我查看 2、功能 根据学生于在校学习平台MOOC学习期间的选课记录等相关特征来对学生进行课程推荐。 采用数据挖掘技术&#xff0c;包括BPR、FM、CF&#xff0c;神经网络推荐&#xff0c;用户协同过滤推荐…

2024 CISCN 华东北分区赛-Ahisec

Ahisec战队 WEB python-1 break 源码如下&#xff1a; # -*- coding: UTF-8 -*-from flask import Flask, request,render_template,render_template_stringapp Flask(__name__)def blacklist(name):blacklists ["print","cat","flag",&q…

【嵌入式Linux】<总览> 多进程(更新中)

文章目录 前言 一、进程的概念与结构 1. 相关概念 2. 内核区中的进程结构 3. 进程的状态 4. 获取进程ID函数 二、进程创建 1. fork和vfork函数 2. 额外注意点 3. 构建进程链 4.构建进程扇 三、进程终止 1. C程序的启动过程 2. 进程终止方式 四、特殊的进程 1. 僵…

AppInventor2添加超过10个屏幕会怎样?

之前发过一篇AppInventor2官方翻译文档&#xff0c;建议一个项目不要超过10个屏幕&#xff0c;详见&#xff1a; App Inventor 2 构建多屏幕App的最佳实践 App Inventor 可以轻松地向应用程序添加更多屏幕&#xff0c;但最好也不要添加太多屏幕&#xff0c;因为多个屏幕的应用…

U盘数据恢复全攻略:从原理到实践

一、引言&#xff1a;为何U盘数据恢复至关重要 在信息化时代&#xff0c;U盘作为便携存储设备&#xff0c;广泛应用于各个领域。然而&#xff0c;U盘数据的丢失往往给个人和企业带来极大的困扰。数据丢失的原因多种多样&#xff0c;可能是误删除、格式化、文件系统损坏&#x…

探索约束LLM输出JSON的应用

0、 引言 JSON&#xff08;JavaScript Object Notation&#xff09;因其简洁、易读和易于解析的特性&#xff0c;已成为全球使用最广泛的数据交换格式之一。它能够满足各种数据交换需求&#xff0c;特别是在构建人工智能驱动的应用程序时&#xff0c;工程师们经常需要将大型语…

Jenkins教程-8-上下游关联自动化测试任务构建

上一小节小节我们学习了一下Jenkins自动化测试任务发送测试结果邮件的方法&#xff0c;本小节我们讲解一下Jenkins上下游关联自动化测试任务的构建。 下面我们以一个真实的自动化测试场景来讲解Jenkins如何管理上下游关联任务的触发和构建&#xff0c;比如我们有两个jenkin任务…

基础入门篇 | YOLOv10 项目【训练】【验证】【推理】最简单教程 | YOLOv10必看 | 最新更新,直接打印 FPS,mAP50,75,95

文章目录 训练 --train.py推理 --detect.py验证 --val.py不训练,只查看模型结构/参数量/计算量 --test.pyYOLOv10 是基于 YOLOv8 项目的改进版本,目前已经被 YOLOv8 项目合并,所以两个算法使用方法完全一致~ 今天我给大家展示一种非常方便的使用过程,包含【训练】【验证】…

情绪管理篇:让七情自然流露,不过分压抑也不掺杂极端的想法即可来去自如

情绪管理篇&#xff1a; 人有七情&#xff0c;本属常理&#xff0c;该哭的时候哭、该笑的时候笑、该怒的时候怒、该忧的时候忧 学习圣贤之学&#xff0c;并非让我们像木头人一样&#xff0c;枯木死灰&#xff0c;而要让自己不要被七情所缠缚、被七情所乱心&#xff0c;我们的喜…

QT拖放事件之三:自定义拖放操作-利用QDrag来拖动完成数据的传输

1、运行效果 1)Qt::MoveAction 2)Qt::CopyAction 2、源码 #include "Widget.h" #include "ui_Widget.h" #include "common.h"

JDBC的概念 ,核心API的介绍 , 注册驱动介绍

第一章 JDBC 1、JDBC的概念 目标 能够掌握JDBC的概念能够理解JDBC的作用 讲解 客户端操作MySQL数据库的方式 使用第三方客户端来访问MySQL&#xff1a;SQLyog、Navicat 使用MySQL自带的命令行方式 通过Java来访问MySQL数据库&#xff0c;今天要学习的内容 如何通过Java代…

考研数学|《李林880》正确率多少算合格?

李林880题是针对考研数学三的练习题集&#xff0c;覆盖了考研数学三的主要知识点和题型。如果能够熟练掌握这些题目&#xff0c;意味着对考研数学三的知识点有了较为深入的理解和应用能力。 首先&#xff0c;考研数学三的总分是150分&#xff0c;题型包括单选题、填空题和解答…

Day5 —— 电商日志数据分析项目

项目二 _____&#xff08;电商日志数据分析项目&#xff09; 引言需求分析详细思路统计页面浏览量Map阶段Reduce阶段 日志的ETL操作Map阶段Reduce阶段 统计各个省份的浏览量Map阶段Reduce阶段 具体步骤统计页面浏览量日志的ETL操作统计各个省份的浏览量工具类&#xff08;utils…

鸿蒙HarmonyOS服务卡片实战

引言 在现代开发中&#xff0c;服务卡片是不可或缺的一部分&#xff0c;比如音乐&#xff0c;天气类等应用&#xff0c;官网的介绍中写道&#xff1a;卡片让您便捷地预览服务信息&#xff0c;例如查看天气或日历日程等内容。您可将卡片添加到屏幕上&#xff0c;让这类信息触手…