当前位置: 首页 > news >正文

深入解析:数据库造神计划第二十一天---JDBC编程

 个人主页:寻星探路

作者简介:Java研发方向学习者

个人专栏:、《

⭐️人生格言:没有人生来就会编程,但我生来倔强!!!



目录

一、什么是JDBC

1、JDBC的应用场景

2、JDBC工作原理

二、为什么要使用JDBC

三、使用JDBC

1、创建Maven工程并配置国内镜像

1.1创建Maven工程

1.2配置国内镜像(阿里的)

2、获取MySQL驱动包

3、修改pom.xml⽂件

4、建立数据库连接

5、创建Statement

6、执行SQL语句

7、处理结果集

8、释放资源

四、JDBC常用接口和类

1、DriverManager 和DataSource

2、DriverManager 与DataSource的区别

3、Connection 数据库连接

4、Statement对象

4.1Statement

4.2SQL注入

4.3PreparedStatement

4.4CallableStatement

4.5executeQuery()

4.6executeUpdate()

5、ResultSet结果集

六、示例


一、什么是JDBC

        JDBC(Java Data Base Connectivity,Java数据库连接)是Java程序和数据库之间的桥梁,包含了⼀套Java定义的用于执行SQL语句的接口,使开发者能够编写数据库的程序。JDBC的主要作用是: 与数据库建立连接、发送SQL语句和处理数据库执行结果。

1、JDBC的应用场景

        如果JAVA要访问不同的数据库,那么就需要根据数据库的协议进行代码的开发
        为了解决不同数据的使用场景,JAVA中只定义了用于连接和操作数据的接口--JDBC
        具体的实现由数据库厂商来完成

2、JDBC工作原理

                JDBC工作原理简洁地概括为:加载驱动、建立连接、创建Statement、执行SQL、处理结果和关闭资源。

二、为什么要使用JDBC

• 首先回顾⼀下使用客户端操作数据库的过程,主要分为以下几步:

        a. 连接到数据库服务

        b. 发送SQL语句

        c. 得到返回结果并显示

        d. 关闭连接

对于JAVA程序员来说,只需要调用JDBC定义的方法就可完成数据库的具体操作

• 同样如果使用程序操作数据库也会经历以上几步,⼤家应该可以想到,为实现上述步骤,可以编写相应的代码实现数据库连接,发送SQL语句,处理结果并显示,最后关闭连接。

• 但是不同的数据库对于同⼀个操作不论是协议还是参数都各有不同,如果让程序员自己去实现,那就必须针对不同的数据库进行编码实现,这个工作量和维护成本显然太大。

• Java采取的做法是把以上操作步骤定义了相应的接口,具体的实现交给数据库厂商去做,Java程序员只需要按照需要调用接口中定义的方法即可,这样不论使用什么数据库,都对于Java程序没有任何影响,即便是换⼀个数据库,也只需要换⼀下相应厂商的实现依赖。

JDBC使用过程可以概括为:加载数据库厂商的驱动包、建立连接、创建Statement、执行SQL、 处理结果释放资源和关闭连接。

三、使用JDBC

1、创建Maven工程并配置国内镜像

1.1创建Maven工程

1.2配置国内镜像(阿里的)

        拖动到idea里面,把<mirrors></mirrors>中的内容换成下面的内容,再CTRL+s(保存)

(默认的仓库在国外,我们下载会很慢,所以要换成国内的镜像)

aliyunmaven*阿⾥云公共仓库https://maven.aliyun.com/repository/public

central*aliyun centralhttps://maven.aliyun.com/repository/central

spring*aliyun springhttps://maven.aliyun.com/repository/spring

2、获取MySQL驱动包

        在Maven仓库(mvnrepository.com)搜索MySQL,找到最新版的驱动包

        一般8.0.33就可以

3、修改pom.xml⽂件

        在⼯程中的pom.xml中的新建<dependencies></dependencies>标签中添加MySQL依赖(把上图最下面的代码复制粘贴到<dependencies></dependencies>中间)

        加载成功后可以通过以下方式查看

