JDBC操作6步

世界杯梅西点球

JDBC编程六步 JDBC编程的步骤是很固定的,通常包含以下六步: 第一步:注册驱动 作用一:将 JDBC 驱动程序从硬盘上的文件系统中加载到内存中……

JDBC编程六步

JDBC编程的步骤是很固定的,通常包含以下六步:

第一步:注册驱动

作用一:将 JDBC 驱动程序从硬盘上的文件系统中加载到内存中。作用二:使得 DriverManager 可以通过一个统一的接口来管理该驱动程序的所有连接操作。

第二步:获取数据库连接

获取java.sql.Connection对象,该对象的创建标志着mysql进程和jvm进程之间的通道打开了。

第三步:获取数据库操作对象

获取java.sql.Statement对象,该对象负责将SQL语句发送给数据库,数据库负责执行该SQL语句。

第四步:执行SQL语句

执行具体的SQL语句,例如:insert delete update select等。

第五步:处理查询结果集

如果之前的操作是DQL查询语句,才会有处理查询结果集这一步。执行DQL语句通常会返回查询结果集对象:java.sql.ResultSet。对于ResultSet查询结果集来说,通常的操作是针对查询结果集进行结果集的遍历。

第六步:释放资源

释放资源可以避免资源的浪费。在 JDBC 编程中,每次使用完 Connection、Statement、ResultSet 等资源后,都需要显式地调用对应的 close() 方法来释放资源,避免资源的浪费。释放资源可以避免出现内存泄露问题。在 Java 中,当一个对象不再被引用时,会被 JVM 的垃圾回收机制进行回收。但是在 JDBC 编程中,如果不显式地释放资源,那么这些资源就不会被 JVM 的垃圾回收机制自动回收,从而导致内存泄露问题。

JDBC完成新增操作

新增操作就是让数据库执行insert语句。通过这个操作来学习一下JDBC编程的每一步。刚开始编写JDBC代码的时候,建议使用文本编辑器,先不借助任何IDE。

JDBC编程第一步:注册驱动

注册驱动有两个作用:

将 JDBC 驱动程序从硬盘上的文件系统中加载到内存。让 DriverManager 可以通过一个统一的接口来管理该驱动程序的所有连接操作。

JDK的API帮助文档:

代码如下:

import java.sql.Driver;

import java.sql.DriverManager;

import java.sql.SQLException;

public class JDBCTest01 {

public static void main(String[] args){

try {

// 1. 注册驱动

// com.mysql.cj.jdbc.Driver 是MySQL驱动最核心的类,

// 这个类实现了 java.sql.Driver 接口

Driver driver = new com.mysql.cj.jdbc.Driver(); // 创建MySQL驱动对象

DriverManager.registerDriver(driver); // 完成驱动注册

} catch(SQLException e){

e.printStackTrace();

}

}

}

注意:注册驱动调用的是java.sql.DriverManager的静态registerDriver()方法。这些方法的使用要参阅JDK的API帮助文档。

思考1:为什么以上代码中new的时候,后面类名要带上包名呢?

因为这个Driver和java.sql.Driver的Driver不是同一个包的

思考2:以上代码中哪些是JDBC接口,哪些是JDBC接口的实现?

new com.mysql.cj.jdbc.Driver();这个是MySQL对java制定的driver规则的实现

JDBC编程第二步:获取连接

获取java.sql.Connection对象,该对象的创建标志着mysql进程和jvm进程之间的通道打开了。

代码实现

API帮助文档:

代码如下:

import java.sql.Driver;

import java.sql.DriverManager;

import java.sql.SQLException;

import java.sql.Connection;

public class JDBCTest01 {

public static void main(String[] args){

try {

// 1. 注册驱动

Driver driver = new com.mysql.cj.jdbc.Driver(); // 创建MySQL驱动对象

DriverManager.registerDriver(driver); // 完成驱动注册

// 2. 获取连接

String url = "jdbc:mysql://localhost:3306/jdbc";

String user = "root";

String password = "123456";

Connection conn = DriverManager.getConnection(url, user, password);

System.out.println("连接对象:" + conn);

} catch(SQLException e){

e.printStackTrace();

}

}

}

