Java之JDBC技术详解

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
云数据库 RDS MySQL,高可用系列 2核4GB
简介: JDBC (Java Date Base Connectivity),指 Java 数据库连接,是一种标准Java应用编程接口 (Java API),用来连接Java编程语言和广泛的数据库。

一、简介


1. 什么是JDBC

JDBC (Java Date Base Connectivity),指 Java 数据库连接,是一种标准Java应用编程接口 (Java API),用来连接Java编程语言和广泛的数据库。

JDBC API 库包含下面提高的每个任务,都是与数据库相关的常用用法。

  • 制作到数据库的连接
  • 创建 SQL 或 MySQL 语句
  • 创建 SQL 或 MySQL 查询数据库
  • 查看和修改所产生的记录

从根本上来说,JDBC 是一种规范,它提供了一套完整的接口,允许便携式访问到底层数据库,因此可以用 Java 编写不同类型的可执行文件,例如:

  • Java 应用程序
  • Java Applets
  • Java Servlets
  • Java ServerPages (JSPs)
  • Enterprise JavaBeans (EJBs)

所有这些不同的可执行文件就可以使用JDBC驱动程序来访问数据库,这样可以方便的访问数据。

JDBC 具有 ODBC 一样的性能,允许 Java 程序包含与数据库无关的代码。

2. 先决条件

为了更好的理解本教程,需要对以下两个主题内容很好的理解:

  • 核心 Java 编程
  • SQL 或 MySQL 数据库

3. JDBC 架构

JDBC 的 API 支持两层和三层处理模式进行数据库访问,但一般的 JDBC 架构由两层处理模式组成:

  • JDBC API:提供了应用程序对 JDBC 管理器的连接
  • JDBC DRIVER API:提供了 JDBC 管理器对驱动程序连接

JDBC API 使用驱动程序管理器和数据库特定的驱动程序来提供异构 (heterogeneous) 数据库的透明连接。

JDBC 驱动程序管理器可确保正确的驱动程序来访问每个数据源。该驱动程序管理器能够支持连接到多个异构数据库的多个并发的驱动 程序。

以下是结构图,其中显示了驱动程序管理器相对于在 JDBC 驱动程序和 Java 应用程序所处的位置。

网络异常,图片无法展示
|

以上引自 JDBC 简介_w3cschool

二、常用接口


在开发 JDBC 程序前,首先了解一下 JDBC 常用的 API。JDBC API主要位于 java.sql 包中,该包定义了一系列访问数据库的接口和类,具体如下:

  1. Driver 接口

Driver 接口由数据库厂家提供,作为 Java 开发人员,只需要使用 Driver 接口就可以了。在编程中要连接的数据库,必须先装载特定厂商的数据库驱动程序,不同的数据库有不同的装载方法。如:

装载 MySQL 驱动:Class.forName ( "ciom.mysql.jdvc.Driver" );

装载 Oracle 驱动:Class.forName ( "oracle.jdbc.driver.OracleDriver" );

  1. Connection 接口

Connection 与特定数据库的连接(会话),在连接上下文中执行 sql 语句并返回结果。

DriverManager.getConnection ( url ,user ,password )方法建立在 JDBC URL 中定义的数据库 Connection 连接上。

连接 MySQL 数据库:

Connection conn = DriverManager.getConnection ( "jdbc:mysql://host:port/database" , "user" , "password");

连接 Oracle 数据库:

Connection conn = DriverManager.getConnection ( "jdbc:oracle:thin:@host:port:database" , "user" , "password");

连接 SqlServer 数据库:

Connection conn = DriverManager.getConnection ( "jdbc:microsoft:sqlsever://host:port;DatabaseName=database" , "user" , "password");

常用方法:

  • createStatement():创建向数据库发送 sql 的 statement 对象。
  • prepareStatement (sql):创建向数据库发送预编译 sql 的 PrepareSatement 对象。
  • prepareCall (sql):创建执行存储过程的 callableStatement 对象。
  • setAutoCommit (boolean autoCommit):设置事物是否自动提交。
  • commit():在链接上提交事物。
  • rollback():在此链接上回滚事物。
  1. Statement 接口

