Java数据库连接(JDBC)
一、引言
在Java应用程序中,经常需要与数据库进行交互以存储、检索和处理数据。Java数据库连接(JDBC)是Java平台中用于执行这一任务的标准API。JDBC允许Java程序连接到关系数据库,并使用SQL语句来执行查询和更新操作。本教程将详细介绍如何使用JDBC进行数据库连接,并提供详细的代码示例。
二、JDBC基本组件
JDBC主要由两部分组成:JDBC API和JDBC驱动程序。
- JDBC API:JDBC API提供了应用程序与数据库交互所需的接口和类。这些接口和类在
java.sql
包中定义。 - JDBC驱动程序:JDBC驱动程序是使JDBC API能够与特定数据库交互的软件。不同的数据库管理系统(DBMS)需要不同的JDBC驱动程序。
三、JDBC驱动程序类型
JDBC驱动程序主要有四种类型:
- Type 1: JDBC-ODBC Bridge:通过ODBC驱动程序与数据库交互。不推荐使用,因为它依赖于ODBC,并且性能较差。
- Type 2: Native-API Partly-Java Driver:使用特定于DBMS的客户端库,通过JNI(Java Native Interface)与数据库交互。性能较好,但可移植性差。
- Type 3: Network Protocol Pure Java Driver:纯Java实现,使用DBMS的网络协议与数据库进行通信。性能可能稍逊于Type 2,但可移植性较好。
- Type 4: Native Protocol Pure Java Driver:纯Java实现,使用DBMS的专有协议与数据库进行通信。通常是最快和最可移植的JDBC驱动程序。
四、使用JDBC连接数据库
以下是一个使用JDBC连接MySQL数据库的详细步骤和代码示例。
步骤1:加载和注册JDBC驱动程序
首先,需要将JDBC驱动程序加载到Java虚拟机(JVM)中,并注册到DriverManager
类中。这通常通过调用Class.forName()
方法并传递驱动程序的完全限定类名来完成。
try {Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {e.printStackTrace();
}
注意:从JDBC 4.0开始,通常不需要显式加载和注册驱动程序,因为DriverManager
类会自动加载实现了java.sql.Driver
接口的所有类。但是,为了确保与旧版本JDBC的兼容性,一些驱动程序可能仍然要求显式加载和注册。
步骤2:创建数据库连接
接下来,使用DriverManager.getConnection()
方法创建一个到数据库的连接。此方法需要一个数据库URL,一个用户名和一个密码(如果适用)。
String url = "jdbc:mysql://localhost:3306/mydatabase";
String username = "myuser";
String password = "mypassword";Connection connection = null;
try {connection = DriverManager.getConnection(url, username, password);
} catch (SQLException e) {e.printStackTrace();
}
步骤3:创建Statement或PreparedStatement对象
一旦建立了数据库连接,就可以使用Connection
对象的createStatement()
或prepareStatement()
方法创建一个Statement
或PreparedStatement
对象。这些对象用于执行SQL语句。
Statement statement = null;
try {statement = connection.createStatement();// 或者// PreparedStatement preparedStatement = connection.prepareStatement("INSERT INTO mytable (column1, column2) VALUES (?, ?)");
} catch (SQLException e) {e.printStackTrace();
}
步骤4:执行SQL语句
使用Statement
或PreparedStatement
对象的executeQuery()
、executeUpdate()
或execute()
方法执行SQL语句。
ResultSet resultSet = null;
try {resultSet = statement.executeQuery("SELECT * FROM mytable");// 或者// preparedStatement.setInt(1, value1);// preparedStatement.setString(2, value2);// int rowsAffected = preparedStatement.executeUpdate();
} catch (SQLException e) {e.printStackTrace();
}
步骤5:处理结果集(如果适用)
如果执行的是查询语句,则返回一个ResultSet
对象,其中包含查询结果。可以使用ResultSet
对象的next()
、getInt()
、getString()
等方法遍历和处理结果集。
try {while (resultSet.next()) {int column1Value = resultSet.getInt("column1");String column2Value = resultSet.getString("column2");// 处理结果...}
} catch
步骤6:关闭连接和释放资源
最后,需要关闭ResultSet
、Statement
或PreparedStatement
以及Connection
对象,以释放数据库资源。这通常使用try-with-resources
语句(如果可用)或显式调用close()
方法来完成。
使用try-with-resources
语句的示例:
try (Connection connection = DriverManager.getConnection(url, username, password);Statement statement = connection.createStatement();ResultSet resultSet = statement.executeQuery("SELECT * FROM mytable")) {// 处理结果集...} catch (SQLException e) {e.printStackTrace();
}
// 这里不需要显式关闭资源,因为try-with-resources会自动处理
如果不使用try-with-resources
,则需要显式关闭资源:
try {// ...(创建连接、语句和结果集的代码)...// 处理结果集...} catch (SQLException e) {e.printStackTrace();
} finally {try {if (resultSet != null) resultSet.close();if (statement != null) statement.close();if (connection != null) connection.close();} catch (SQLException e) {e.printStackTrace();}
}
五、完整的JDBC示例
下面是一个完整的JDBC示例,演示了如何连接到MySQL数据库,执行查询并处理结果:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;public class JdbcExample {public static void main(String[] args) {String url = "jdbc:mysql://localhost:3306/mydatabase";String username = "myuser";String password = "mypassword";try (Connection connection = DriverManager.getConnection(url, username, password);Statement statement = connection.createStatement();ResultSet resultSet = statement.executeQuery("SELECT * FROM mytable")) {while (resultSet.next()) {int id = resultSet.getInt("id");String name = resultSet.getString("name");// ... 处理其他列 ...System.out.println("ID: " + id + ", Name: " + name);}} catch (SQLException e) {e.printStackTrace();}}
}
六、注意事项
- 异常处理:在实际应用中,应该妥善处理
SQLException
和其他可能的异常。 - 安全性:不要在生产环境中硬编码数据库凭据(用户名和密码)。使用配置文件、环境变量或密钥管理服务来管理凭据。
- 资源管理:确保正确关闭和释放所有数据库资源,以避免资源泄漏。
- 连接池:对于高并发的应用程序,使用连接池可以提高性能和可伸缩性。连接池负责管理数据库连接的创建、使用和释放。
- 使用PreparedStatement:当执行带有参数的SQL语句时,使用
PreparedStatement
可以提高性能和安全性。PreparedStatement
还可以防止SQL注入攻击。 - 事务管理:如果需要在多个操作中维护数据的一致性,请使用数据库事务。通过
Connection
对象的setAutoCommit()
方法可以设置自动提交模式,或者使用commit()
和rollback()
方法来手动控制事务的提交和回滚。
七、事务管理
在JDBC中,事务管理是通过Connection
对象来控制的。默认情况下,JDBC连接是自动提交的,即每次执行一个SQL语句后,该语句的影响都会立即生效(如果成功执行)。然而,在需要确保多个操作作为一个原子单元(即要么全部成功,要么全部失败)执行时,就需要使用事务。
以下是一个使用JDBC进行事务管理的基本示例:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;public class JdbcTransactionExample {public static void main(String[] args) {String url = "jdbc:mysql://localhost:3306/mydatabase";String username = "myuser";String password = "mypassword";try (Connection connection = DriverManager.getConnection(url, username, password)) {// 禁用自动提交connection.setAutoCommit(false);try (Statement statement = connection.createStatement()) {// 执行第一个SQL语句statement.executeUpdate("UPDATE mytable SET column1 = 'value1' WHERE id = 1");// 假设这里有一个条件判断,如果条件不满足,则回滚事务boolean someCondition = false; // 示例条件if (!someCondition) {throw new SQLException("Some condition failed, rolling back transaction");}// 执行第二个SQL语句statement.executeUpdate("UPDATE mytable SET column2 = 'value2' WHERE id = 2");// 如果所有操作都成功,则提交事务connection.commit();} catch (SQLException e) {// 如果在事务中发生异常,则回滚事务try {connection.rollback();} catch (SQLException ex) {ex.printStackTrace();}throw e; // 重新抛出异常以便上层处理} finally {// 恢复自动提交状态(可选)connection.setAutoCommit(true);}} catch (SQLException e) {e.printStackTrace();}}
}
八、使用PreparedStatement进行参数化查询
为了避免SQL注入攻击,并提高查询性能(因为JDBC可以预编译SQL语句),推荐使用PreparedStatement
。
以下是一个使用PreparedStatement
的示例:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;public class JdbcPreparedStatementExample {public static void main(String[] args) {String url = "jdbc:mysql://localhost:3306/mydatabase";String username = "myuser";String password = "mypassword";try (Connection connection = DriverManager.getConnection(url, username, password)) {String sql = "SELECT * FROM mytable WHERE id = ?";try (PreparedStatement preparedStatement = connection.prepareStatement(sql)) {preparedStatement.setInt(1, 1); // 设置第一个参数的值try (ResultSet resultSet = preparedStatement.executeQuery()) {while (resultSet.next()) {int id = resultSet.getInt("id");String name = resultSet.getString("name");// ... 处理其他列 ...System.out.println("ID: " + id + ", Name: " + name);}}}} catch (SQLException e) {e.printStackTrace();}}
}
九、使用连接池
在实际应用中,频繁地创建和关闭数据库连接会带来性能开销。为了解决这个问题,可以使用连接池来管理数据库连接。连接池预先创建并维护一组数据库连接,应用程序从连接池中获取连接,使用完后将其归还给连接池,而不是直接关闭连接。有许多开源的连接池库可供选择,如Apache DBCP、C3P0、HikariCP等。这些库通常提供了配置选项,以便控制连接池的大小、超时时间等参数。使用连接池时,需要将连接池库添加到项目的依赖中,并在代码中配置和使用连接池。
相关文章:
Java数据库连接(JDBC)
一、引言 在Java应用程序中,经常需要与数据库进行交互以存储、检索和处理数据。Java数据库连接(JDBC)是Java平台中用于执行这一任务的标准API。JDBC允许Java程序连接到关系数据库,并使用SQL语句来执行查询和更新操作。本教程将详…...
记录一次cas单点登录的集成
主要思路:浏览器访问CAS服务器登录,拿到凭证给后端,后端用此凭证到CAS服务器验证登录并拿到用户信息,之后基于该凭证维持用户的登录状态。 主要流程: 1.浏览器访问后端需认证登录地址(不带ticket…...

【吊打面试官系列】Java高并发篇 - 什么是乐观锁和悲观锁?
大家好,我是锋哥。今天分享关于 【什么是乐观锁和悲观锁?】面试题,希望对大家有帮助; 什么是乐观锁和悲观锁? 1、乐观锁: 就像它的名字一样,对于并发间操作产生的线程安全问题持乐观状态, 乐观锁认为竞争…...
机器学习之词袋模型
目录 1 词袋模型基本概念 2 词袋模型的表示方法 2.1 三大方法 1 独热表示法(One-Hot) 2 词频表示法(Term Frequency, TF) 3 词频-逆文档频率表示法(TF-IDF) 2.2 例子 1 词袋模型基本概念 词袋模型&a…...

【C++/STL】vector(常见接口、模拟实现、迭代器失效)
🌈个人主页:秦jh_-CSDN博客🔥 系列专栏: https://blog.csdn.net/qinjh_/category_12575764.html?spm1001.2014.3001.5482 目录 简单使用 常见接口 find insert vector模板 模拟实现 尾插 构造 迭代器失效 使用memcpy拷贝问…...
Spring Boot Web 开发:MyBatis、数据库连接池、环境配置与 Lombok 全面解析
推荐一个AI网站,免费使用豆包AI模型,快去白嫖👉海鲸AI 1.0 MyBatis 概述 MyBatis 是一个优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 可以帮助我们将数据库操作抽象出来,使得我们的代码更加简洁…...

【UE5.1 多线程 异步】“Async Blueprints Extension”插件使用记录
目录 一、异步生成Actor示例 二、异步计算示例 参考视频 首先需要在商城中下载“Async Blueprints Extension”插件 一、异步生成Actor示例 2. 创建一个线程类,这里要指定父类为“LongAsyncTask”、“InfiniteAsyncTask”、“ShortAsyncTask”中的一个 在线程类…...

【已解决】在jupyter里运行torch.cuda.is_available(),显示True,在pycharm中运行却显示false。
文章目录 问题概述1、在Jupyter中GPU运行true2、在pycharm中GPU运行false3、个人解决方案仅供参考 问题概述 在jupyter里运行torch.cuda.is_available(),显示True,在pycharm中运行却显示false。原因在于jupyter 运行环境和pycharm 运行环境不同…...
Flutter 中的 Scrollbar 小部件:全面指南
Flutter 中的 Scrollbar 小部件:全面指南 在Flutter中,滚动条(Scrollbar)是一种常见的UI组件,用于提供对滚动内容的快速访问和控制。Scrollbar 小部件可以附加到任何可滚动的widget上,如ListView、GridVie…...

【华为】将eNSP导入CRT,并解决不能敲Tab问题
华为】将eNSP导入CRT,并解决不能敲Tab问题 eNSP导入CRT打开eNSP,新建一个拓扑右键启动查看串口号关联CRT成功界面 SecureCRT连接华为模拟器ensp,Tab键不能补全问题选择Options(选项)-- Global Options (全局选项&#…...

实验二 电子传输系统安全-进展2
上周任务完成情况(代码链接,所写文档等) 重新调通电子公文传输系统部署gmssl学习生成SM2证书学习gmssl中的CTLS实现将数据库从SqlServer迁移到Mysql调试Mysql驱动学习Bouncy Castle 代码链接 Mysql表设计 /* Navicat MySQL Data Transfer…...
JavaScript 获取 HTML 中特定父元素下的子元素
JavaScript 获取 HTML 中特定父元素下的子元素 <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <title>查找子元素示例</title> </head> <body><div id"parent"><p&…...

等保服务是一次性服务吗?为什么?怎么理解?
我国等保政策已经严格落地执行,但还有不少企业对于等保服务不是很了解。例如有人问,等保服务是一次性服务吗?为什么?怎么理解?今天我们就来简单回答一下,仅供参考哈! 等保服务是一次性服务吗&…...

全网首发UNIAPP功能多的iapp后台源码
全网首发UNIAPP功能多的iapp后台源码,众所周知UN Dev Assist 后台是一款既不免费又不好用的后台今天直接分享。 搭建教程在里面了,自己查看。 源码下载:https://download.csdn.net/download/m0_66047725/89291994 更多资源下载:…...

【搜索方法推荐】高效信息检索方法和实用网站推荐
博主未授权任何人或组织机构转载博主任何原创文章,感谢各位对原创的支持! 博主链接 本人就职于国际知名终端厂商,负责modem芯片研发。 在5G早期负责终端数据业务层、核心网相关的开发工作,目前牵头6G算力网络技术标准研究。 博客…...

面试被问到不懂的东西,是直接说不懂还是坚持狡辩一下?
大家好,我是瑶琴呀。 面试被问到不懂的东西,是直接说不懂还是坚持狡辩一下?这个问题可以转变一下,如果你顺利拿到 offer,公司安排的工作跟你之前的技术和经验不匹配,你还愿意干下去吗? 转变一…...
Flutter 中的 StatefulBuilder 小部件:全面指南
Flutter 中的 StatefulBuilder 小部件:全面指南 在Flutter中,StatefulBuilder是一个高效的小部件,它根据给定的构建函数来构建widget,并在组件树中只对需要重新构建的部分进行更新。这使得它在性能优化方面非常有用,特…...

mail发送接口API如何使用?怎么调用接口?
mail发送接口API的性能怎么样?邮件接口发信的技巧? 为了自动化和集成电子邮件功能到应用程序或系统中,开发人员可以使用各种邮件发送接口API。AokSend将介绍如何使用这些API来发送电子邮件,提高效率和灵活性。 mail发送接口API&…...

DOS学习-目录与文件应用操作经典案例-attrib
新书上架~👇全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我👆,收藏下次不迷路┗|`O′|┛ 嗷~~ 目录 一.前言 二.使用 三.案例 一.前言 DOS系统中的attrib命令是一个用于显示或更改文件&#…...
STP简介
一、STP介绍 STP 即生成树协议(Spanning Tree Protocol)一种网络协议 STP 主要用于解决以太网中的环路问题。在具有冗余链路的网络环境中,环路可能导致广播风暴、重复帧等不良后果,严重影响网络性能和稳定性。STP 通过在交换机之…...
Python爬虫实战:研究MechanicalSoup库相关技术
一、MechanicalSoup 库概述 1.1 库简介 MechanicalSoup 是一个 Python 库,专为自动化交互网站而设计。它结合了 requests 的 HTTP 请求能力和 BeautifulSoup 的 HTML 解析能力,提供了直观的 API,让我们可以像人类用户一样浏览网页、填写表单和提交请求。 1.2 主要功能特点…...

使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...

51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...

Qt/C++开发监控GB28181系统/取流协议/同时支持udp/tcp被动/tcp主动
一、前言说明 在2011版本的gb28181协议中,拉取视频流只要求udp方式,从2016开始要求新增支持tcp被动和tcp主动两种方式,udp理论上会丢包的,所以实际使用过程可能会出现画面花屏的情况,而tcp肯定不丢包,起码…...
DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径
目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...

Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...

UDP(Echoserver)
网络命令 Ping 命令 检测网络是否连通 使用方法: ping -c 次数 网址ping -c 3 www.baidu.comnetstat 命令 netstat 是一个用来查看网络状态的重要工具. 语法:netstat [选项] 功能:查看网络状态 常用选项: n 拒绝显示别名&#…...
【解密LSTM、GRU如何解决传统RNN梯度消失问题】
解密LSTM与GRU:如何让RNN变得更聪明? 在深度学习的世界里,循环神经网络(RNN)以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而,传统RNN存在的一个严重问题——梯度消失&#…...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...