Java学习笔记21——使用JDBC访问MySQL数据库

JDBC(Java Database Connectivity,Java数据库连接)是应用程序编程借口(API),描述了一套访问关系数据库的标准Java类库。可以在程序中使用这些API,连接到关系数据库,执行SQL语句,对数据进行处理。JDBC不但提供了访问关系数据库的标准API,还为数据库厂商提供了一个标准的体系结构,让厂商可以为自己的数据库提供JDBC驱动程序,这些驱动程序可以让Java应用程序直接访问厂商的数据库产品,从而提高了Java程序访问数据库的效率。

1、JDBC驱动程序的类型:

JDBC驱动程序可以分为4类,分别是:

  • 1)JDBC-ODBC桥:通过ODBC访问数据库。
  • 2)部分本地API,部分Java驱动程序:大都C语言编写,依赖具体的平台。
  • 3)JDBC网络纯Java驱动程序:利用中间件的应用服务器来访问数据库,应用服务器作为数据库的网关,客户端通过它可以连接到不同的数据库服务器,如WebLogic服务器。
  • 4)本地协议纯Java驱动程序:目前,绝大多数数据库厂商支持客户程序通过网络直接与数据库通信的网络协议来直接访问数据库。这种类型的JDBC驱动程序完全用Java编写,通过与数据库建立直接的套接字连接,采用具体厂商的网络协议把JDBC API调用转换为直接的网络调用。这种类型的驱动是访问数据库效率最高的,不过,由于每个数据库厂商有自己的协议,因此访问不同厂商的数据库,需要不同的JDBC驱动程序。

2、下载MySQL JDBC 驱动

MySQL的JDBC 驱动程序没有包含在数据库的安装包中,需要单独下载,下载的网址为:MySQL :: Download Connector/Jicon-default.png?t=N7T8https://dev.mysql.com/downloads/connector/j/在浏览器中输入上面的网址,进入MySQL的JDBC 驱动程序的下载页面,如下图:

在上图下拉框中选择“Platfrom Independent”,然后出现如下图,Window平台下载zip文件下载。

将zip文件解压缩,将出现一个类似mysql-connector-j-8.3.0.jar的文件,它就是MySQL数据库的JDBC驱动。

3、JDBC API

JDBC API包含在JDK中,被分为两个包:java.sql和javax.sql。java.sql包中定义了访问数据库的接口和类,其中一些接口由驱动程序提供商来实现。

在开发数据库访问程序时,经常会编写如下的代码。

String url = "jdbc:mysql://127.0.0.1:3306/mysql";     
String username = "root"; 
String password = "2005Liuzx0302";// 加载数据库驱动
Class.forName("com.mysql.jdbc.Driver");		
conn = DriverManager.getConnection(url,username,password);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("select * from user_info");

从上面代码可以看出利用JDBC访问数据库有统一的步骤。

1)首先调用Class类的forName()方法加载要访问的数据库的JDBC驱动类,

2)接下来调用Java的JDBC API(java.sql包)中的DriverManager类中的getConnection方法建立与数据库的连接,

3)然后调用Connection对象的createStatement方法,

4)最后调用Statement对象的executeQuery方法执行SQL语句得到ResultSet对象,就可以利用该对象来获取数据库中的数据了。

当然,最后要关闭数据库连接对象,释放数据库连接资源。

4、加载并注册数据库驱动

使用JDBC方法数据库,首先就是要调用Class类的forName方法加载要访问数据库厂商的JDBC驱动。了解这行代码背后发生的事情让我感觉有些豁然开朗。

1)Driver接口

java.sql.Driver是所有JDBC驱动程序需要实现的接口。这个接口是提供给数据库厂商使用的,不同厂商实现该接口的类名是不同的。常见的有:

  • com.microsoft.jdbc.sqlserver.SQLServerDriver:微软SQL Server2000版本驱动
  • com.microsoft.sqlserver.jdbc.SQLServerDriver:微软SQL Server2005及以后版本驱动
  • oracle.jdbc.driver.OracleDriver:是Oracle的JDBC驱动的类名,Oracle安装目录下jdbc目录中
  • com.mysql.cj.jdbc.Driver:是MySQL 8.0.x版本的驱动的类名。

