JDBC: Java数据库连接的桥梁
什么是JDBC?
Java数据库连接(Java Database Connectivity,简称JDBC)是Java提供的一种API,允许Java应用程序与各种数据库进行交互。JDBC提供了一组标准的接口,开发者可以利用这些接口执行SQL语句、处理结果集以及管理数据库连接。通过JDBC,Java应用程序能够轻松地进行增删改查操作(CRUD),使得数据库操作变得简单而高效。
下载JDBC驱动
MySQL :: Download Connector/J
以MySQL为例
下载对应压缩包
找到合适的路径进行解压,解压后找到如下的 jar 包
IDEA引入驱动
1.新建一个项目,在项目下新建一个 lib 文件夹,将找到的 jar 包 复制进去
2.放进去jar包之后,右键lib,选择 add as library
3.找到下面的文件打开
4.复制内容,用于进行注册
Class.forName("com.mysql.cj.jdbc.Driver");
下面先看一个例子
package com.ffyc;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;public class jdbctest {public static void main(String[] args) {final String USERNAME="root";final String PASSWORD = "123456";final String URL ="jdbc:mysql://localhost:3306/kingdom_db?useSSL=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai";Connection conn = null;Statement statement = null;try {//注册驱动Class.forName("com.mysql.cj.jdbc.Driver");//获取连接conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);//创建statement对象statement = conn.createStatement();String sql = "INSERT INTO dept_tab VALUES (6, '教学部', '102');";//执行sql语句statement.executeUpdate(sql);System.out.println("数据插入成功!");} catch (Exception e) {throw new RuntimeException(e);}finally {//关闭资源try {if (statement != null) statement.close();if (conn != null) conn.close();} catch (SQLException e) {throw new RuntimeException(e);}}}
}
s
URL的构成部分
jdbc:mysql:
jdbc
是Java数据库连接的协议前缀,指明这是一个JDBC类型的连接。mysql
表示使用MySQL数据库。localhost:
localhost
指的是数据库服务器的地址。在这里,它表示数据库安装在本地计算机上。如果您要连接远程数据库,可以替换为相应的IP地址或主机名。:3306:
3306
是MySQL默认的端口号。它告诉JDBC在这个端口与MySQL数据库进行连接。如果您的MySQL数据库使用了不同的端口,请相应地更改此值。/kingdom_db:
/kingdom_db
是您要连接的数据库的名称。在这个例子中,试图连接名为kingdom_db
的数据库。?useSSL=true:
?
用于开始查询参数。这部分包含了一些用于配置连接行为的选项。useSSL=true
指示JDBC驱动程序在连接时使用SSL加密。这对于保护数据传输是一个安全措施。&useUnicode=true:
&
用于分隔多个查询参数。useUnicode=true
表示使用Unicode字符编码,确保对于包含多语言字符的数据能够正确地处理和存储。&characterEncoding=utf-8:
characterEncoding=utf-8
指定了字符编码为UTF-8。UTF-8是一种广泛使用的字符编码方式,它支持多种语言字符的表示。这样可以避免字符乱码问题。&serverTimezone=Asia/Shanghai:
serverTimezone=Asia/Shanghai
设置了数据库服务器时区。此参数对于处理日期和时间数据是很重要的,确保在进行时区转换时能够准确。
只需要修改一下 2 3 4的写法,其他基本都是固定写法,用的时候上网搜一下即可,不需要记住 。
这个URL提供了与MySQL数据库连接所需的详细信息,包括服务器位置、端口号、数据库名称以及一系列连接参数。正确地配置这些参数有助于确保您的应用程序能够稳定、高效地与数据库交互,同时提高安全性和数据的一致性。
JDBC中的常用方法及解释
注册驱动:
Class.forName("com.mysql.cj.jdbc.Driver");
这行代码用于加载MySQL的JDBC驱动,在使用JDBC时必须先注册相应的数据库驱动。获取连接:
Connection conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
通过DriverManager获取到数据库的连接,这样才能进行后续的SQL操作。创建预编译语句:
PreparedStatement pst = conn.prepareStatement(sql);
预编译语句主要用于执行SQL语句,其具有参数占位符,使得插入的值更安全, 可防止SQL注入攻击。执行更新或查询:
pst.executeUpdate();
和ResultSet rs = pst.executeQuery();
这两个方法用于执行SQL语句,前者用于执行更新(如插入、删除、更新),后者用于查询并返回结果集。关闭连接: 在操作完成后应及时关闭连接,以释放资源。
PreparedStatement vs. Statement
Statement
- 使用
Statement
时,SQL语句及参数是拼接在一起的,这意味着开发者需要手动构建整个SQL字符串。Statement
在执行前不会进行预编译,因此每次执行SQL时都会重新解析并编译SQL语句,这会影响性能。
示例代码:
String username = "user";
String password = "pass123";
String sql = "SELECT * FROM user_tab WHERE username = '" + username + "' AND user_password = '" + password + "'";
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql);
PreparedStatement
PreparedStatement
使用占位符(?
)来表示参数,SQL语句是通过预编译的,这可以有效提升性能,减少数据库的负担。PreparedStatement
可以防止SQL注入,因为参数是在执行时传递给SQL的,JDBC会自动进行转义处理。
示例代码:
String sql = "SELECT * FROM user_tab WHERE username = ? AND user_password = ?";
PreparedStatement pst = conn.prepareStatement(sql);
pst.setString(1, username); // 设置第一个参数
pst.setString(2, password); // 设置第二个参数
ResultSet rs = pst.executeQuery();
SQL注入漏洞
SQL注入是一种常见的安全攻击手段,攻击者可以通过在输入字段中插入恶意SQL代码来操纵数据库。例如,在使用Statement
的情况下,以下拼接 SQL 的方式就容易受到SQL注入攻击:
String unsafeUsername = "' OR '1'='1"; // 攻击者输入的用户名
String sql = "SELECT * FROM user_tab WHERE username = '" + unsafeUsername + "'";
ResultSet rs = stmt.executeQuery(sql);
在这个例子中,如果unsafeUsername
被设置为' OR '1'='1
,那么SQL语句实际上变成了:
SELECT * FROM user_tab WHERE username = '' OR '1'='1'
这个查询会返回user_tab
表中的所有用户,因为OR '1'='1'
始终为真。
相比之下,使用PreparedStatement
可以有效防止这样的攻击。例如:
String sql = "SELECT * FROM user_tab WHERE username = ? AND user_password = ?";
PreparedStatement pst = conn.prepareStatement(sql);
pst.setString(1, unsafeUsername); // 输入的用户名
pst.setString(2, password);
ResultSet rs = pst.executeQuery();
在这种情况下,unsafeUsername
的值不会被直接当作SQL代码执行,而是只作为参数处理。因此,即使攻击者输入了恶意的SQL片段,也不会改变原有SQL的结构,防止了SQL注入的发生。
这就是为什么要用PreparedStatement而不用Statement
简单封装
由于每次连接数据库都有一些重复的代码要写,所以我们对它进行简单的封装,下面的例子展示了如何封装JDBC操作,以便于日后的使用:
JdbcUtil 类
package com.util;import java.sql.*;/*** static*/
public class JdbcUtil {static final String USERNAME = "root";static final String PASSWORD = "123456";static final String URL ="jdbc:mysql://localhost:3306/kingdom_db?useSSL=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai";static Connection conn;static PreparedStatement pst;static ResultSet rs;static{registry();}/*** 注册驱动*/private static void registry(){try {Class.forName("com.mysql.cj.jdbc.Driver");}catch (Exception e){e.printStackTrace();}}public static void connect(){try {conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);} catch (SQLException e) {throw new RuntimeException(e);}}/*** 预编译sql语句*/public static void prepareStatement(String sql,Object ... vals){try {pst = conn.prepareStatement(sql);for(int i=0;i<vals.length;i++){pst.setObject(i+1, vals[i]);}} catch (SQLException e) {throw new RuntimeException(e);}}/*** 增删改sql语句*/public static void executeUpdate(){try {pst.executeUpdate();} catch (SQLException e) {throw new RuntimeException(e);}}/*** 查询sql语句*/public static ResultSet executeQuery(){try {rs = pst.executeQuery();} catch (SQLException e) {throw new RuntimeException(e);}return rs;}public static void close(){try {if(rs!=null) rs.close();if(pst!=null) pst.close();if(conn!=null) conn.close();} catch (SQLException e) {throw new RuntimeException(e);}}
}
DeptDemo类
package com.ffyc;import com.util.JdbcUtil;import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Scanner;public class DeptDemo {public static void main(String[] args) throws SQLException {JdbcUtil.connect();String sql = null;ResultSet rs= null;Scanner sc = new Scanner(System.in);System.out.println("1. 添加部门信息\t2.查询所有部门信息");System.out.println("3. 根据部门名称查询");System.out.print("请选择: ");String choice = sc.nextLine();switch (choice) {case "1":System.out.print("请输入部门名称: ");String name = sc.nextLine();System.out.print("请输入部门位置: ");String loc = sc.nextLine();sql = "INSERT INTO dept_tab(dept_name, dept_loc) VALUES(?,?)";JdbcUtil.prepareStatement(sql, name,loc);JdbcUtil.executeUpdate();System.out.println("添加成功");break;case "2":sql = "SELECT * FROM dept_tab";JdbcUtil.prepareStatement(sql );rs = JdbcUtil.executeQuery();while(rs.next()){System.out.print(rs.getObject("dept_id"));System.out.print("-"+rs.getObject("dept_name"));System.out.print("-"+rs.getObject("dept_loc"));System.out.println();}break;case "3":System.out.print("请输入部门的名称: ");String nName= sc.nextLine();sql = "SELECT * FROM dept_tab WHERE dept_name LIKE ?";JdbcUtil.prepareStatement(sql,"%"+nName+"%");rs = JdbcUtil.executeQuery();while(rs.next()){System.out.print(rs.getObject("dept_id"));System.out.print("-"+rs.getObject("dept_name"));System.out.print("-"+rs.getObject("dept_loc"));System.out.println();}break;default:System.out.println("输入不合法..");}JdbcUtil.close();}
}
代码解释
以上面这个例子。我对必要的地方做出解释说明
1.数据库连接
String sql = "INSERT INTO dept_tab(dept_name, dept_loc) VALUES(?,?)";
JdbcUtil.prepareStatement(sql, name, loc);
JdbcUtil.executeUpdate();
JdbcUtil.connect();
通过 JdbcUtil
类的 connect
方法连接到数据库。
2.用户交互
Scanner sc = new Scanner(System.in);
System.out.println("1. 添加部门信息\t2.查询所有部门信息");
System.out.println("3. 根据部门名称查询");
使用 Scanner
类从控制台获取用户输入,提示用户选择要执行的操作。
3.添加部门信息
String sql = "INSERT INTO dept_tab(dept_name, dept_loc) VALUES(?,?)";
JdbcUtil.prepareStatement(sql, name, loc);
JdbcUtil.executeUpdate();
重点是要对JdbcUtil这个封装类的方法理解,这是我们自定以的封装类
JDBC的优缺点
优点
- 平台独立性:作为 Java 的一部分,JDBC 具有平台无关性,可以在任何支持 Java 的环境中运行。
- 标准化接口:JDBC 提供了统一的 API,使得不同数据库之间的操作变得一致。
- 灵活性:支持多种数据库,如 MySQL、Oracle、PostgreSQL 等,只需更换驱动程序即可。
缺点
- 性能开销:传统的 JDBC 连接可能存在性能问题,尤其是在大量数据操作时。
- 代码复杂性:直接使用 JDBC 需要编写较多的样板代码,增加了开发的复杂性。
- 异常处理:JDBC 的异常处理相对复杂,开发者需要处理多种异常类型。
总结
JDBC 是 Java 开发中必不可少的组成部分,它为开发者提供了一种灵活、标准化的方法与数据库交互。尽管存在一些缺点,但通过合理的设计和封装,可以最大限度地发挥 JDBC 的优势。作为 Java 开发者,理解 JDBC 的工作原理及操作方式,将对提升数据库管理能力大有裨益。
相关文章:

