Java总结:JDBC连接操作数据库(一)

2023-07-01 15:44:13 浏览数 (2)

前言

Java Database Connectivity简称JDBC,属于Java核心API的一部分,是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口。支持ANSI SQL-92标准,通过调用这些类和接口提供的成员方法,我们可以方便地连接各种不同的数据库,进而使用标准的SQL命令对数据库进行查询、插入、删除、更新等操作。

一、JDBC结构

1.Java程序

主要功能是根据JDBC方法实现对数据库的访问和操作。

主要任务有:请求与数据库建立连接,向数据库发送SQL请求,为结果集定义存储应用和数据类型,查询结果,处理错误,控制传输、提交及关闭连接等。

2.JDBC管理器

即驱动程序管理器,动态地管理和维护数据库查询查询所需要的所有驱动程序对象,实现Java程序与特定驱动程序的连接。

主要任务有:为特定数据库选择驱动程序,处理JDBC初始化调用,为每个驱动程序提供JDBC功能的入口,为JDBC调用执行参数等

3.驱动程序

主要任务:建立与数据库的连接,向数据库发送请求,用户程序请求是执行编译,将错误代码格式化成标准的JDBC错误代码。

编程所使用的数据库系统不同,所需要的驱动程序也有所不同。

4.数据库

按数据结构来存储和管理数据的计算机软件。

常见的数据库比如mysql、Oracle、SqlServer等。

二、JDBC编程的步骤

一次完整的JDBC实现过程分为以下几步:

1、导入包

在程序首部将相关的包导入程序

代码语言:javascript复制
import java.sql.*;
2、加载驱动程序

使用Class.forName()方法来加载相应的驱动程序。不同数据库所需要加载的驱动程序也不同:

代码语言:javascript复制
// 加载mysql的驱动程序
Class.forName("com.mysql.jdbc.Driver");

//加载oracle的驱动程序
Class.forName("oracle.jdbc.driver.oracleDriver");
3、设置JDBC的连接地址信息

指定JDBC要连接的地址、端口、数据库、用户名、密码等信息

代码语言:javascript复制
String username = "root";
String password = "root";
String url = "jdbc:mysql://localhost:3306/test";

// 如果要往表中插入中文,还需要设置编码为utf-8
String url = "jdbc:mysql://localhost:3306/test?seUnicode=true&characterEncoding=utf8";

其中,"jdbc:mysql"是连接协议,“localhost”是连接地址,“3306”是mysql的连接端口(mysql的默认连接端口是3306),“test”是要连接操作的数据库。

4、创建数据库连接

DriverManager 类中的getConnection() 方法用上一步设置好的url作为参数来创建一个连接对象,并返回这个连接对象给Connection的实例。

代码语言:javascript复制
//url是上一步创建的连接地址
Connection conn = DriverManager.getConnection(url,username,password);
5、使用SQL语句操作数据库

JDBC中执行SQL语句可以使用Statement接口以及其子接口PreparedStatement接口,下面分别使用不同接口来举例简单说明其用法:

5.1.Statement接口方法创建表:
代码语言:javascript复制
/**
* 例子:Statement接口执行创建表,并且插入一组数据
*/

// 在当前数据库下创建一个学生表,表中包含主键字段id、姓名name、以及更新时间updatetime
String sql1 = "create table student(id int NOT NULL AUTO_INCREMENT primary key,name char(10),updateTime Datetime)";
// 向创建的student表添加一组信息
String sql2 = "insert into student(name,updatetime) values('qwe',sysdate())";
// 创建一个Statement对象
Statement st = conn.createStatement();
// 用executeUpdate()函数执行不返回任何内容的sql语句,如INSERT、UPDATE、DELETE以及其他DDL(数据定义语言)等。其参数为SQL语句
// 执行建表SQL语句
st.executeUpdate(sql1);
// execute()函数可以执行传进来的任意SQL语句
// 执行插入数据的SQL语句
st.execute(sql2);
// 释放资源
st.close();
5.2.PreparedStatement接口:
代码语言:javascript复制
/**
* 例子:PreparedStatement接口执行查询表中数据的SQL语句
*/