执行结果如下:

看到以上的输出结果,表示数据库已经连接成功了。

通过以上程序的输出结果得知:com.mysql.cj.jdbc.ConnectionImpl是java.sql.Connection接口的实现类,大家可以想象一下,如果换成Oracle数据库的话,这个实现类的类名是不是就会换一个呢?答案是肯定的。不过对于我们来说是不需要关心具体实现类的,因为后续的代码都是直接面向java.sql.Connection接口来调用方法的。面向接口编程在这里体现的淋漓尽致。确实降低了耦合度。

JDBC编程第三步:获取数据库操作对象

数据库操作对象是这个接口:java.sql.Statement。这个对象负责将SQL语句发送给数据库服务器,服务器接收到SQL后进行编译,然后执行SQL。

API帮助文档如下:

获取数据库操作对象代码如下:

import java.sql.Driver;

import java.sql.DriverManager;

import java.sql.SQLException;

import java.sql.Connection;

import java.sql.Statement;

public class JDBCTest01 {

public static void main(String[] args){

try {

// 1. 注册驱动

Driver driver = new com.mysql.cj.jdbc.Driver(); // 创建MySQL驱动对象

DriverManager.registerDriver(driver); // 完成驱动注册

// 2. 获取连接

String url = "jdbc:mysql://localhost:3306/jdbc?useUnicode=true&serverTimezone=Asia/Shanghai&useSSL=true&characterEncoding=utf-8";

String user = "root";

String password = "123456";

Connection conn = DriverManager.getConnection(url, user, password);

// 3. 获取数据库操作对象

Statement stmt = conn.createStatement();

System.out.println("数据库操作对象stmt = " + stmt);

} catch(SQLException e){

e.printStackTrace();

}

}

}

执行结果如下:

同样可以看到:java.sql.Statement接口在MySQL驱动中的实现类是:com.mysql.cj.jdbc.StatementImpl。不过我们同样是不需要关心这个具体的实现类。因为后续的代码仍然是面向Statement接口写代码的。

另外,要知道的是通过一个Connection对象是可以创建多个Statement对象的:

import java.sql.Driver;

import java.sql.DriverManager;

import java.sql.SQLException;

import java.sql.Connection;

import java.sql.Statement;

public class JDBCTest01 {

public static void main(String[] args){

try {

// 1. 注册驱动

Driver driver = new com.mysql.cj.jdbc.Driver(); // 创建MySQL驱动对象

DriverManager.registerDriver(driver); // 完成驱动注册

// 2. 获取连接

String url = "jdbc:mysql://localhost:3306/jdbc?useUnicode=true&serverTimezone=Asia/Shanghai&useSSL=true&characterEncoding=utf-8";

String user = "root";

String password = "123456";

Connection conn = DriverManager.getConnection(url, user, password);

// 3. 获取数据库操作对象

Statement stmt = conn.createStatement();

System.out.println("数据库操作对象stmt = " + stmt);

Statement stmt2 = conn.createStatement();

System.out.println("数据库操作对象stmt2 = " + stmt2);

} catch(SQLException e){

e.printStackTrace();

}

}

}

执行结果:

JDBC编程第四步:执行SQL

当获取到Statement对象后,调用这个接口中的相关方法即可执行SQL语句。

API帮助文档如下:

该方法的参数是一个SQL语句,只要将insert语句传递过来即可。当执行executeUpdate(sql)方法时,JDBC会将sql语句发送给数据库服务器,数据库服务器对SQL语句进行编译,然后执行SQL。

该方法的返回值是int类型,返回值的含义是:影响了数据库表当中几条记录。例如:返回1表示1条数据插入成功,返回2表示2条数据插入成功,以此类推。如果一条也没有插入,则返回0。

该方法适合执行的SQL语句是DML,包括:insert delete update。

代码实现如下:

import java.sql.Driver;

import java.sql.DriverManager;

import java.sql.SQLException;

