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 通过在交换机之…...
练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...
ESP32读取DHT11温湿度数据
芯片:ESP32 环境:Arduino 一、安装DHT11传感器库 红框的库,别安装错了 二、代码 注意,DATA口要连接在D15上 #include "DHT.h" // 包含DHT库#define DHTPIN 15 // 定义DHT11数据引脚连接到ESP32的GPIO15 #define D…...
屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!
5月28日,中天合创屋面分布式光伏发电项目顺利并网发电,该项目位于内蒙古自治区鄂尔多斯市乌审旗,项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站,总装机容量为9.96MWp。 项目投运后,每年可节约标煤3670…...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
Java 加密常用的各种算法及其选择
在数字化时代,数据安全至关重要,Java 作为广泛应用的编程语言,提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景,有助于开发者在不同的业务需求中做出正确的选择。 一、对称加密算法…...
Robots.txt 文件
什么是robots.txt? robots.txt 是一个位于网站根目录下的文本文件(如:https://example.com/robots.txt),它用于指导网络爬虫(如搜索引擎的蜘蛛程序)如何抓取该网站的内容。这个文件遵循 Robots…...
CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云
目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...
HDFS分布式存储 zookeeper
hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架,允许使用简单的变成模型跨计算机对大型集群进行分布式处理(1.海量的数据存储 2.海量数据的计算)Hadoop核心组件 hdfs(分布式文件存储系统)&a…...
C++:多态机制详解
目录 一. 多态的概念 1.静态多态(编译时多态) 二.动态多态的定义及实现 1.多态的构成条件 2.虚函数 3.虚函数的重写/覆盖 4.虚函数重写的一些其他问题 1).协变 2).析构函数的重写 5.override 和 final关键字 1&#…...
LRU 缓存机制详解与实现(Java版) + 力扣解决
📌 LRU 缓存机制详解与实现(Java版) 一、📖 问题背景 在日常开发中,我们经常会使用 缓存(Cache) 来提升性能。但由于内存有限,缓存不可能无限增长,于是需要策略决定&am…...