String sql3 = "select * from student";
// 创建一个PreparedStatement对象,同时对传入的SQL语句进行预编译
PreparedStatement ps = conn.prepareStatement(sql3);
// PreparedStatement接口中的execute()方法是没有参数的,因为SQL语句在创建对象时已传入并且预编译了

ResultSet result = ps.executeQuery();
while(rs.next()){
    // 通过索引来获取查询到的值
    int id = rs.getInt(1);
    String name = rs.getString(2);
    // 通过列名来获取查询到的值
    Date date = rs.getDate("updateTime");
}

// 释放资源
ps.close();
6、关闭连接

用完就要释放所连接的数据库及JDBC资源,关闭与数据库的连接

代码语言:javascript复制
conn.close();

上面就是是JDBC编程的基本流程,下面对这个过程中涉及到的一些类与方法做简单介绍:

三、相关的类与方法

1、DriverManager类 ——管理驱动

用于管理一组JDBC驱动程序的基本服务。

官方文档介绍:DriverManager (Java Platform SE 8 ) (langp.wang)

其常用成员方法如下:

返回值

方法体

说明

static Connection

getConnection(String url)

用指定的数据库URL来创建连接

static Connection

getConnection(String url, Properties info)

用指定的数据库URL和相关信息(用户名、用户密码等属性列表)来创建连接

static Connection

getConnection(String url, String user, String password)

用指定的数据库URL、用户名和用户密码来创建连接

static Driver

getDriver(String url)

定位在给定URL下的驱动程序。 DriverManager尝试从已注册的JDBC驱动程序集中选择适当的驱动程序。

static void

deregisterDriver(Driver driver)

从DriverManager的已注册驱动程序列表中删除指定的驱动程序。

static void

println(String message)

将消息输出到当前JDBC日志流。

static void

setLoginTimeout(int seconds)

驱动程序尝试连接数据库时将等待的最长时间,以秒为单位。

2、Connection接口 ——建立连接

负责建立与指定数据库的连接。

默认情况下,Connection对象处于自动提交模式,这意味着它在执行每个语句后自动提交更改。 如果禁用了自动提交模式,则必须显式调用方法commit()方法才能提交更改;否则,将不会保存数据库更改。

官方文档介绍: Connection (Java Platform SE 8 ) (langp.wang)

其常用成员方法如下:

返回值

方法体

说明

Statement

createStatement()

创建一个Statement对象,用于将SQL语句发送到数据库。

PreparedStatement

prepareStatement(String sql)

创建一个PreparedStatement对象,用于将参数化的SQL语句发送到数据库。

void

close()

立即释放此Connection对象的数据库和JDBC资源,而不是等待它们自动释放。

void

commit()

使自上一次提交/回退以来进行的所有更改永久生效,并释放此Connection对象当前持有的所有数据库锁。

void

rollback()

撤销对数据库执行的添加、删除或者修改记录等操作,并释放此Connection对象当前持有的所有数据库锁。

3、Statement接口 ——执行SQL语句

用于执行静态SQL语句并返回其产生的结果的对象。

默认情况下,每个Statement对象只能同时打开一个ResultSet对象。 因此,如果一个ResultSet对象的读取与另一个的读取交错,则每个都必须由不同的Statement对象生成。 如果当前存在打开的语句,Statement接口中的所有执行方法都会隐式关闭该语句的当前ResultSet对象。

官方文档介绍: Statement (Java Platform SE 8 ) (langp.wang)

其常用成员方法如下:

返回值

方法体

说明

Connection

getConnection()

检索产生此Statement对象的Connection对象

void

close()

立即释放此Statement对象的数据库和JDBC资源,而不是在自动关闭时等待它发生

boolean

execute(String sql)

执行给定的SQL语句,该语句可能返回多个结果

ResultSet

executeQuery(String sql)

执行给定的SQL语句,该语句返回一个ResultSet对象

int

executeUpdate(String sql)

执行给定的SQL语句,该语句可以是INSERT,UPDATE或DELETE语句,也可以是不返回任何内容的SQL语句,例如SQL DDL语句

ResultSet

getResultSet()

以ResultSet对象的形式检索当前结果