JDBC: Java数据库连接的桥梁
什么是JDBC? Java数据库连接(Java Database Connectivity,简称JDBC)是Java提供的一种API,允许Java应用程序与各种数据库进行交互。JDBC提供了一组标准的接口,开发者可以利用这些接口执行SQL语句、处理结果集…...

英伟达GPU算力【自用】
GPU(图形处理单元)算力的提升是驱动当代科技革命的核心力量之一,尤其在人工智能、深度学习、科学计算和超级计算机领域展现出了前所未有的影响力。2024年的GPU技术发展,不仅体现在游戏和图形处理的传统优势上,更在跨行…...

「C/C++」C++11 之 智能指针
✨博客主页何曾参静谧的博客📌文章专栏「C/C」C/C程序设计📚全部专栏「VS」Visual Studio「C/C」C/C程序设计「UG/NX」BlockUI集合「Win」Windows程序设计「DSA」数据结构与算法「UG/NX」NX二次开发「QT」QT5程序设计「File」数据文件格式「PK」Parasoli…...

算法面试小抄
第一章:算法与数据结构要点速学 1.时间复杂度 (大 O) 首先,我们来谈谈常用操作的时间复杂度,按数据结构/算法划分。然后,我们将讨论给定输入大小的合理复杂性。 数组(动态数组/列表) 规定 n arr.length, 注意: &am…...