4、建立数据库连接

        使用驱动管理类 DriverManager 的静态方法获取数据库连接

// 注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
// 获取数据库连接
Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/jobs_info_db?characterEncoding" +"=utf8&allowPublicKeyRetrieval=true&useSSL=false","root","123456");

        通过数据源 DataSource 对象获取,推荐在实际开发中应用这种方式

// 设置数据源的连接串、⽤⼾名和密码
MysqlDataSource mysqlDataSource = new MysqlDataSource();
mysqlDataSource.setURL("jdbc:mysql://127.0.0.1:3306/jobs_info_db?characterEncoding" +"=utf8&allowPublicKeyRetrieval=true&useSSL=false");
mysqlDataSource.setUser("root");
mysqlDataSource.setPassword("123456");
// 把mysqlDataSource 转换为JDBC的dataSource
DataSource dataSource = mysqlDataSource;

        MySQL数据库连接URL格式: jdbc:mysql:// 服务器地址 : 端⼝ / 数据库 ? 参数名 = 值 [& 参数名 = 值 ]...

5、创建Statement

        Statement是用于执行静态SQL语句并返回执行结果的对象

// 通过connection获取statement对象
Statement statement = connection.createStatement();

6、执行SQL语句

        执行select查询时返回的是⼀个结果集,用ResultSet接收

        执行nsert,update,delete操作时,返回的是受影响的行数,用int类型接收

// 执⾏select语句, 并接收结果集
ResultSet resultSet = statement.executeQuery("select id, name, sno, age, gender, enroll_date, class_id from student");
// 执⾏insert, update, delete语句,并接收受影响的⾏数
int row = statement.executeUpdate("update student set age = 20 where id = 2");

7、处理结果集

        如果返回的是⼀个结果集,则需要遍历这个集合获取对应列的值,具体代码如下:

// 遍历结果集获取数据
while (resultSet.next()) {// 编号long id = resultSet.getLong("id");// 姓名String name = resultSet.getString("name");// 学号String sno = resultSet.getString("sno");// 年龄int age = resultSet.getInt("age");// 性别byte gender = resultSet.getByte("gender");// ⼊学时间Date enrollDate = resultSet.getDate("enroll_date");// 班级编号long classId = resultSet.getLong("class_id");// TODO: 使⽤获取到的值...
}

8、释放资源

        在整个数据库访问过程中创建的对象都需要释放,包括:ResultSet,Statement和Connection, 后创建的先释放

// 释放结果集
if (resultSet != null) {try {resultSet.close();} catch (SQLException e) {e.printStackTrace();}
}
// 释放statement
if (statement != null) {try {statement.close();} catch (SQLException e) {e.printStackTrace();}
}
// 关闭连接
if (connection != null) {try {connection.close();} catch (SQLException e) {e.printStackTrace();}
}

四、JDBC常用接口和类

1、DriverManager 和DataSource

        DataSource驱动管理类,用于管理JDBC驱动程序,可以从驱动程序中获取数据库连接,始于 JDK1.1。

        DataSource数据源是DriverManager的替代方案,始于JDK1.4,是获取数据库连接的首选方法, 推荐使用。

2、DriverManager 与DataSource的区别

        DriverManager和DataSource都可以获取到数据库连接,但它们之间存着着⼀些区别,主要在于连接的管理方式和资源利用效率

        连接管理方式不同:

                 DriverManager每次调用getConnection方法都会初始化⼀个新的连接,使用完成后会关闭真实连接,导致资源浪费

                DataSource使用了连接池的技术,会在初始化时创建⼀定数量的数据库连接,这些连接可以重复使用,关闭时并不是真正关闭连接,而是将连接归还给连接池,以供后续使用,有效地提高资源利用率和和性能

3、Connection 数据库连接

        数据库连接(会话)对象,在连接的上下文中执行SQL语句并返回结果

4、Statement对象

4.1Statement

        用于执行静态SQL语句并返回执行结果,由于只能执行静态语句,所以这⾥会有⼀个问题,假设⼀个语句中需要动态的参数,如where子句中的条件,那么只能通过字符串拼接的方式组装完成的SQL语句,如:

