彻底搞懂JDBC的运行过程

2023-10-28

转载自:https://blog.csdn.net/y277an/article/details/96937010

JDBC的作用

JDBC的全称是Java DataBase Connection,也就是Java数据库连接,我们可以用它来操作关系型数据库。JDBC接口及相关类在java.sql包和javax.sql包里。我们可以用它来连接数据库,执行SQL查询,存储过程,并处理返回的结果。

JDBC接口让Java程序和JDBC驱动实现了松耦合,使得切换不同的数据库变得更加简单。


JDBC的连接步骤

执行一次JDBC连接,分六个步骤进行:
1. 导入包

在程序中包含数据库编程所需的JDBC类。大多数情况下,使用 import java.sql.* 就足够了。
2. 注册JDBC驱动程序

需要初始化驱动程序,这样就可以打开与数据库的通信。
3. 打开一个连接

使用DriverManager.getConnection()方法来创建一个Connection对象,它代表一个数据库的物理连接。
4. 执行一个查询

需要使用一个类型为Statement或PreparedStatement的对象(两者区别看后文),并提交一个SQL语句到数据库执行查询。
5. 从结果集中提取数据

这一步中演示如何从数据库中获取查询结果的数据。使用ResultSet.getXXX()方法来检索的数据结果
6. 清理环境资源

在使用JDBC与数据交互操作数据库中的数据后,应该明确地关闭所有的数据库资源以减少资源的浪费。本文使用了try with resources方式关闭资源,这是JDK7的语法糖,读者可自行搜索。

完整代码如下。

//STEP 1. 导入包	
import java.sql.*;	
	
class JDBCExample {	
    // JDBC驱动包名和数据库的URL	
    static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";	
    static final String DB_URL      = "jdbc:mysql://localhost/test";	
	
    // 数据库名和密码自己修改	
    static final String USER = "username";	
    static final String PASS = "password";	
	
    public static void main(String[] args) {	
        String sql = "SELECT id, first, last, age FROM Employees";	
	
        //STEP 2: 注册JDBC驱动程序	
        try {	
            Class.forName(JDBC_DRIVER);	
        } catch (ClassNotFoundException e) {	
            e.printStackTrace();	
        }	
	
        // try with resources方式关闭资源。	
        //STEP 6: 清理环境资源	
        try (Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);	
             Statement stmt = conn.createStatement();	
             ResultSet rs = stmt.executeQuery(sql)) {	
	
            //STEP 3: 打开一个连接	
            System.out.println("Connecting to database...");	
//            Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);	
	
            //STEP 4: 执行一个查询	
            System.out.println("Creating statement...");	
//            Statement stmt = conn.createStatement();	
//            ResultSet rs = stmt.executeQuery(sql);	
	
            //STEP 5: 从结果集中提取数据	
            while (rs.next()) {	
                // 根据列名获取数据	
                int id = rs.getInt("id");	
                int age = rs.getInt("age");	
                String first = rs.getString("first");	
                String last = rs.getString("last");	
	
                // 显示结果	
                System.out.print("ID: " + id);	
                System.out.print(", Age: " + age);	
                System.out.print(", First: " + first);	
                System.out.println(", Last: " + last);	
            }	
        } catch (SQLException se) {	
            // 处理可能出现的错误	
            se.printStackTrace();	
        }	
        System.out.println("Goodbye!");	
    }	
}

JDBC的最佳实践

    数据库资源是非常昂贵的,用完了应该尽快关闭它。Connection, Statement, ResultSet等JDBC对象都有close方法,调用它就好了。

    在代码中必须显式关闭掉ResultSet,Statement,Connection,如果你用的是连接池的话,连接用完后会放回池里,但是没有关闭的ResultSet和Statement就会造成资源泄漏了。

    在finally块中关闭资源,保证即便出了异常也能正常关闭。

    大量相似的查询应当使用批处理完成。

    尽量使用PreparedStatement而不是Statement,以避免SQL注入,同时还能通过预编译和缓存机制提升执行的效率。

    如果你要将大量数据读入到ResultSet中,应该合理的设置fetchSize以便提升性能。

    你用的数据库可能没有支持所有的隔离级别,用之前先仔细确认下。

    数据库隔离级别越高性能越差,确保你的数据库连接设置的隔离级别是最优的。

    如果你需要长时间对ResultSet进行操作的话,尽量使用离线的RowSet。