Driver接口提供了一个connection方法,用来建立到数据库的连接,该方法的签名如下:

Connection connect(String url,Properties info) throws SQLException

开发人员在程序中不需要直接去访问这些实现了Driver接口的类,而是由Java的JDK 中的JDBC API(java.sql)中的驱动程序管理器类提供的方法来建立数据库连接,通过驱动程序管理器类的getConnection()方法来获取数据库连接。

2)深入理解JDBC的加载与注册驱动背后发生的事情

加载JDBC驱动是调用Class类的静态方法forName,向其传递要加载的JDBC驱动的类名。在运行时,类加载从CLASSPATH路径中定位和加载JDBC驱动类。在加载驱动程序后,需要注册驱动程序的一个实例。

DriverManager类是属于JDBC API(java.sql包)中提供的,用来负责管理加载的驱动程序,这个类中的所有方法都是静态的,在DriverManager类中提供了registerDriver方法来注册驱动程序类的实例,该方法的签名如下:

public statcic void registerDriver(Driver driver) throw SQLException

需要清楚的是,通常不需要开发人员在程序中直接调用registerDriver方法来注册驱动程序的实例,因为实现Driver接口的驱动程序类都包含了一个静态代码块,在这个静态代码块中,会调用DriverManager.registerDriver方法来注册自身的的一个实例。当使用Class类的forName方法在数据库驱动程序类的时候,会自动执行该静态代码块,从而注册驱动程序的一个实例,这样使用DriverManager.getConnection方法,就返回相应的驱动程序的数据库连接(Connection)对象。

下面是MySQL 驱动程序类的代码片段:

public class Driver extends NonRegisteringDriver implements java.sql.Driver {//// Register ourselves with the DriverManager//static {try {java.sql.DriverManager.registerDriver(new Driver());} catch (SQLException e) {throw new RuntimeException("Can't register driver!");}}...}

从上面代码看,加载数据库厂商的驱动类,会自动执行该类的静态代码块,调用JDBC的驱动管理类DriverManager.registerDriver方法,并传入参数(new Driver())注册该厂商自身的驱动实例。

5、建立数据库连接

调用JDBC的DriverManager类的getConnection方法建立数据库连接,上面提到DriverManager类在java.sql包中,其中方法都是静态的,所以可以直接通过类名DriverManager.getConnection()来调用。在DriverManager类中重载了3个getConnection方法:

1)public static Connection getConnection(String url) throws SQLException

该方法通过给出的数据库URL建立到数据库的连接。

2)public static Connection getConnection(String url,String user,String password) throws SQLException

该方法除了需要数据库URL,还需要用户名和密码来建立到数据库的连接。

3)public static Connection getConnection(String url,Properties info) throws SQLException

该方法需要数据库URL和java.util.Properties对象。Properties对象包含了用于特定数据库所需要的参数,以键值对的方式指定连接参数,来建立到数据库的连接。

JDBC URL用于标识一个被注册的驱动程序,驱动程序管理器通过这个URL来选择正确的驱动程序,从而建立到数据库的连接。JDBC URL的语法如下:

jdbc:subprotocol:subname

整个URL用冒号(:)被分成了3个部分。

协议:在上面语法中,jdbc为协议,在JDBC中,它是唯一允许的协议,即总是它,只能是它。

子协议(subprotocl):子协议用于标识一个数据库驱动程序。

子名称(subname):子名称的语法与具体的驱动程序相关,不同驱动语法不尽相同。

常用数据可的JDBC URL:

SQL Server2005及以后:jdbc:sqlserver://localhost:1433;databasename=pubs

Oracle9i、10g、11g:jdbc:oracel:thin@localhost:1521:ORCL