import java.sql.Connection;

import java.sql.Statement;

public class JDBCTest01 {

public static void main(String[] args){

try {

// 1. 注册驱动

Driver driver = new com.mysql.cj.jdbc.Driver(); // 创建MySQL驱动对象

DriverManager.registerDriver(driver); // 完成驱动注册

// 2. 获取连接

String url = "jdbc:mysql://localhost:3306/jdbc?useUnicode=true&serverTimezone=Asia/Shanghai&useSSL=true&characterEncoding=utf-8";

String user = "root";

String password = "123456";

Connection conn = DriverManager.getConnection(url, user, password);

// 3. 获取数据库操作对象

Statement stmt = conn.createStatement();

// 4. 执行SQL语句

String sql = "insert into t_user(name,password,realname,gender,tel) values('tangsanzang','123','唐三藏','男','12566568956')"; // sql语句最后的分号';'可以不写。

int count = stmt.executeUpdate(sql);

System.out.println("插入了" + count + "条记录");

} catch(SQLException e){

e.printStackTrace();

}

}

}

执行结果如下:

数据库表变化了:

第五步去哪里了?第五步是处理查询结果集,以上操作不是select语句,所以第五步直接跳过,直接先看一下第六步释放资源。【后面学习查询语句的时候,再详细看第五步】

为什么要释放资源

在 JDBC 编程中,建立数据库连接、创建 Statement 对象等操作都需要申请系统资源,例如打开网络端口、申请内存等。为了避免占用过多的系统资源和避免出现内存泄漏等问题,我们需要在使用完资源后及时释放它们。

释放资源的原则

原则1:在finally语句块中释放

建议在finally语句块中释放,因为程序执行过程中如果出现了异常,finally语句块中的代码是一定会执行的。也就是说:我们需要保证程序在执行过程中,不管是否出现了异常,最后的关闭是一定要执行的。当然了,也可以使用Java7的新特性:Try-with-resources。Try-with-resources 是 Java 7 引入的新特性。它简化了资源管理的代码实现,可以自动释放资源,减少了代码出错的可能性,同时也可以提供更好的代码可读性和可维护性。

原则2:释放有顺序

从小到大依次释放,创建的时候,先创建Connection,再创建Statement。那么关闭的时候,先关闭Statement,再关闭Connection。

原则3:分别进行try…catch…

关闭的时候调用close()方法,该方法有异常需要处理,建议分别对齐try…catch…进行异常捕获。如果只编写一个try…catch…进行一块捕获,在关闭过程中,如果某个关闭失败,会影响下一个资源的关闭。

代码如何实现

import java.sql.Driver;

import java.sql.DriverManager;

import java.sql.SQLException;

import java.sql.Connection;

import java.sql.Statement;

public class JDBCTest01 {

public static void main(String[] args){

Connection conn = null;

Statement stmt = null;

try {

// 1. 注册驱动

Driver driver = new com.mysql.cj.jdbc.Driver(); // 创建MySQL驱动对象

DriverManager.registerDriver(driver); // 完成驱动注册

// 2. 获取连接

String url = "jdbc:mysql://localhost:3306/jdbc?useUnicode=true&serverTimezone=Asia/Shanghai&useSSL=true&characterEncoding=utf-8";

String user = "root";

String password = "123456";

conn = DriverManager.getConnection(url, user, password);

// 3. 获取数据库操作对象

stmt = conn.createStatement();

// 4. 执行SQL语句

String sql = "insert into t_user(name,password,realname,gender,tel) values('tangsanzang','123','唐三藏','男','12566568956')"; // sql语句最后的分号';'可以不写。

int count = stmt.executeUpdate(sql);

System.out.println("插入了" + count + "条记录");

} catch(SQLException e){

e.printStackTrace();

} finally {

// 6. 释放资源

if(stmt != null){

try{

stmt.close();

}catch(SQLException e){

e.printStackTrace();

}

}

if(conn != null){

try{

conn.close();

}catch(SQLException e){

e.printStackTrace();

}

}

}

}

}