【MySQL】使用 JDBC 连接数据库

文章目录
- 前言
- 1. 认识 JDBC
- 1.1 概念
- 1.2 好处
- 2. 使用 JDBC
- 2.1 安装数据驱动包
- 2.2 把 jar 包导入到项目中
- 2.3 代码编写
- 2.4 测试结果
- 3. 代码优化
- 4. 源码展示
- 结语
前言
在 MySQL 系列中,我们介绍了很多内容,包括但不限于建库建表,增删查改等等,但是这些操作都是直接在本机上的 MySQL 进行的,而在实际的开发过程中,我们很少会这样做,更多的是通过代码(C++、Java、Python……)来操作数据库的。今天我们就会简单介绍如何通过 Java 代码来操作数据库
1. 认识 JDBC
1.1 概念
JDBC(Java Database Connectivity)是一个 Java API,它提供了一种标准的方法,用于 Java 程序与各种数据库进行交互。简单来说,JDBC 是一个桥梁,使得 Java 应用程序能够执行 sql 语句,以查询、更新和管理数据库中的数据
1.2 好处
- 平台无关性:JDBC 使我们可以在任何支持 Java 的平台上运行的数据库访问代码,而无需关心底层数据库的类型
- 数据库无关性:JDBC 提供了统一的 API,使得我们可以使用相同的代码结构来访问不同类型的数据库,如 MySQL、Oracle、SQL Server 等
- 简化数据库访问:JDBC 简化了数据库访问的过程,我们不需要深入了解底层数据库的复杂性,就可以通过 JDBC 提供的接口轻松地执行数据库操作
2. 使用 JDBC
2.1 安装数据驱动包
所谓的数据驱动包,实际上就是包含了 JDBC 操作数据库的 API 的一个 jar 包,里面有很多的 .class 文件,我们可以在官网下载驱动包 (https://dev.mysql.com/downloads/)
也可以在 Maven 中央仓库下载(https://mvnrepository.com/),此处我们简单演示一下在 Maven 下载数据驱动包
-
打开 Maven 网址,搜索栏输入“Mysql”,此时最上面会出现两个结果。因为博主使用的 MySQL 版本比较老,所以选择 “经典版”

-
点进去后就是各种版本的驱动包了。这里需要下载和你 MySQL 安装的版本一致才可,我的MySQL是
5.7的,所以要选择 5.1 开头的,后面的小版本无所谓;如果你的 MySQL 是8.x版本的,那你就要选择 8 开头的驱动包了
-
博主这里选择
5.1.49这个版本,点进去后下载jar包
-
这样就下载好啦~

2.2 把 jar 包导入到项目中
-
先新建一个 Java 项目,并在这个项目下右键建立一个目录,命名为
lib(注意不要带有中文/特殊字符)
-
接着找到我们下载好的
jar包,直接复制然后粘贴到 lib 目录中(ctrl c 和 ctrl v 即可),点击 OK
-
然后右键 lib 目录,点击 add as library,再点击 OK 就行了。此时 idea 就能自动分析出 jar 包里有什么内容了


-
这样就大功告成啦

2.3 代码编写
1. 创建数据源:要连接数据库时,我们需要知道这个数据库的位置;我们可以通过 DataSource 对象来获取
DataSource dataSource = new MysqlDataSource();((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/javatest?characterEncoding=utf8&useSSL=false"); // “Javatest”是数据库名((MysqlDataSource)dataSource).setUser("root");((MysqlDataSource)dataSource).setPassword("xxxxxxxxx"); // 根据你安装是设置的密码填入
DataSourse是 Java 中的一个接口,不能直接创建对象,因此我们使用MysqlDataSource这个子类来创建对象- 接下来是 setURL( )、setUser( )、setPassWord( ),它们都是 MysqlDataSource 中的方法,分别服务器的 url(统一资源定位符)、服务器的账号、服务器的密码()
- 此处我们还使用了向上转型和向下转型,目的是为了降低耦合。若之后我们使用的数据库不是 MySQL,那修改代码就十分方便
2. 和数据库服务器建立网络连接
Connection connection = dataSource.getConnection();
- 要注意此处的导入的包是
import java.sql.Connection这个,不要选错了 - 此处的
Connection对象,表示的就是一个数据库连接(抽象的客户端服务器连接) - 此处的异常可以使用
throw直接抛出
3. 构造 SQL 语句
比如我们现在想要在表中插入一条信息,就可以使用字符串来表示
String sql = "insert into student values ('qiqi', 77)";
接着使用 PreparedStatement 来预编译这个 sql 语句
PreparedStatement statement = connection.prepareStatement(sql);
- 我们写的 sql 语句就可以放在
statement这个对象里面 - 预编译指的是它可以在客户端发送 sql 语句前,先解析一下,从而降低服务器的工作压力
4. 执行 SQL 语句
我们需要把 sql 发送到服务器上进行执行,可以使用 statement 里的方法
-
如果我们要执行的是增、删、改的操作,那就使用 executeUpdate 方法
statement.executeUpdate(); -
如果我们要执行的是查操作,那就使用 executeQuery 方法
statement.executeQuery();
5. 断开连接,释放资源
在进行类似的网络通信时,在使用完后一定要记得释放资源。我们上面创建了 connection 和 statement 两个对象,它们都需要释放,我们按照创造顺序的相反来关闭(先 statement,后 connection)
statement.close();
connection.close();
完整代码如下:
package jdbc;import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Scanner;public class TestUpdate {public static void main(String[] args) throws SQLException {//1.创建数据源对象(基本是默认的)DataSource dataSource = new MysqlDataSource();((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/javatest?characterEncoding=utf8&useSSL=false");((MysqlDataSource)dataSource).setUser("root");((MysqlDataSource)dataSource).setPassword("xxxxxxxxx");//2.和数据库服务器建立网络连接(选择Connection java.sql包)Connection connection = dataSource.getConnection();//System.out.println(connection);//测试连接是否成功//3.构造sql语句(基于PreparedStatement预处理)String sql = "insert into student values ('qiqi', 77)";//写死的//4.把sql发送到服务器上进行执行//statement.executeQuery()查询//statement.executeUpdate()增删改int n = statement.executeUpdate();//影响的行数System.out.println(n);//5.释放上述资源(倒着释放)statement.close();connection.close();}
}
2.4 测试结果

最终打印 1,即影响的行数,表示插入成功
3. 代码优化
String sql = "insert into student values ('qiqi', 77)";//写死的
- 我们这里是把插入的 sql 给写死了,如果我们能够在控制台输入我们需要插入的信息,岂不美哉。因此得把代码修改一下
//用户输入Scanner scanner = new Scanner(System.in);System.out.println("请输入姓名:");String name = scanner.nextLine();System.out.println("请输入分数:");int grade = scanner.nextInt();//修改sql语句String sql = "insert into a values ('"+ name +"',"+ grade +")";
-
这时候就可以通过控制台输入信息了。但是此处还有点小瑕疵,它有可能会引起 sql 注入攻击,别人可以通过代码直接拼接构造 sql 语句导致 sql 语句被恶意篡改(有一篇 2012 年的新闻报道了 sql 注入事件,感兴趣的可以看一下( 网传技术流号牌遮挡能干掉交警数据库 警方辟谣)
-
所以我们可以把 sql 语句再修改一下,使用占位符 “ ?”
String sql = "insert into a values (?,?)";//?为占位符
接着通过 statement 对象里面的 setInt() 和 setString() 方法来设置这两个字段,从而将这个 sql 语句构造完整,这样就能防止 sql 注入攻击啦
PreparedStatement statement = connection.prepareStatement(sql);
statement.setInt(1, id);
statement.setString(2, name);
补充:数据库的查找操作
上面我们提到了,如果我们要执行的是查操作,那就得使用 executeQuery 方法
除此之外,返回的结果也不一样:
- 如果是增、删、改操作的话,返回的就只是一个 int 类型的值,表示影响的行数,可以检验 sql 语句是否执行成功
- 但是对于查操作,它会返回一个结果集,也就是我们查询的结果,因此我们可以使用
ResultSet对象来进行接收,接着遍历里面的内容。最后也要记得关闭它哦 - 其他的代码就和上面的插入是一样的
package jdbc;import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;public class Testselect {public static void main(String[] args) throws SQLException {DataSource dataSource = new MysqlDataSource();((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/javatest?characterEncoding=utf8&useSSL=false");((MysqlDataSource)dataSource).setUser("root");((MysqlDataSource)dataSource).setPassword("xxxxxxxxx");Connection connection = dataSource.getConnection();String sql = "select * from student";PreparedStatement statement = connection.prepareStatement(sql);//一个集合类,可以遍历得到ResultSet resultSet = statement.executeQuery();//遍历结果while (resultSet.next()) {System.out.println(resultSet.getString("name"));System.out.println(resultSet.getInt("grade"));}resultSet.close();statement.close();connection.close();}
}
运行结果如下:

4. 源码展示
插入操作
package jdbc;import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Scanner;public class TestUpdate {public static void main(String[] args) throws SQLException {//0.用户输入Scanner scanner = new Scanner(System.in);System.out.println("请输入姓名:");String name = scanner.nextLine();System.out.println("请输入分数:");int grade = scanner.nextInt();//1.创建数据源对象(基本是默认的)DataSource dataSource = new MysqlDataSource();((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/javatest?characterEncoding=utf8&useSSL=false");((MysqlDataSource)dataSource).setUser("root");((MysqlDataSource)dataSource).setPassword("xxxxxxxxx");//2.和数据库服务器建立网络连接(选Connection java.sql包)Connection connection = dataSource.getConnection();//System.out.println(connection);//测试连接是否成功//3.构造sql语句(基于PreparedStatement预处理)//String sql = "insert into student values ('qiqi', 77)";//写死的//String sql = "insert into student values ('"+name+"',"+grade+")";//代码看起来乱,而且可能会被“sql注入攻击”---> ');drop database xxx;String sql = "insert into student values (?,?)";//?为占位符//String sql = "delete from a where name = ?";//删除也是一样PreparedStatement statement = connection.prepareStatement(sql); //预编译statement.setString(1,name); //1表示第一个问号statement.setInt(2,grade);//4.把sql发送到服务器上进行执行//executeQuery()查询//executeUpdate()增删改int n = statement.executeUpdate();//影响的行数System.out.println(n);//5.释放上述资源(倒着释放)statement.close();connection.close();}
}
查询操作
package jdbc;import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;public class Testselect {public static void main(String[] args) throws SQLException {DataSource dataSource = new MysqlDataSource();((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/javatest?characterEncoding=utf8&useSSL=false");((MysqlDataSource)dataSource).setUser("root");((MysqlDataSource)dataSource).setPassword("xxxxxxxxx");Connection connection = dataSource.getConnection();String sql = "select * from student";PreparedStatement statement = connection.prepareStatement(sql);//一个集合类,可以遍历得到ResultSet resultSet = statement.executeQuery();//遍历结果while (resultSet.next()) {System.out.println(resultSet.getString("name"));System.out.println(resultSet.getInt("grade"));}resultSet.close();statement.close();connection.close();}
}
结语
今天我们介绍了如何使用 JDBC 连接数据库,通过代码来直接操作 MySQL 数据库,上面展示的操作方法还是比较粗糙的,而且随着技术的不断更新,我们也很少会直接使用 JDBC 了。但是理解上述的操作方法对我们来说肯定是有作用,在后续使用框架的时候,底层原理还是离不开这个操作思路的。接下来是博主的一些碎碎念 (●’◡’●)
一个月没写博客了,有点生疏,加上需要回顾前面的知识以及查阅资料,确实需要消耗更多的时间。不知道值不值得继续✍,但是总觉得学习完一个知识点后不总结篇博客就不得劲,自己写的东西到时候来回顾应该也更加得心应手吧。接下来我更加努力更新博客,加油 (ง •_•)ง
希望大家能够喜欢本篇博客,有总结不到位的地方还请多多谅解。若有纰漏,希望大佬们能够在私信或评论区指正,博主会及时改正,共同进步
相关文章:
【MySQL】使用 JDBC 连接数据库
文章目录 前言1. 认识 JDBC1.1 概念1.2 好处 2. 使用 JDBC2.1 安装数据驱动包2.2 把 jar 包导入到项目中2.3 代码编写2.4 测试结果 3. 代码优化4. 源码展示结语 前言 在 MySQL 系列中,我们介绍了很多内容,包括但不限于建库建表,增删查改等等…...
数据结构与算法笔记:概念与leetcode练习题
1、数组Array 时间复杂度 数组访问:O(1) 数组搜索:O(N) 数组插入:O(N) 数组删除:O(N) 特点 适合读,不适合写 数组常用操作 # 1、创建数组 a [] # 2、尾部添加元素 a.append(1) a.append(2) a.append(3) # 3、…...
十大时间序列预测模型
目录 1. 自回归模型 原理 核心公式 推导过程: 完整案例 2. 移动平均模型 原理 核心公式 推导过程: 完整案例 3. 自回归移动平均模型 原理 核心公式 推导过程: 完整案例 4. 自回归积分移动平均模型 原理 核心公式 推导过程 完整案例 5. 季节性自回归积分…...
G2O 通过工厂函数类 OptimizationAlgorithmFactory 来生成固定搭配的优化算法
OptimizationAlgorithmFactory 类位于 optimization_algorithm_factory.h //***g2o源码 g2o/g2o/core/optimization_algorithm_factory.h ***// /*** \brief create solvers based on their short name** Factory to allocate solvers based on their short name.* The Factor…...
手机USB连接不显示内部设备,设备管理器显示“MTP”感叹号,解决方案
进入小米驱动下载界面,等小米驱动下载完成后,解压此驱动文件压缩包。 5、小米USB驱动安装方法:右击“计算机”,从弹出的右键菜单中选择“管理”项进入。 6、在打开的“计算机管理”界面中,展开“设备管理器”项&…...
SpringBootWeb快速入门!详解如何创建一个简单的SpringBoot项目?
在现代Web开发中,SpringBoot以其简化的配置和快速的开发效率而受到广大开发者的青睐。本篇文章将带领你从零开始,搭建一个基于SpringBoot的简单Web应用~ 一、前提准备 想要创建一个SpringBoot项目,需要做如下准备: idea集成开发…...
RabbitMQ 入门到精通指南
RabbitMQ 是一种开源消息代理软件,基于 AMQP(高级消息队列协议)构建,用于异步传输数据,帮助我们解耦系统、削峰流量、处理高并发。本指南将详细介绍 RabbitMQ 的架构设计、使用场景、安装步骤以及一些高级应用…...
ARM base instruction -- movz
Move wide with zero moves an optionally-shifted 16-bit immediate value to a register. 用零移动宽值将可选移位的16位即时值移动到寄存器。即把立即数移动寄存器前先把寄存器清零。 32-bit variant MOVZ <Wd>, #<imm>{, LSL #<shift>} 64-bit var…...
安装jdk安装开发环境与maven
1.下载maven 链接: https://pan.baidu.com/s/1gTmIWBFBdIQob0cqGG3E_Q 提取码: 42ck,apache-maven-3.8.4-bin.zip 2.安装java jdk yum install -y java-1.8.0-openjdk-devel 3.在/opt目录下新建目录 mkdir /opt/maven 4.将apache-maven-3.8.4-bin.zip上传到/opt/ma…...
openpnp - 图像传送方向要在高级校正之前设置好
文章目录 openpnp - 图像传送方向要在高级校正之前设置好笔记图像传送方向的确定END openpnp - 图像传送方向要在高级校正之前设置好 笔记 图像传送方向和JOG面板的移动控制和实际设备的顶部摄像头/底部摄像头要一致,这样才能和贴板子时的实际操作方向对应起来。 …...
数据库建表规范【记录】
建表规约 【强制】创建表时必须显式指定表存储引擎类型,如无特殊需求,一律为InnoDB。 【强制】必须有行数据的创建时间字段create_date和最后更新时间字段edit_date。 【强制】自增主键命名必须是id,关联表外键命名xxyyzz_id;业务…...
css的动画属性
CSS动画属性是CSS3的一个重要特性,它允许你创建平滑的过渡效果,增强用户的交互体验。CSS动画可以通过keyframes规则和animation属性来创建。 animation属性 animation属性是一个简写属性,用于设置动画的多个属性,包括动画名称、…...
【Ubuntu】PlantUML工具 | 安装 | 语法 | 使用工具画序列图
🌱 PlantUML是一个通用性很强的工具,可以快速、直接地创建各种图表。 目录 1 安装 2 使用PlantUML画序列图 ① 语法 ②示例和效果 利用简单直观的语言,用户可以毫不费力地绘制各种类型的图表。PlantUML 是一个开源项目,支持快速绘制:• 时序图• 用例图• 类图• 对...
微信步数C++
题目: 样例解释: 【样例 #1 解释】 从 (1,1) 出发将走 2 步,从 (1,2) 出发将走 4 步,从 (1,3) 出发将走 4 步。 从 (2,1) 出发将走 2 步,从 (2,2) 出发将走 3 步,从 (2,3) 出发将走 3 步。 从 (3,1) 出发将…...
AI写作工具大比拼:揭秘Claude的神秘魅力以及如何订阅Claude
AI写作困境与Claude的惊喜表现 最近有很多朋友在吐槽AI写的文章不太行,我一看他的要求写的很清楚,已经把提示词都用到位了,例如:写作背景、写作要求等,都有具体写出来。但文章阅读起来就是欠缺点啥。 你们有没有遇到…...
秋招内推2025-招联金融
【投递方式】 直接扫下方二维码,或点击内推官网https://wecruit.hotjob.cn/SU61025e262f9d247b98e0a2c2/mc/position/campus,使用内推码 igcefb 投递) 【招聘岗位】 后台开发 前端开发 数据开发 数据运营 算法开发 技术运维 软件测试 产品策…...
GOM引擎启动后M2提示Invalid filename报错的解决办法
在架设一个GOM引擎版本的时候,启动M2就提示Invalid filename,之后的网关就没有办法再启动了,研究了半天也终于是弄好了,其实也简单,就是路径设置的不对,所以无法完成启动,很多人以为在控制台设置…...
CPU 多级缓存
在多线程并发场景下,普通的累加很可能错的 CPU 多级缓存 Main Memory : 主存Cache : 高速缓存,数据的读取存储都经过此高速缓存CPU Core : CPU 核心Bus : 系统总线 CPU Core 和 Cache 通过快速通道连接,Main menory 和 Cache 都挂载到 Bus 上…...
Chrome浏览器调用ActiveX控件--allWebOffice控件功能介绍
allWebOffice控件概述 allWebOffice控件能够实现在浏览器窗口中在线操作文档的应用(阅读、编辑、保存等),支持编辑文档时保留修改痕迹,支持书签位置内容动态填充,支持公文套红,支持文档保护控制等诸多办公功…...
JavaScript-下篇
上篇我们学习了,一些基础语法和函数,现在我们学习下篇,主要包括,对象和事件。而对象又包括,数组Arrays,String字符串,BOM,DOM等 JS对象 Arrays数组 数组是一种特殊的对象,用于存储…...
手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...
1688商品列表API与其他数据源的对接思路
将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...
基于Uniapp开发HarmonyOS 5.0旅游应用技术实践
一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架,支持"一次开发,多端部署",可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务,为旅游应用带来…...
ffmpeg(四):滤镜命令
FFmpeg 的滤镜命令是用于音视频处理中的强大工具,可以完成剪裁、缩放、加水印、调色、合成、旋转、模糊、叠加字幕等复杂的操作。其核心语法格式一般如下: ffmpeg -i input.mp4 -vf "滤镜参数" output.mp4或者带音频滤镜: ffmpeg…...
相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...
LLM基础1_语言模型如何处理文本
基于GitHub项目:https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken:OpenAI开发的专业"分词器" torch:Facebook开发的强力计算引擎,相当于超级计算器 理解词嵌入:给词语画"…...
k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...
代理篇12|深入理解 Vite中的Proxy接口代理配置
在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...
USB Over IP专用硬件的5个特点
USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中,从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备(如专用硬件设备),从而消除了直接物理连接的需要。USB over IP的…...
React---day11
14.4 react-redux第三方库 提供connect、thunk之类的函数 以获取一个banner数据为例子 store: 我们在使用异步的时候理应是要使用中间件的,但是configureStore 已经自动集成了 redux-thunk,注意action里面要返回函数 import { configureS…...