MySQL8.0.x:jdbc:mysql://localhost:3306/databasename?userSSL=false&serverTimezone=UTC

  • userSSL=false: 这个参数指示JDBC驱动程序不要使用SSL来加密与MySQL服务器的连接。在某些情况下,为了简化配置或出于性能考虑,你可能想要禁用SSL。但请注意,禁用SSL可能会降低连接的安全性。
  • serverTimezone=UTC: 这个参数设置MySQL服务器使用的时区为UTC(协调世界时)。这有助于避免在Java应用程序和MySQL服务器之间由于时区差异而可能产生的时间问题。

serverTimezone=UTC 并不是JDBC连接MySQL时必须的参数。这个参数的主要用途是告诉JDBC驱动程序期望从MySQL服务器接收的时间戳使用哪个时区。如果不指定这个参数,JDBC驱动程序通常会使用系统的默认时区来解析时间戳,这可能导致在Java应用程序和MySQL服务器之间出现时区相关的问题。

如果你确定你的Java应用程序和MySQL服务器使用的时区是一致的,或者你愿意让Java应用程序使用系统的默认时区来解析时间戳,那么你可以省略这个参数。

然而,在实际应用中,为了避免潜在的时区问题,很多开发者会选择明确指定 serverTimezone 参数。特别是当你的应用程序需要处理跨时区的数据,或者当你的应用程序和数据库服务器部署在不同的地理位置时,指定时区参数会是一个好习惯。

另外,需要注意的是,除了 serverTimezone 参数,MySQL JDBC驱动程序还提供了其他与时区相关的参数,如 useLegacyDatetimeCode=false 和 useSSL=false 等。这些参数可以根据你的具体需求进行配置。

总的来说,是否指定 serverTimezone=UTC 取决于你的具体应用场景和需求。如果你不确定是否需要它,或者你的应用程序可能会受到时区问题的影响,那么建议添加这个参数以确保时间戳的正确处理。

6、访问数据库

数据库连接被用于向数据库服务器发送命令和SQL语句,在连接建立后,需要对数据库进行访问,执行SQL语句。在java.sql包中提供了3个接口,分别定义了对数据库调用的不同方式,分别是:Statement、PreparedStatement、CallableStatement。

1)Statement

调用Connnect对象的createStatement方法创建一个Statement对象。Statement对象用于执行静态的SQL语句,返回执行的结果。在Connection接口中定义了createStatement()方法,如下:

Statement createStatement() throws SQLException,常用来执行没有参数的SQL语句。

Statement接口中定义了如下的方法执行SQL语句:

  • ResultSet executeQuery(String sql) throws SQLException,该方法执行参数sql指定的SQL语句,返回一个ResultSet对象。ResultSet对象用于查看执行的结果。
  • int exceuteUpdate(String sql) throws SQLException,该方法执行参数sql指定的insert 、update或delete语句。该方法也可以用来执行SQL DDL 语句,必须创建表。
  • boolean execute(String sql) throws SQLException,该方法执行返回多个结果集的SQL语句。在某些情况下,一条SQL语句可以返回多个结果集或者更新行数。在通常情况下,不使用这个方法。除非要执行返回多个结果集的存储过程或者动态执行一个未知的SQL串。如果使用该方法,就必须使用getResultSet()或者getUpdateCount()方法获取结果,并且调用getMoreResults()方法来访问下一个结果集。如果返回的第一个结果是一个ResultSet对象,那么这个方法返回的是true;如果返回的是一个更新的行数或者没有结果,那么返回的是false
  • int[] executeBatch() throws SQLException,该方法允许向数据库提交一批命令,然后一起执行。如果所有的命令都成功执行,那么返回值是一个更新行数的数组。数组中的每一个int元素都是按照加入命令的先后顺序来存储的,表示了相应命令的更新行数。可以使用addBatch()方法将SQL命令加入到命令列表中。

2)PreparedStatement