JDBC是如何实现Java程序和JDBC驱动的松耦合?

JDBC API使用Java的反射机制来实现Java程序和JDBC驱动的松耦合。看一下上文的JDBC示例,你会发现所有操作都是通过JDBC接口完成的,而驱动只有在通过Class.forName反射机制来加载的时候才会出现。
这是Java核心库里反射机制的最佳实践之一,它使得应用程序和驱动程序之间进行了隔离,让迁移数据库的工作变得更简单。

Statement和PreparedStatement区别

    关系:PreparedStatement继承自Statement,两者都是接口

    区别:PreparedStatement可以使用占位符,而且是预编译的,批处理比Statement效率高

预编译

创建时的区别:

Statement statement = conn.createStatement();	
PreparedStatement preStatement = conn.prepareStatement(sql);
执行时的区别:
ResultSet rSet = statement.executeQuery(sql);	
ResultSet pSet = preStatement.executeQuery();

由上可以看出,PreparedStatement有预编译的过程,已经绑定sql,之后无论执行多少次,都不会再去进行编译,而Statement 不同,如果执行多次,则相应的就要编译多少次sql,所以从这点看,PreparedStatement的效率会比Statement要高一些。PreparedStatement是预编译的,所以可以有效的防止SQL注入等问题

占位符

PrepareStatement可以替换变量在SQL语句中可以包含?,可以用?替换成变量。

ps = conn.prepareStatement("select * from Employees where id=?");	
int sid = 1001;	
ps.setInt(1, sid);	
rs = ps.executeQuery();

而Statement只能用字符串拼接。

int sid = 1001;	
Statement stmt = conn.createStatement();	
ResultSet rs = stmt.executeQuery("select * from Employees where id=" + sid);

JDBC的ResultSet

在查询数据库后会返回一个ResultSet,它就像是查询结果集的一张数据表。

ResultSet对象维护了一个游标,指向当前的数据行。开始的时候这个游标指向的是第一行。如果调用了ResultSet的next()方法游标会下移一行,如果没有更多的数据了,next()方法会返回false。可以在for循环中用它来遍历数据集。

默认的ResultSet是不能更新的,游标也只能往下移。也就是说你只能从第一行到最后一行遍历一遍。不过也可以创建可以回滚或者可更新的ResultSet,像下面这样。
 

Statement stmt = con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);

当生成ResultSet的Statement对象要关闭或者重新执行或是获取下一个ResultSet的时候,ResultSet对象也会自动关闭。

可以通过ResultSet的getter方法,传入列名或者从1开始的序号来获取列数据。

ResultSet的不同类型

根据创建Statement时输入参数的不同,会对应不同类型的ResultSet。如果你看下Connection的方法,你会发现createStatement和prepareStatement方法重载了,以支持不同的ResultSet和并发类型。

ResultSet对象有三种类型。

    ResultSet.TYPE_FORWARD_ONLY:这是默认的类型,它的游标只能往下移。

    ResultSet.TYPE_SCROLL_INSENSITIVE:游标可以上下移动,一旦它创建后,数据库里的数据再发生修改,对它来说是透明的。

    ResultSet.TYPE_SCROLL_SENSITIVE:游标可以上下移动,如果生成后数据库还发生了修改操作,它是能够感知到的。

ResultSet有两种并发类型。

    ResultSet.CONCUR_READ_ONLY:ResultSet是只读的,这是默认类型。

    ResultSet.CONCUR_UPDATABLE:我们可以使用ResultSet的更新方法来更新里面的数据。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