String sql = "select * from student where name = '" + name + "' and class_id = " + classId;

        字符串拼接形式构造SQL语句时,如果不处理参数中的特殊字符就会造成SQL注入,这是⼀个非常严重的安全性问题。

4.2SQL注入

        SQL注入即是指web应用程序对用户输⼊数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进⼀步得到相应的数据信息。

大家一定不要去做没有授权的安全测试

4.3PreparedStatement

        预编译SQL语句对象,SQL语句被预编译并存储在PreparedStatement对象中,可以使用该对象多次执行SQL语句,同时可以解决SQL注入问题。

例:通过Connection对象获取到PreparedStatement对象,需要传入SQL模板,动态参数用占位符?表示

// 获取了个处理SQL的PrepareStatement对象
PreparedStatement preparedStatement = connection.prepareStatement("select id, name, sno, age, gender, enroll_date, class_id from student where name = ? and class_id = ?");

        为动态参数设置真实值,下标从1开始

// ⽤真实值去替换占位符
preparedStatement.setString(1, "宋江");
preparedStatement.setLong(2, 2);

        执行SQL语句

// select 操作
ResultSet resultSet = statement.executeQuery();
// insert, update, delete操作
int result = statement.executeUpdate();

4.4CallableStatement

        用于执行SQL存储过程的接口。这里不做讨论

4.5executeQuery()

        执行结果返回的是⼀个结果集,通常用于select操作

4.6executeUpdate()

        执行结果返回的是⼀个整形,通常用于insert,update,delete操作

5、ResultSet结果集

        是⼀个查询结果集的数据表,通常由执行查询操作的语句生成。

        ResultSet对象维护了⼀个指向当前数据行的游标,最初游标位于第一行之前,调用next方法将游标移动到下⼀行,当ResultSet中没有更多的数据行时返回false,所以可以在while循环中使用它来遍历结果集。

        ResultSet接口提供了getter⽅法(getBoolean、getLong等),用于从当前行检索列值,可以使用列的索引号或列的名称来检索值。⼀般来说,使用列索引会更有效率,索引编号从1开始,按照从左到右的顺序读取。

六、示例

        查询学生编号为1的学生基本信息

package org.bitejiuyeke;
import com.mysql.cj.jdbc.MysqlDataSource;
import javax.sql.DataSource;
import java.sql.*;
import java.text.MessageFormat;
public class Demo_DataSource {public static void main(String[] args) {// 定义数据源DataSource dataSource = null;// 定义连接对象Connection connection = null;// 定义预编译对象PreparedStatement statement = null;// 定义结果集对象ResultSet resultSet = null;// 设置数据源参数MysqlDataSource mysqlDataSource = new MysqlDataSource();mysqlDataSource.setURL("jdbc:mysql://127.0.0.1:3306/java01?characterEncoding=utf8&allowPublicKeyRetrieval=true&useSSL=false");mysqlDataSource.setUser("root");mysqlDataSource.setPassword("123456");// 转为JDBC数据源dataSource = mysqlDataSource;// 获取连接try {connection = dataSource.getConnection();// 获取了个处理SQL的PrepareStatement对象statement = connection.prepareStatement("select id, name, sno, age, gender, " +"enroll_date, class_id from student where id = ?");// ⽤真实值去替换占位符statement.setLong(1, 1);resultSet = statement.executeQuery();// 处理结果集,由于查询的是⼀条记录,这⾥⽤if即可if (resultSet.next()) {long id = resultSet.getLong("id");String name = resultSet.getString("name");String sno = resultSet.getString("sno");int age = resultSet.getInt("age");byte gender = resultSet.getByte("gender");Date enrollDate = resultSet.getDate("enroll_date");long classId = resultSet.getLong("class_id");// 打印结果System.out.println(MessageFormat.format("{0}, {1}, {2}, {3}, {4}, {5}, {6}", id, name, sno, age, gender,enrollDate, classId));}} catch (SQLException e) {e.printStackTrace();} finally {// 在finally中释放所有资源// 关闭结果集if (resultSet != null) {try {resultSet.close();} catch (SQLException e) {e.printStackTrace();}}// 关闭预编译对象if (statement != null) {try {statement.close();} catch (SQLException e) {e.printStackTrace();}}// 关闭数据库连接if (connection != null) {try {connection.close();} catch (SQLException e) {e.printStackTrace();}}}}}

http://www.jsqmd.com/news/12752/

相关文章:

  • 深入解析:扩散模型-图像编辑【An Edit Friendly DDPM Noise Space: Inversion and Manipulations】
  • Docker Desktop 挂载目录实际位置
  • 2025年10月掘进机厂家最新权威推荐榜单:高效施工与卓越性能的首选品牌!
  • 2025年10月电源适配器厂家最新推荐排行榜,笔记本电源适配器,手机电源适配器,USB电源适配器公司推荐!
  • 2025年10月彩钢瓦保养厂家最新推荐排行榜,防腐彩钢瓦,隔热彩钢瓦,耐候彩钢瓦公司推荐!
  • 【网络安全】二、入门篇:HTTP 协议进阶 ——GET/POST 常用传参手段详解
  • AI元人文构想:基础理论框架解析2025年10月13日
  • 2025年10月南通婚纱照最新权威推荐榜:创意摄影与贴心服务完美结合!
  • 2025年10月安全光栅厂家最新推荐排行榜,超薄/四级/无盲区/红外/光电/小型/冲床/折弯机/机床安全光栅及传感器公司推荐!
  • 2025 年吸塑纸卡厂家推荐榜:吸塑热压/牙刷/电池/玩具/牙刷烫银纸卡厂家,聚焦环保与品质,帮企业精准选对合作伙伴
  • 2025年10月风机盘管定制厂家最新推荐排行榜:专业定制与优质服务口碑之选
  • 2025年10月液压阀块厂家最新推荐排行榜,专业生产与品质保障的首选!
  • 2025年10月风机盘管厂家最新推荐榜单,中央空调风机盘管,商用风机盘管,家用风机盘管,优质供货厂家推荐!
  • ubuntu?centos?还是 redhat?Linux 架构选哪个?
  • 2025年10月微弧氧化厂家最新推荐排行榜,铝合金/镁合金/黑色/钛合金微弧氧化技术加工公司推荐
  • 2025年10月新型农机带制造厂家最新推荐榜单,专业生产与技术创新引领行业前沿!
  • 2025 年打包带厂家推荐榜:PP/PET/铁皮/轻质打包带厂家,聚焦品质与效率,助力企业优化包装方案
  • 2025年10月七水硫酸锌厂家最新推荐排行榜:专业生产与优质服务的行业佼佼者!
  • 2025年10月TAB拉链厂家最新权威推荐榜:品质与创新并重的行业佼佼者!
  • 2025年10月无弦吉他厂家最新推荐排行榜,智能无弦吉他,便携无弦吉他,专业演奏无弦吉他公司推荐!
  • 完整教程:GSM8K:评估大模型数学推理能力的关键数据集
  • 2025年10月PP鱼池厂家最新推荐排行榜,环保耐用,养鱼爱好者的首选!
  • 2025年10月UV面光源定制厂家最新推荐榜单:专业定制与卓越品质口碑之选!
  • 2025年10月石头纸设备定做厂家最新推荐榜单,专业定制与高效生产口碑之选
  • 20232407 2025-2026-1 《网络与系统攻防技术》 实验一实验报告
  • 2025 年减压阀厂商推荐榜:气体/实验室/调压/膜片/不锈钢/可调式/气路/气体管路/蒸汽减压阀厂家,聚焦安全与专业,助力企业精准选品
  • 完整教程:【FPGA 开发分享】如何在 Vivado 中使用 PLL IP 核生成多路时钟
  • 实用指南:精读C++20设计模式——创造型设计模式:单例模式
  • 2025 年潜水泵厂家推荐榜,轴流/混流/全贯流/浮筒轴流/立式轴流/大流量轴流潜水泵厂家怎么选?3 个核心参数帮你挑对款!
  • 2025年10月机械加工订制厂家最新推荐榜单:专业实力与客户满意度深度解析