在程序中传递的SQL语句在执行前需要被预先编译,包括语句分析、代码优化等,然后才能被数据库引擎执行。如果重复执行只有参数不同的SQL语句,则程序效率会比较低。这就是PreparedStatement使用比Statement多的原因。

如果要用不同的参数来多次执行同一个SQL语句,推荐使用PreparedStatement对象。PreparedStatement接口是继承Statement接口,它的对象表示一条预编译过的SQL语句。PreparedStatement对象所代表的SQL语句中的参数使用问号(?)来表示,调用PreparedStatement对象的setXxx方法来设置这些参数。setXxx方法有两个参数,第一个参数是要设置SQL语句中的参数索引(从1开始),第二个参数是要设置的SQL语句中的参数的值。

conn = DriverManager.getConnection(url,user,password);
Statement stmt = conn.createStatement();
stmt.executeUpdate("create table emp(id,INT,name VARCHAR(10),hiredate DATE");PreparedStatement pstmt = conn.prepareStatement("insert emp(?,?,?)");pstmt.setInt(1,1);
pstmt.setString(2,"liuzx");
pstmt.setDate(3,java.sql.Date.valueOf("2005-3-3"));
pstmt.executeUpdate();pstmt.setInt(1,2);
pstmt.setString(2,"renrui");
pstmt.setDate(3,java.sql.Date.valueOf("1976-9-19"));
pstmt.executeUpdate();

针对不同类型的参数,需要使用对应的setXxx方法,尤其对应数据库日期类型的Java类型是java.sql.Date而不是java.util.Date(虽然java.sql.Date是java.util.Date的子类),MySQL数据库中的数据类型与Java中的数据类型有一定的对应关系,需要注意。

3)ResultSet

ResultSet对象以逻辑表格的形式封装了执行数据库操作的结果集,ResultSet对象维护了一个指向当前数据行的游标,在初始的时候,游标在第一行之前,调用ResultSet对象的next方法移动到游标的第一行,next方法移动到游标的下一行,如果新的数据行有效(有数据),则返回true,否则返回false。通过判断这个方法的返回值,可以循环读取结果集中的数据库,直到最后。

该方法如下:

boolean next() throws SQLException

在ResultSet接口中定义了很多方法来获取当前行中列的数据,根据表中字段类型的不同,采用不同的方法来获取数据。如:getBoolean()、getInt()、getLong()、getString()、getDate()等。

在上面这些方法中,提供了两种形式的调用:一种是以列的索引作为参数(索引值从1开始),另一种是以列的名字作为参数。例如对于getString()方法,有下面两种形式:

  • String getString(int columnIndex) throws SQLException
  • String getString(String columnName) throws SQLException

如果不知道要获取的列数据的类型,则可以一律采用getString()方法来得到一个String类型的数据。

3.1)对于要遍历结果集ResultSet,利用ResultSet对象的next方法,循环取出每行的数据。需要注意的是,在ResultSet对象初始化的时候,ResultSet对象的游标指向第一行之前,所以需要先调用一次next方法(通常在while循环的条件判断中调用),将游标移动到第一行,读取最后一行后,再次执行next方法则返回false,while循环也就结束,完成了ResultSet结果集的遍历(从第一行到最后一行)。

try(rs) {while(rs.next()) {System.out.print(rs.getString("title") + "\t");System.out.print(rs.getString("author") + "\t");System.out.print(rs.getFloat("price") + "\t");System.out.println();}
}

在Java中,当你看到try后面直接跟着一对圆括号并包含一个或多个对象时,这通常是Java 7引入的“try-with-resources”语句的用法。这个特性主要用于自动管理实现了AutoCloseableCloseable接口的资源,如数据库连接、文件流等,确保在try块执行完毕后,这些资源能够被正确地关闭,即使发生异常也是如此。

AutoCloseable接口是java.lang包中的一个标记接口,它定义了一个close()方法,用于释放资源。任何实现了这个接口的对象都可以用在try-with-resources语句中。