彻底搞懂JDBC的运行过程 的相关文章

  • 游戏数据存储的四种常用方式

    原文地址 http blog csdn net xiaominghimi article details 6948046 首先向大家说句抱歉 可能一些童鞋看到我的微薄了 我说突然不想写博客了 是Himi的错 我不该发微薄让大家担心的 Him
  • 彻底搞懂JDBC的运行过程

    转载自 https blog csdn net y277an article details 96937010 JDBC的作用 JDBC的全称是Java DataBase Connection 也就是Java数据库连接 我们可以用它来操作关
  • 多线程实现一分钟插入1000万条数据

    首先我们需要建立一个线程类 继承Thread类 并实现run方法 1 获取数据库连接 2 编写插入的sql语句 3 关闭自动提交 conn setAutoCommit false 4 编写for循环 跟着那个的插入方法一样 5 将注入的信息
  • MySql安装版安装最新教程(附错误解决 )

    目录 1 安装版自定义安装 2 问题总结 1 安装版自定义安装 如果需要安装版安装 可参考另一篇博客 MySql压缩版安装最新教程 附错误解决 链接 MySql官网 滑到最下面 上面的是企业版下载 需要付费 我们下载开源的社区版 在这里我下
  • 复合查询

    复合查询 1 单表查询 查询工资高于500或岗位为MANAGER的雇员 同时还要满足他们的姓名首字母为大写的J select empno ename sal job from emp where sal gt 500 or job MANA
  • 分页(Paging) / SQL Server / Oracle

    分页 Paging SQL Server Oracle 虽然 DataGrid 控件自己带了一个分页处理机制 但它是将符合查询条件的所有记录读入内存 然后进行分页显示的 随着符合条件的记录数目增多 就会出现运行效率问题 或者至少是资源的利用
  • mysql8安装以及配置、参数优化

    1 配置bin到path 2 mysql解压版本在根目录创建my ini 3 初始化数据库 mysqld initialize console 这里会生成一个初始密码 需要记录下来 否则需要删除datadir目录重新初始化 D dev my
  • 【Hive报错】Hive报错Expression Not In Group By Key解决方法

    SQL例如以下会报错 select sum time as time roadCoding upstreamOrDownstream from historicalroaddata where 报以下roadcoding upstreamO
  • 数据库 SQL 遍历父子关系表(二叉树)获得所有子节点 所有父节点

    数据库 SQL 遍历父子关系表 二叉树 获得所有子节点 所有父节点 创建表 Create Table A IDInt fatherIDInt NameVarchar 10 Insert A Select 1 NULL tt Union Al
  • SQL中根据经纬度计算两点之间的直线距离

    最近接到一个需求获取当前用户的经纬度 然后计算与目标地的的距离 我自己也是看别人的博客学习 自己也做个记录吧 直接放出计算的公式 不想浪费时间的 直接看公式套进去就成 依次是纬度 纬度 经度 round 6378 138 2 ASIN SQ
  • 你知道什么是DBA吗?

    数据库管理员 英文是Database Administrator 简称DBA 这个职位对不同的人意味着不同的意义 一个小的软件开发工作室和一个分工高度明细的大公司相比 DBA的职责来得更加宽泛一些 一个公司 不管它是自己开发应用软件 还是购
  • Oracle数据单实例多实例服务示例

    在我们工作时 有时需要一个oracle实例被不同网段的ip访问 从而需要开通2个或以上的实例服务 如下为例子 listener ora文件内容 listener ora Network Configuration File oracle a
  • Mycat/Mysql主从复制搭建详解

    Mycat server 1 6 mysql 5 7 24 linux 工具下载地址 mycat mysql navivat 链接 https pan baidu com s 1KCmSgXYXs9O5vHMHIgnbAg 提取码 ukaq
  • 啥是ddl?

    我们在安装软件的时候 经常出现某一个dll文件丢失 无法安装 让人头痛不已 那么到底啥是ddl 还是有度娘好呀 下面是百度百科的词条 数据库模式定义语言DDL Data Definition Language 是用于描述数据库中要存储的现实
  • 什么叫持久化? 为什么持久化?(转)

    1 应用程序层次结构演变 这里本来应该有张描述应用程序结构演变的图 可是CSDN在这里上传不了 所以没有传上来 纵观几十年的计算机应用软件的演变过程 应用程序逐渐由单层体系结构发展为多层体系结构 最初应用软件只是在大型机上的单层应用程序 大
  • Python数据库操作手册

    数据库的操作在现在的Python里面已经变得十分的好用 有了一套API标准 下面的就是讲讲如何的去使用这套框架定义 此框架包含以下部分 模块接口 连接对象 游标对象 DBI辅助对象 数据类型与定义 如何实现的提示 从1 0到2 0的变化 例
  • MySql 笔记

    数据结构 B TREE 二叉树 顺序增长依次查询效率低 红黑树 数据多了深度越深 效率自然低了 HASH 查询条件限制 B TREE 度 degree 节段的数据存储个数 叶节点具有 相同的深度 叶节点的指针为空 节点的数据key从左到右递
  • 【SQL基础】SQL查询语句实例

    参考自 https www w3school com cn sql index asp 下面举实例 员工表 部门表 薪资等级表 附上sql语句 薪资等级表SALGRADE 部门表DEPT 员工表EMP CREATE TABLE DEPT D
  • oracle9i升级oracle10g

    author skate time 2009 09 11 网上看到一篇oracle9i升级oracle10g的文章 觉得不错 记录下来 你可以参考汪海的文章 http wzwanghai spaces live com 37AFBD116
  • (转载)我们需要什么样的字段类型

    数据库定义到char类型的字段时 不知道大家是否会犹豫一下 到底选char nchar varchar nvarchar text ntext中哪一种呢 结果很可能是两种 一种是节俭人士的选择 最好是用定长的 感觉比变长能省些空间 而且处理