用于执行静态 SQL 语句并返回它所生成结果的对象

三种 Statement 类:

  • Statement:由 createStatement 创建,用于发送简单的 SQL 语句 (不带参数)。
  • PreparedStatement:继承自Statement接口,由 preparedStatement 创建,用于发送含有一个或多个参数的 SQL 语句。PreparedStatement 对象比 Startement 对象的效率更高,并且可以防止 SQL 注入,所以一般我们都使用 PreparedStatement
  • CallableStatement:继承自 PreparedStatement 接口,由方法 prepareCall 创建,用于调用 存储过程。

常用Statement 方法:

  • execute (String sql):运行语句,返回是否有结果集
  • executeQuery (String sql):运行select语句,返回 ResultSet 结果集。
  • executeUpdate (String sql):运行insert/update/delete操作,返回更新的行数。
  • addBatch (String sql):把多条 sql 语句放到一个批处理中。
  • executeBatch():向数据库发送一批 sql 语句并执行。
  1. ResultSet 接口

ResulttSet 提供检索不同类型字段的方法,常用的有:

  • getString (int index)、getString (String columnName):获得在数据库里是varchar、char等类型的数据对象。
  • getFloat (int index)、getFloat (String columnName):获得在数据库里是Float类型的数据对象。
  • getDate (int index)、getDate (String columnName):获得在数据库里是Date类型的数据。
  • getBoolean (int index)、getBoolean (String columnName):获得在数据库里是Boolean类型的数据。
  • getObject(int index)、getObject(String columnName):获取在数据库里任意类型的数据。

ResultSet还提供了对结果集进行滚动的方法:

  • next ():移动到下一行
  • Previous ():移动到前一行
  • absolute (int row):移动到指定行
  • beforeFirst ():移动resultSet的最前面。
  • afterLast ():移动到resultSet的最后面。

使用后依次关闭对象及连接:ResultSet → Statement →Connection

三、使用JDBC的步骤

加载JDBC驱动程序 → 建立数据库连接Connection → 创建执行SQL的语句Statement → 处理执行结果ResultSet → 释放资源

  1. 注册驱动 (只做一次)

方式一:Class.forName(“com.MySQL.jdbc.Driver”);

  推荐这种方式,不会对具体的驱动类产生依赖。

方式二:DriverManager.registerDriver(com.mysql.jdbc.Driver);

  会造成DriverManager中产生两个一样的驱动,并会对具体的驱动类产生依赖。

  1. 建立连接
Connection conn = DriverManager.getConnection(url, user, password);

URL用于标识数据库的位置,通过URL地址告诉JDBC程序连接哪个数据库,URL的写法为:

  image.png

其他参数如:useUnicode=true&characterEncoding=utf8

  1. 创建执行SQL语句的statement
//Statement  
String id = "5";
String sql = "delete from table where id=" +  id;
Statement st = conn.createStatement();  
st.executeQuery(sql);  
//存在sql注入的危险
//如果用户传入的id为“5 or 1=1”,那么将删除表中的所有记录
//PreparedStatement 有效的防止sql注入(SQL语句在程序运行前已经进行了预编译,当运行时动态地把参数传给PreprareStatement时,即使参数里有敏感字符如 or '1=1'也数据库会作为一个参数一个字段的属性值来处理而不会作为一个SQL指令)
String sql = “insert into user (name,pwd) values(?,?)”;  
PreparedStatement ps = conn.preparedStatement(sql);  
ps.setString(1, "col_value");  //占位符顺序从1开始
ps.setString(2, "123456");     //也可以使用setObject
ps.executeQuery();
  1. 处理执行结果(ResultSet)
ResultSet rs = ps.executeQuery();  
While(rs.next()){  
    rs.getString("col_name");  
    rs.getInt(1);  
    //…
}
  1. 释放资源