在上面的代码中,当try块执行完毕后,rs对象的close()方法会自动被调用,无论是否发生了异常。这使得资源的管理更加简洁和安全,避免了因为忘记关闭资源而导致的潜在问题,如内存泄漏或文件句柄泄漏等。

这种结构特别适用于那些需要在finally块中关闭的资源,因为它自动处理了资源的关闭逻辑,使得代码更加清晰和易于维护。

3.3)多个条件的SQL语句,在应用中动态构造查询语句,往往可能需要多个不同条件,因此需要进行判断,并在程序中拼接and条件,可是while子句后的第一个条件是没有and关键字的,所以往往做法是判断是否有一个条件了,后面才好拼接“and”字符串。为了避免复杂的if判断,通常做法是在where子句后附加一个恒等条件:1=1,这样就简化了条件的字符串拼接,只要某个条件存在,就统一拼接:and  field=value,例如:

StringBuffer sb = new StringBuffer("select * from bookinfo where 1=1");
// and前有一个空格
sb.append(" and title=" + title);
sb.append(" and author=" + authoor);ResultSet rs = stmt.executeQuery(sb.toString());

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/757693.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

IDEA Git恢复DropCommit删除的提交

刚刚Dorp commit了,本地代码也被删除了,如何恢复呢, 从项目中登录git,找到刚刚的commit代码,如下所示:输入命令git reflog 复制代码,到idea中,打开GIt,找到RESET HEAD, …

初始 Navicat BI 工具

早前,海外 LearnBI online 博主 Adam Finer 对 Navicat Charts Creator 这款 BI(商业智能)工具进行了真实的测评。今天,我们来看下他对 Navicat BI 工具的初始之感,希望这能给用户一些启发与建议。LearnBI online 作为…

《计算机考研精炼1000题》为你考研之路保驾护航

创作背景 在这个充满挑战与竞争的时代,每一位考生在备战研究生考试的过程中,都希望通过更多符合考纲要求的练习题来提高自己的知识和技能。为了满足这一需求,我们精心策划和编辑了这本《计算机考研精炼1000题》。在考研政治和考研数学领域&a…

springboot283图书商城管理系统

图书商城管理系统 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本图书商城管理系统就是在这样的大环境下诞生,其可以帮助管理者在短时间内处理…

耳机壳UV树脂制作私模定制耳塞需要什么样的设备和技术?

制作私模定制耳塞需要使用到一些特定的设备和技术,包括但不限于以下内容: 耳模制作工具:用于获取用户耳型的耳模制作工具,如硅胶、橡皮泥等。需要使用熟练的手法和技术,确保耳模的准确性和稳定性。UV树脂:…

社交变革:探索Facebook的魔力

社交媒体平台的崛起已经改变了我们与世界的交互方式,而Facebook作为其中的巨头,其影响力和魔力更是不可忽视。本文将深入探讨Facebook如何引领社交变革,并探索其背后的魔力所在。 连接世界的纽带 Facebook的独特之处在于它作为一个社交平台&…

「滚雪球学Java」:安全(章节汇总)

🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,助你一臂之力,带你早日登顶🚀,欢迎大家关注&&收藏!持续更新中,up!up!up!&#xf…

【视频异常检测】Diversity-Measurable Anomaly Detection 论文阅读

Diversity-Measurable Anomaly Detection 论文阅读 Abstract1. Introduction2. Related Work3. Diversity-Measurable Anomaly Detection3.1. The framework3.2. Information compression module3.3. Pyramid deformation module3.4. Foreground-background selection3.5. Trai…

JavaScript实现简单的表单验证

关键代码&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><s…

ChatGPT在大气科学领域建模、数据分析、可视化与资源评估中的高效应用及论文写作

深度探讨人工智能在大气科学中的应用&#xff0c;特别是如何结合最新AI模型与Python技术处理和分析气候数据。课程介绍包括GPT-4等先进AI工具&#xff0c;旨在帮助学员掌握这些工具的功能及应用范围。课程内容覆盖使用GPT处理数据、生成论文摘要、文献综述、技术方法分析等实战…