当有违法数据时,浏览器不解析,返回了undefined,导致数据不解析
现象:页面上没有看到数据 排查:断点到线上的源码里:1、协议回调确实没有拿到数据是个undefined 2、network里看服务确实响应了数据 3、控制台没有任何报错。 心情:莫名其妙的现象 我本地有json格式化工具,copy进去后&…...

在MySQL中ORDER BY使用的那种排序算法
在 MySQL 中,ORDER BY 子句的排序算法通常根据场景、数据量和表的索引情况而有所不同。MySQL 常用的排序算法包括: 文件排序(File Sort):MySQL 没有使用索引排序的情况下,会进行文件排序,这可以…...

学习threejs,使用粒子实现雨滴特效
👨⚕️ 主页: gis分享者 👨⚕️ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨⚕️ 收录于专栏:threejs gis工程师 文章目录 一、🍀前言1.1 ☘️THREE.Points简介1.11 ☘️…...

分布式-单元化架构1
一 两地三中心 1.1 两地三中心* 两地指的是两个城市:同城,异地。三中心指的是三个数据中心:生产中心、同城容灾中心、异地容灾中心。 在同一个城市或者临近的城市建设两个相同的系统,双中心具备相当的业务处理能力,…...

C++模板、STL
目录 一、模板 1、函数模板 (1)、基本语法和使用 (2)、函数模板注意事项 (3)、普通函数与函数模板的区别 (4)、普通函数与函数模板的调用规则 (5)、模板的局限性 2、类模板 (1)、基本语法 (2)、类模板与函数模板区别 (3)、类模板中成员函数创建时机 (4)、类模板对象…...