随机推荐

  • Unity在运行时使用FBX SDK的API

    1 写在前面 本文主要一块学习关于Unity官方封装的AutoDesk的FBX SDK的API的C 版本包 最初该包的本意是想让开发者在编辑器模式下使用 但是官方也提供了在运行时对于该包的支持 2 获取Autodesk FBX SDK fo
  • 竞赛 基于机器视觉的手势检测和识别算法

    0 前言 优质竞赛项目系列 今天要分享的是 基于深度学习的手势检测与识别算法 该项目较为新颖 适合作为竞赛课题方向 学长非常推荐 更多资料 项目分享 https gitee com dancheng senior postgraduate
  • LeetCode:228(Python)—— 汇总区间(简单)

    汇总区间 概述 给定一个无重复元素的有序整数数组 nums 返回恰好覆盖数组中所有数字的最小有序区间范围列表 也就是说 nums 的每个元素都恰好被某个区间范围所覆盖 并且不存在属于某个范围但不属于 nums 的数字 x 输入 nums 0
  • js逆向补环境示例代码1

    在官方文档 内置对象中的object下很多属性都可以用来检测环境 Object JavaScript MDN 拿Object getOwnPropertyDescriptor 来做示例笔记 在文档中它的说明 Object getOwnPro
  • matlab erf erfi,误差函数

    误差函数 在数学中 误差函数 也称之为高斯误差函数 是一个特殊函数 即不是初等函数 其在概率论 统计学以及偏微分方程中都有广泛的应用 它的定义如下 erf x 1 x x e t 2 d t 2 0 x e t 2 d t displays
  • 关于pthread_rwlock_t读写锁产生死锁的情况

    对于pthread rwlock t读写锁 一个线程持有着写锁 又去加 该锁的 读锁 可能会产生死锁 一个线程持有着 读或者写 锁 又去加 该锁的 写锁 可能会产生死锁 此时pthread rwlock rdlock和pthread rwl
  • 49黑马QT笔记之利用TCP传输文件

    49黑马QT笔记之利用TCP传输文件 前提 黑马视频的代码第二次不能传输的原因是因为 客户端在第一次传输完成后 isStart false 即第二次无法接收文件信息并打开文件 所以他会出现 write device not open 我们在
  • 使用 FeignClient 进行微服务交互(微服务接口互相调用)

    先写一个公共方法 public String getSettingValue String name Map
  • Ros小车应用篇(一)——Ros小车wifiQT上位机

    Ros小车多功能QT上位机 代码仓库 https github com zhuchen99899 RosCar tree master Ros car pid test 小车嵌入式控制可以查看我的博客 https blog csdn net
  • Win10 开机密码破解

    1 开机 当出现Windows图标时 就强制关机 重复2 3次 系统便会进入自动修复 2 高级设置 gt 疑难解答 gt 高级选项 gt 命令提示符 3 依次输入 cd c windows system32 ren sethc exe ab
  • 为什么用GIF做埋点?

    原因 防止跨域拦截 一般而言 打点域名都不是当前域名 所以所有的接口请求都会构成跨域 而跨域请求很容易出现由于配置不当被浏览器拦截并报错 这是不能接受的 但图片的 src 属性并不会跨域 并且同样可以发起请求 防止阻塞页面加载 影响用户体验
  • linux FIO命令详解(一):磁盘IO测试工具 fio (并简要介绍iostat工具)

    FIO介绍 FIO是测试IOPS的非常好的工具 用来对磁盘进行压力测试和验证 磁盘IO是检查磁盘性能的重要指标 可以按照负载情况分成照顺序读写 随机读写两大类 FIO是一个可以产生很多线程或进程并执行用户指定的特定类型I O操作的工具 FI
  • 【技能树笔记】网络篇——练习题解析(一)

    目录 一 认识身边的计算机网络 1 1 常见的网络设备 1 2 网络中拓扑的分类 二 认识网络模型 2 1 网络模型概述 2 2 OSI模型 2 2 1 OSI参考模型 2 2 2 数据的加密和解密 2 3 TCP IP模型 2 3 1 T
  • WPF后台动态创建Grid行与列,并将控件添加到Grid中的指定行指定列

  • 算法基础复盘笔记Day10【动态规划】—— 线性DP

    作者主页 欢迎来到我的技术博客 个人介绍 大家好 本人热衷于Java后端开发 欢迎来交流学习哦 如果文章对您有帮助 记得关注 点赞 收藏 评论 您的支持将是我创作的动力 让我们一起加油进步吧 第一章 线性DP 一 数字三角形 1 题目描述
  • 如何使用 AWS 和 ChatGPT 创建最智能的多语言虚拟助手

    上周ChatGPT发布了 每个人都在尝试令人惊奇的事情 我也开始使用它并想尝试它如何使用AWS的AI 服务进行集成 结果非常棒 在这篇文章中 我将逐步解释我是如何创建这个项目的 这样你也可以做到 最重要的是 您无需成为AI 专家即可创建它
  • openvino是啥

    英特尔发布的开源框架 用于深度学习的推理优化与模型部署 openvino具体使用方法还是看官方文档比较好https docs openvino ai 支持多种框架 tensorflow caffe pytorch mxnet keras o
  • Wireshark的抓包和分析,看这篇就够了!

    点击上方蓝字 关注 程序IT圈 WireShark是一个网络封包分析软件 网络封包分析软件的功能是撷取网络封包 并尽可能显示出最为详细的网络封包资料 Wireshark使用WinPCAP作为接口 直接与网卡进行数据报文交换 在网络封包和流量
  • 【DDD架构】

    DDD domain driven design 领域驱动设计模型 一 DP domain primitive 1 什么是DP 2 为什么要用DP 2 1 API接口清晰度 2 2 数据验证和错误处理 2 3 业务代码的清晰度 3 DP原则
  • 彻底搞懂JDBC的运行过程

    转载自 https blog csdn net y277an article details 96937010 JDBC的作用 JDBC的全称是Java DataBase Connection 也就是Java数据库连接 我们可以用它来操作关