// 数据库连接(Connection)非常耗资源,尽量晚创建,尽量早的释放 //都要加try catch 以防前面关闭出错,后面的就不执行了  
try {
     if (rs != null) {
         rs.close();
     }
} catch (SQLException e) {
     e.printStackTrace();
} finally {
    try {
         if (st != null) {
             st.close();
         }
     } catch (SQLException e) {
         e.printStackTrace();
     } finally {
         try {
             if (conn != null) {
                 conn.close();
             }
         } catch (SQLException e) {
             e.printStackTrace();
         }
     }
}

上文引自 JDBC详解 - ErBing - 博客园 (cnblogs.com) ,如有侵权请通知。

三、PreparedStatement 接口的解释和用法


PreparedStatement 是 Statement 接口的子接口

优点:

  1. 使用 PreparedStatement 接口可以防止 SQL 注入
  2. PreparedStatement 是预编译(Statement 每次执行sql语句,都要执行相关数据库的编译,而 PreparedStatement 的sql是一个模板 (可以类比函数),编译过程与执行是分开的,当为其参数赋予值时,实际上只是将值给传入进去,放进模板中,需要时取出插入数据即可,不需要继续编译。)的,对于批量处理可以大大提高效率。总的来说,区别在于前者编译执行一体化,后者属于先编译后执行。
  3. 可以重复使用同一SQL模板,给予其不同的参数来重复的使用。

第二点也就是为什么预编译能够防止SQL注入。

创建 PreparedStatement 对象

PreparedStatement ps = null;
try{
    ……
    String sql = "select studentNo from student where studentName = ?";
    ps = connection.prepareStatement(sql);
    ……
} catch (SQLException e) {
    ……
} finally {
    ps.close();
}

在使用 PreparedStatement 对象的同时,所有的参数都被用 ?符号表示,而为其参数赋值则需要用到 setXXX() 方法将值绑定到参数,其中 XXX 表示参数的数据类型

当你没有给参数赋予值,你会收到一个 SQLException

setXXX (int parementerIndex , XXX类型变量) ,每个参数的起始下标为1。

Statement 和 PreparedStatement 执行SQL语句方法的区别

PreparedStatement对象独有的executeQuery()方法是没有参数的,而Statement的executeQuery()是需要参数(SQL语句)的。因为在创建PreparedStatement对象时已经让它与一条SQL模板绑定在一起了,所以在调用它的executeQuery()和executeUpdate()方法时就不再需要参数了。

总结


  • JDBC 由一组使用 Java 语言编写的类和接口组成,可以为多种关系型数据库提供统一的访问方式。
  • JDBC API 是一套接口规范,数据库厂商或第三方中间件厂商根据这套接口规范提供针对不同数据库的数据库驱动
  • JDBC操作步骤
  • 加载JDBC驱动
  • 获取数据库连接
  • 创建SQL语句集,发送SQL语句,并得到返回结果
  • 处理返回结果
  • 每个JDBC驱动只对应一种数据库,甚至只对应某个版本的数据库
  • 数据库操作结束后,应该关闭数据库连接,释放系统资源。为了确保程序的执行,关闭数据库连接语句要放到 finally 语句块中
  • Connection 接口负责连接数据库并担任传达数据库的任务
  • Statement 接口负责执行 SQL 语句
  • ResultSet 接口负责保存和处理 Statement 接口执行后所产生的查询结果
  • SQL 注入是通过提交一段 SQL 代码,执行超出用户权限的数据库操作的攻击行为
  • PreparedStatement 接口能够提高代码的可读性、可维护性、SQL语句的执行性能和安全性