计算机视觉中的点算子:从零开始构建
Hey小伙伴们!今天我们要聊的是一个非常基础但极其重要的计算机视觉技术——点算子(Point Operators)。点算子主要用于对图像的每个像素进行独立的处理,比如亮度调整、对比度增强、灰度化等。通过这些简单的操作,我们可…...

国际中文教育知识图谱问答
你还在为毕业设计头疼么?想快速搭建一个智能化系统,展示数据又能精准回答问题?那你绝对不能错过这个超实用的 知识图谱问答系统,特别适用于需要整合复杂数据关系、交互性强的项目! 这个系统基于 Neo4j图数据库 开发&a…...

酒店大板轻触开关与传统的开关有什么区别
酒店大板轻触开关与传统的开关在功能、设计、使用方式以及安装维护等多个方面都存在显著的差异。以下是对这些差异的详细分析: 功能差异 酒店大板轻触开关: 多功能性:酒店大板轻触开关通常集成了多种功能,如控制照明、窗帘、夜灯、…...

【蓝桥杯选拔赛真题78】python电话号码 第十五届青少年组蓝桥杯python选拔赛真题 算法思维真题解析
目录 python电话号码 一、题目要求 1、编程实现 2、输入输出 二、算法分析 三、程序编写 四、程序说明 五、运行结果 六、考点分析 七、 推荐资料 1、蓝桥杯比赛 2、考级资料 3、其它资料 python电话号码 第十五届蓝桥杯青少年组python比赛选拔赛真题 一、题目要…...

对比两个json串的diff,支持map的深度递归
背景 项目重构,对老接口进行技术改造。动代码后,难免会有些bug,我们需要对比改造前后接口的返回,来判断逻辑是否有问题,这就涉及两个json的对比。 常规的diff文本工具是按行对比,无法处理复杂的map。本文通…...

【我的创作纪念日1024】
我的创作纪念日1024 机缘成就明年的规划 机缘 过去的1024个日子里,我在专业发展、职场和发展、科技创新创业、软件开发、人工智能、虚拟现实、区块链等栏目分享了一些工作和学习的建议和体会。尤其是在2022年,我连续发布100篇的博文,不仅仅是…...

萤石设备视频接入平台EasyCVR私有化视频平台变电站如何实现远程集中监控?
一、方案背景 随着城市经济的发展和电力系统的改造,变电站的数量和规模逐渐增加,对变电站的安全管理和监控需求也越来越高。视频监控系统作为重要的安全管理手段,在变电站中起到了关键的作用。 目前青犀视频研发的萤石设备视频接入平台EasyC…...

什么是多线程?请描述 Java 中实现多线程的基本方式?
今天和大家探讨一下 Java 中的多线程,包括它的基本概念、实现方式以及一些实际开发中的注意事项。 什么是多线程? 多线程是指在一个程序中存在多个执行流,每个执行流都可以独立于其他执行流执行。 在 Java 中,多线程允许开发者…...