HTML案例-1.标签练习

效果 源码 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title> </head&g…

物资管理系统建设方案

二、 项目概述 2.1 项目背景 2.2 现状分析 2.2.1 业务现状 2.2.2 系统现状 三、 总体需求 3.1 系统范围 3.2 系统功能 3.3 用户分析 3.4 假设与依赖关系 四、 功能需求 五、 非功能性需求 5.1 用户界面需求 5.2 软硬件环境需求 5.3 产品质量需求 5.4 接口需求 …

高效文件管理,批量复制文件夹名称 ,轻松提升工作效率

在信息爆炸的时代&#xff0c;电脑中的文件夹数量与日俱增&#xff0c;管理和整理这些文件夹成为一项繁琐的任务。您是否曾因为需要复制大量文件夹的名称而感到苦恼&#xff1f;现在&#xff0c;我们为您带来了一款能够一键批量复制文件夹名称的神奇工具&#xff0c;让您的效率…

在SAP BAS中创建你的第一个Fiori项目

1. 前言 本文将通过step by step的方式介绍如何在SAP Business Studio中创建一个Fiori项目&#xff0c;并通过Mock Data启动Fiori应用程序。 2. Demo Step1: 登录BAS并创建Dev Space Step2: 进入创建好的Dev Space&#xff0c;通过Get Started页面&#xff0c;选择New Projec…

STM32-DMA数据转运

DMA进行转运的条件 1&#xff1a;开关控制&#xff0c;DMA_CMD必须使能2&#xff1a;传输计数器必须大于03&#xff1a;触发源必须有触发的信号

Zookeeper(五)Zokeeper 环境搭建与Curator使用

目录 一 环境搭建1.1 单机环境搭建1.2 可视化工具ZooKeeper Assistant1.3 集群环境搭建 二 常用命令1.1 命令行语法1.2 数据节点信息1.3 节点类型 三 CuratorAPI使用3.1 依赖3.1 创建会话3.2 基本使用增删改查3.3 ACL权限控制3.4 分布式锁3.5 分布式计数器3.6 分布式Barrier3.7…

婴儿洗衣机硬核测评:希亦、鲸立、小吉婴儿洗衣机性能大比拼!

如果你非常注重婴儿衣物的卫生问题&#xff0c;那么婴儿洗衣机则是非常理想的选择。毕竟&#xff0c;在婴儿吃奶或者接触其他材料时&#xff0c;其抵抗力是比较弱的&#xff0c;再加上普通洗衣机无法对婴儿的衣物进行有效的消毒处理&#xff0c;轻则会对婴儿的健康造成威胁&…

基于 HBase Phoenix 构建实时数仓(5)—— 用 Kafka Connect 做实时数据同步

目录 一、总体架构 二、安装配置 MySQL 1. 创建 mysql 用户 2. 建立 MySQL 使用的目录 3. 解压安装包 4. 配置环境变量 5. 创建 MySQL 配置文件 6. MySQL 系统初始化 7. 启动 mysql 服务器 8. 创建 dba 用户 三、配置 MySQL 主从复制 四、安装部署 Kafka Connector…

23.python标准库之turtle库

一、窗体函数 turtle.setup(width, height, startx, starty) width:窗口宽度 height:窗口高度 startx:窗口与屏幕左侧距离&#xff08;单位象素&#xff09; starty:窗口与屏幕顶部距离&#xff08;单位象素&#xff09; 二、画笔状态函数 三、画笔运动函数

Java字符串精通之旅:从新手到专家

目录 一、字符串的创建 1.直接赋值 2.使用构造方法 二、字符串不可变性 三、常用操作 1.字符串长度 2.连接字符串 3.格式化字符串 四、示例代码&#xff1a;String类应用 五、String中常用的方法 在Java编程世界里&#xff0c;字符串无疑是最常用的数据类型之一。不论…