executeUpdate()executeQuery()execute()方法的区别:

  • execute()函数:可以执行所有SQL语句。 当执行查询语句时,返回的boolean值指示查询结果的形式,返回值为true时表示查询结果为ResultSet,反之为false(即认为没有查到);执行其他语句时,如果第一个结果是更新计数或不存在任何结果,则返回false
  • executeUpdate():执行insert、update、delete等不返回任何内容的非查询语句。
  • executeQuery():用于执行select语句。返回一个ResultSet对象,其中包含由给定查询产生的数据; 永不为空
4、PreparedStatement接口 ——执行SQL语句

表示预编译的SQL语句的对象。是Statement的子接口。

创建PreparedStatement对象时需传入一个SQL语句,该SQL语句已预编译并存储在PreparedStatement对象中。然后可以使用该对象多次有效地执行该语句。

官方文档介绍: PreparedStatement (Java Platform SE 8 ) (langp.wang)

其常用成员方法如下:

返回值

方法体

说明

boolean

execute()

在此PreparedStatement对象中执行SQL语句,可以是任何类型的SQL语句

ResultSet

executeQuery()

在此PreparedStatement对象中执行SQL查询,并返回查询生成的ResultSet对象

int

executeUpdate()

在此PreparedStatement对象中执行SQL语句,该对象必须是SQL数据操作语言(DML)语句,例如INSERT,UPDATE或DELETE; 或不返回任何内容的SQL语句,例如DDL语句

5、ResultSet接口 ——存放查询之后返回的结果

表示数据库结果集的数据表,通常通过执行查询数据库的语句来生成。

ResultSet对象有一个游标,该游标指向其当前数据行。 最初,光标位于第一行之前。next()方法可将光标移动到下一行,当ResultSet对象中没有更多行时它将返回false,因此可以在while循环中使用它来迭代结果集。例如:

代码语言:javascript复制
// 假设rs是前面进行查询操作返回的ResultSet对象
while(rs.next()){
    // 输出结果
}

用next()方法可以实现访问每一个数据行,那么如何获取数据行中的每一列数据呢?ResultSet接口提供了用于从当前行中检索列值的getter方法,方法名是get 类型,如getBoolean(),getInt()。

getter方法的参数可以是列的索引值或者列的名称,对应的是用索引或者列名来从当前数据行中检索列值。

通常,使用列索引会更有效。 列从1开始编号。为实现最大的可移植性,应按从左到右的顺序读取每一行中的结果集列,并且每一列只能读取一次。

getter方法用列名检索时传入的列名称不区分大小写。 当多个列具有相同的名称时,将返回第一个匹配列的值。 对于在查询中未明确命名的列,最好使用列的索引。 如果使用了列名,则应注意确保它们唯一地引用了预期的列,这可以通过SQL AS子句来确保。

例如:

代码语言:javascript复制
// 假设rs是前面进行查询操作返回的ResultSet对象
while(rs.next()){
    // 使用索引来检索
    int id = rs.getInt(1);
    // 使用列的名称来检索
    String name = rs.getString("name");
    // 且列名不区分大小写
    Date updateTime = rs.getDate("UPDATETIME");
}

官方文档介绍: ResultSet (Java Platform SE 8 ) (langp.wang)

其常用成员方法如下:

返回值

方法体

说明

boolean

absolute(int row)

将光标移动到此ResultSet对象中的给定行号

boolean

first()

将光标移动到此ResultSet对象的第一行

void

beforeFirst()

将光标移动到此ResultSet对象的前面,紧挨着第一行

boolean

isFirst()

检索光标是否在此ResultSet对象的第一行上

boolean

last()

将光标移动到此ResultSet对象的最后一行

void

afterLast()

将光标移动到此ResultSet对象的末尾,紧接在最后一行之后

boolean

isLast()

检索光标是否在此ResultSet对象的最后一行

boolean

next()

将光标从当前位置向前移动一行

void

insertRow()

将插入行的内容插入到此ResultSet对象和数据库中

void

updateRow()

使用此ResultSet对象的当前行的新内容更新底层数据库

void

deleteRow()

从此ResultSet对象和底层数据库中删除当前行

void

update类型(int ColumnIndex,类型 x)

使用给定类型x更新指定列

int

get类型(int ColumnIndex)

以Java类型的形式获取此ResultSet的对象的当前行中指定列的值

主要参考资料: 《数据库系统概论(第5版)》 王珊 萨师煊 编著 Java SE 1.8 官方文档

0 人点赞