Dynamic Sparse No Training: Training-Free Fine-tuning for Sparse LLMs
大语言模型(LLM)在设备上部署道路上落下了一个令人生畏的障碍。本文关注于大语言模型的剪枝算法。 动态稀疏训练(Dynamic Sparse Training,DST)是一种近期收到广泛关注的剪枝算法。与之前大部分剪枝方法需要训练整个网…...

解决n+1查询数据库问题
文章目录 1. 问题描述2. 解决方法3. 总结 1. 问题描述 在写项目中,可能会碰到一个问题:通过查询表A得到一个list结果,再对list中的n个元素各查询一次关联的表B。形成对数据库执行n1次查询。这种代码会无形增加数据库的处理负担,影…...

DICOM 基础知识:深入理解DICOM数据结构与标签说明
目录 DICOM 图像概念 DICOM 图像关键特性: DICOM 文件结构 常见数据元素: 数据元素示例详解 DICOM-VR 数据类型说明 DICOM 标准支持的数据集 结语 DICOM 图像概念 DICOM(Digital Imaging and Communications in Medicine&…...

Git - 如何删除 push 过一次的文件链路追踪?
(以 target 文件夹为例)如果你已经在 .gitignore 中添加了 target/ 目录,但 target 文件夹仍然出现在 Git 的变更列表中,可能是因为它之前已经被添加到 Git 仓库中。即使你更新了 .gitignore,Git 仍然会跟踪这些文件。…...

软件测试学习总结
一.软件测试概念和目的 软件测试的概念: 测试模型(V模型) 软件测试就是在软件投入运行前,对软件需求分析、设计规格说明和编码实现的最终审查,它是软件质量保证的关键步骤。 通常对软件测试的定义有两种描述: 定义1:软件测试是为了发现错误而执行程序的过程 定义2:…...

c语言错题——#define对应的查找替换
文章目录 一、题目 提示:以下是本篇文章正文内容,下面案例可供参考 一、题目 分析 结构体向最长的char对齐,前两个位段元素一共42位,不足8位,合起来占1字节,最后一个单独1字节,一共3字节。另外…...

Visual Basic介绍及简单例子
Visual Basic(简称 VB)是一种由微软公司开发的包含协助开发环境的事件驱动编程语言。 一、主要特点 易于学习和使用: Visual Basic 具有直观的可视化开发环境,使用户可以通过拖放控件和设置属性的方式快速创建用户界面。对于初学者来说,这种方式非常容易上手,无需深入了…...

Matlab学习01-矩阵
目录 一,矩阵的创建 1,直接输入法创建矩阵 2,利用M文件创建矩阵 3,利用其它文本编辑器创建矩阵 二,矩阵的拼接 1,基本拼接 1) 水平方向的拼接 2)垂直方向的拼接 3…...

【复旦微FM33 MCU 外设开发指南】外设篇1——硬件除法器
前言 本系列基于复旦微FM33LC0系列单片机的DataSheet编写,旨在提供一些开发指南。 本文章及本系列其他文章将持续更新,本系列其它文章请跳转【复旦微FM33 MCU 外设开发指南】总集篇 本文章最后更新日期:2024/10/24 文章目录 前言用途工作流…...

在元神操作系统启动时自动执行任务脚本
1. 背景 本文主要介绍让元神操作系统启动时自动执行任务脚本的方法,适用于无人化任务执行目的。将任务脚本及相关的应用程序准备好之后,把装有元神操作系统的U盘插入目标电脑,然后打开电脑电源就会自动完成所设置的任务。 2. 方法 &#x…...

JAVA学习-练习试用Java实现“判断是否为等边三角形的方法”
问题: 定义一个三角形类(Triangle),包含三个边长(a, b, c)属性,并实现一个判断是否为等边三角形的方法。 解答思路: 下面是一个简单的 Triangle 类定义,其中包含了三个…...

Leetcode 140 Word Break II
题意:给定一个string以及一个wordDict,要求返回一个vector<string> ,这个vector中的string都是word Dict中的组合 Input: s “catsanddog”, wordDict [“cat”,“cats”,“and”,“sand”,“dog”] Output: [“cats and dog”,“cat sand dog”…...

文理学院数据库应用技术实验报告0
文理学院数据库应用技术实验报告0 实验内容 打开cmd,利用MySQL命令连接MySQL服务器。 mysql -u root -p查看当前MySQL服务实例使用的字符集(character)。 SHOW VARIABLES LIKE character_set_server;查看当前MySQL服务实例支持的字符序(collation)。 SHOW VARIABLES LIKE c…...