相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。   相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情: https://www.aliyun.com/product/rds/mysql 
相关文章
|
1月前
|
SQL Java 数据库连接
除了JDBC,还有哪些常见的数据库访问技术?
除了JDBC,还有哪些常见的数据库访问技术?
213 2
|
2月前
|
监控 Cloud Native Java
Quarkus 云原生Java框架技术详解与实践指南
本文档全面介绍 Quarkus 框架的核心概念、架构特性和实践应用。作为新一代的云原生 Java 框架,Quarkus 旨在为 OpenJDK HotSpot 和 GraalVM 量身定制,显著提升 Java 在容器化环境中的运行效率。本文将深入探讨其响应式编程模型、原生编译能力、扩展机制以及与微服务架构的深度集成,帮助开发者构建高效、轻量的云原生应用。
346 44
|
2月前
|
安全 Java API
Java Web 在线商城项目最新技术实操指南帮助开发者高效完成商城项目开发
本项目基于Spring Boot 3.2与Vue 3构建现代化在线商城,涵盖技术选型、核心功能实现、安全控制与容器化部署,助开发者掌握最新Java Web全栈开发实践。
362 1
|
3月前
|
安全 Java 编译器
new出来的对象,不一定在堆上?聊聊Java虚拟机的优化技术:逃逸分析
逃逸分析是一种静态程序分析技术,用于判断对象的可见性与生命周期。它帮助即时编译器优化内存使用、降低同步开销。根据对象是否逃逸出方法或线程,分析结果分为未逃逸、方法逃逸和线程逃逸三种。基于分析结果,编译器可进行同步锁消除、标量替换和栈上分配等优化,从而提升程序性能。尽管逃逸分析计算复杂度较高,但其在热点代码中的应用为Java虚拟机带来了显著的优化效果。
128 4
|
3月前
|
Java API Maven
2025 Java 零基础到实战最新技术实操全攻略与学习指南
本教程涵盖Java从零基础到实战的全流程,基于2025年最新技术栈,包括JDK 21、IntelliJ IDEA 2025.1、Spring Boot 3.x、Maven 4及Docker容器化部署,帮助开发者快速掌握现代Java开发技能。
792 1
|
4月前
|
人工智能 Java
Java多任务编排技术
JDK 5引入Future接口实现异步任务处理,但获取结果不够灵活。Java 8新增CompletableFuture,实现异步任务编排,支持流式处理、多任务组合及异常处理,提升执行效率与代码可读性,简化并发编程复杂度。
112 0
|
3月前
|
Java 测试技术 API
2025 年 Java 开发者必知的最新技术实操指南全览
本指南涵盖Java 21+核心实操,详解虚拟线程、Spring Boot 3.3+GraalVM、Jakarta EE 10+MicroProfile 6微服务开发,并提供现代Java开发最佳实践,助力开发者高效构建高性能应用。
628 4
|
2月前
|
安全 Cloud Native Java
Java 模块化系统(JPMS)技术详解与实践指南
本文档全面介绍 Java 平台模块系统(JPMS)的核心概念、架构设计和实践应用。作为 Java 9 引入的最重要特性之一,JPMS 为 Java 应用程序提供了强大的模块化支持,解决了长期存在的 JAR 地狱问题,并改善了应用的安全性和可维护性。本文将深入探讨模块声明、模块路径、访问控制、服务绑定等核心机制,帮助开发者构建更加健壮和可维护的 Java 应用。
251 0
|
3月前
|
JavaScript 安全 前端开发
Java开发:最新技术驱动的病人挂号系统实操指南与全流程操作技巧汇总
本文介绍基于Spring Boot 3.x、Vue 3等最新技术构建现代化病人挂号系统,涵盖技术选型、核心功能实现与部署方案,助力开发者快速搭建高效、安全的医疗挂号平台。
223 3
|
4月前
|
存储 Java Linux
操作系统层面视角下 Java IO 的演进路径及核心技术变革解析
本文从操作系统层面深入解析Java IO的演进历程,涵盖BIO、NIO、多路复用器及Netty等核心技术。分析各阶段IO模型的原理、优缺点及系统调用机制,探讨Java如何通过底层优化提升并发性能与数据处理效率,全面呈现IO技术的变革路径与发展趋势。
110 2
下一篇
oss云网关配置