一、JDBC概述
JDBC是一种可用于执行SQL语句的Java API (Application Programming Interface,应用程序设计接口),是连接数据库和Java应用程序的纽带。
1、JDBC-ODBC桥
JDBC-0DBC桥是一个JDBC驱动程序,完成了从JDBC操作到0DBC操作之间的转换工作,允许JDBC驱动程序被用作ODBC的驱动程序。使用JDBC-ODBC桥连接数据库的步骤如下:
(1)首先加载JDBC-ODBC桥的驱动程序。代码如下:
Class.forNamet"sunjdbc.odbc.JdbcOdbcDriver”);
Class类是java.lang 包中的-一个类,通过该类的静态方法forName()可加载sun.jdbc.odbc 包中的JdbcOdbcDriver类来建立JDBC-ODBC桥连接器。
(2)使用java.sql包中的Connection接口,并通过DriverManager类的静态方法getConnection()创建连接对象。代码如下:
Connection conn = DriverManager.getConnection("jdbc:odbc:数据源名字”,"user name","password");
数据源必须给出一个简短的描述名。假设没有设置username和password,则要与数据源tom交换数据。建立Connection对象的代码如下:
Connection conn = DriverManagergetConnectionC"jdbc.odbc:tom”,",");
(3)向数据库发送SQL语句。使用Statement 接口声明一个SQL语句对象,并通过刚才创建的连接数据库对象conn的createStatement(方法创建这个SQL对象。代码如下:
Statement sql = conn.createStatement);
JDBC-ODBC桥作为连接数据库的过渡性技术,现在已经不被Java广泛应用了,现在被广泛应用的是JDBC技术。但这并不表示JDBC-ODBC桥技术已经被淘汰,由于ODBC技术被广泛地使用,使得Java可以利用JDBC-0DBC桥访间几乎所有的数据库。JDBC-ODBC桥作为sun.jdbc.odbe包与JDK一起自 动安装,不需要特殊配置。
2、JDBC技术
JDBC的全称是Java DataBase Connectivity,是一套面向对象的应用程序接口,指定了统一的访问各种关系型数据库的标准接口。JDBC是一种底层的API,因此访问数据库时需要在业务逻辑层中嵌入SQL语句。SQL语句是面向关系的,依赖于关系模型,所以通过JDBC技术访问数据库也是面向关系的。JDBC技术主要完成以下几个任务:
- 与数据库建立一个连接。
- 向数据库发送 SQL语句。
- 处理从数据库返回的结果。
需要注意的是,JDBC并不能直接访问数据库,必须依赖于数据库厂商提供的JDBC驱动程序。
3、JDBC驱动程序的类型
JDBC的总体结构由4个组件一应用程序、 驱动程序管理器、驱动程序和数据源组成。JDBC驱动基本上分为以下4种。
- JDBC-ODBC桥:依靠ODBC驱动器和数据库通信。这种连接方式必须将ODBC二进制代码加载到使用该驱动程序的每台客户机上。这种类型的驱动程序最适合于企业网或者用Java编写的三层结构的应用程序服务器代码。
- 本地API一部分用Java编写的驱动程序:这类驱动程序把客户机的API上的JDBC调用转换为Oracle、DB2、Sybase 或其他DBMS的调用。这种驱动程序也需要将某些二进制代码加载到每台客户机上。
- JDBC 网络驱动:这种驱动程序将JDBC转换为与DBMS无关的网络协议,又被某个服务器转换为一-种DBMS协议,是-种利用Java编写的JDBC驱动程序,也是最为灵活的JDBC驱动程序。这种方案的提供者提供了适合于企业内部互联网(Intranet) 用的产品。为使这种产品支持Internet访问,需要处理Web提出的安全性、通过防火墙的访问等额外的要求。
- 本地协议驱动: 这是一种纯Java的驱动程序。这种驱动程序将JDBC调用直接转换为DBMS所使用的网络协议,允许从客户机上直接调用DBMS服务器,是一种很实用的访问Intranet的解决方法。
JDBC网络驱动和本地协议驱动是JDBC访问数据库的首选,这两类驱动程序提供了Java的所有优点。
二、JDBC中常用的类和接口
1、Connection接口
Connection接口代表与特定的数据库的连接,在连接.上下文中执行SQL 语句并返回结果。Connection接口的常用方法如下表所示:
2、Statement接口
Statement接口用于在已经建立连接的基础上向数据库发送SQL语句。在JDBC中有3种Statement对象,分别是Staterment、PreparedStaterment 和CallableStatement。Statement 对象用于执行不带参数的简的SQL语句; PreparedStatement 继承了Statement, 用来执行动态的SQL语句; CallableStatemnent 继承了PreparedStatement, 用于执行对数据库的存储过程的调用。Statement 接口的常用方法如下表所示。
3、PreparedStatement接口
PreparedStatement接口用来动态地执行SQL语句。通过PreparedStatement实例执行的动态SQL语句,将被预编译并保存到PreparedStatement实例中,从而可以反复地执行该SQL语句。PreparedStatement接口的常用方法如下表所示。
4、DriverManager类
DriverManager类用来管理数据库中的所有驱动程序。它是JDBC的管理层,作用于用户和驱动程序之间,跟踪可用的驱动程序,并在数据库的驱动程序之间建立连接。如果通过getConnection0方法可以建立连接,则经连接返回,否则抛出SQLException异常。DriverManager 类的常用方法如下表所示。
5、ResultSet接口
ResultSet接口类似于一个临时表,用来暂时存放数据库查询操作所获得的结果集。ResultSet 实例具有指向当前数据行的指针,指针开始的位置在第一条 记录的前面,通过next()方法可将指针向下移。ResultSet常用方法如下表所示。
三、数据库操作实例
运行环境:eclipse版本:2019-09;JDK:12,驱动jar包:mysql-connector-java-8.0.19;MySQL Server 8.0。注意此处要将mysql-connector-java-8.0.19.jar添加至构建路径。
例1:
import java.sql.*;
public class Gradation {
static Connection con;
static Statement sql;
static ResultSet res;
public Connection getConnection() {
try {
// 加载数据库驱动类
//Class.forName("com.mysql.jdbc.Driver");
Class.forName("com.mysql.cj.jdbc.Driver");
// 连接数据库
// 注意此处因为数据库和系统时区差异会引起异常所以在在jdbc连接的url后面加上
// “?serverTimezone=UTC&characterEncoding=utf-8”
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test"
+"?serverTimezone=UTC&characterEncoding=utf-8", "root", "12345");
} catch (Exception e) {
e.printStackTrace();
}
return con;
}
public static void main(String[] args) {
Gradation c = new Gradation();
con = c.getConnection();
try {
sql = con.createStatement(); // 实例化Statement对象
res = sql.executeQuery("select * from tb_stu"); // 执行SQL语句,返回结果集
while (res.next()) { // 如果当前语句不是最后一条则进入循环
String id = res.getString("id");
String name = res.getString("name");
String sex = res.getString("sex");
String birthday = res.getString("birthday");
System.out.print("编号:" + id); // 将列值输出
System.out.print(" 姓名:" + name);
System.out.print(" 性别:" + sex);
System.out.println(" 生日:" + birthday);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
输出:
例2:
import java.sql.*;
public class Renewal {
static Connection con;
static PreparedStatement sql;
static ResultSet res;
public Connection getConnection() {
try {
// 加载数据库驱动类
//Class.forName("com.mysql.jdbc.Driver");
Class.forName("com.mysql.cj.jdbc.Driver");
// 连接数据库
// 注意此处因为数据库和系统时区差异会引起异常所以在在jdbc连接的url后面加上
// “?serverTimezone=UTC&characterEncoding=utf-8”
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/test"
+"?serverTimezone=UTC&characterEncoding=utf-8", "root", "12345");
} catch (Exception e) {
e.printStackTrace();
}
return con;
}
public static void main(String[] args) {
Renewal c = new Renewal();
con = c.getConnection();
try {
sql = con.prepareStatement("select * from tb_stu"); // 查询数据库
res = sql.executeQuery(); // 执行SQL语句
System.out.println("执行增加、修改、删除前数据:");
while (res.next()) {
String id = res.getString(1);
String name = res.getString("name");
String sex = res.getString("sex");
String birthday = res.getString("birthday"); // 遍历查询结果集
System.out.print("编号:" + id);
System.out.print(" 姓名:" + name);
System.out.print(" 性别:" + sex);
System.out.println(" 生日:" + birthday);
}
// 预处理添加数据
sql = con.prepareStatement("insert into tb_stu(name,sex,birthday) values(?,?,?)");
sql.setString(1, "张一");
sql.setString(2, "女");
sql.setString(3, "2012-12-1");
sql.executeUpdate();
// 更新数据
sql = con.prepareStatement("update tb_stu set birthday = ? where id = ? ");
sql.setString(1, "2012-12-02");
sql.setInt(2, 1);
sql.executeUpdate();
Statement stmt = con.createStatement();
stmt.executeUpdate("delete from tb_stu where id = 1");
// 查询修改数据后的tb_stu表中数据
sql = con.prepareStatement("select * from tb_stu");
res = sql.executeQuery(); // 执行SQL语句
System.out.println("执行增加、修改、删除后的数据:");
while (res.next()) {
String id = res.getString(1);
String name = res.getString("name");
String sex = res.getString("sex");
String birthday = res.getString("birthday");
System.out.print("编号:" + id);
System.out.print(" 姓名:" + name);
System.out.print(" 性别:" + sex);
System.out.println(" 生日:" + birthday);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
输出:
executeQuery()方法是在PreparedStatement对象中执行SQL查询,并返回该查询生成的ResultSet对象,而executeUpdate()方法是在PreparedStaterment对象中执行SQL语句,该语句必须是一个SQL数据操作语言(Data Manipulation Language, DML)语句,如INSERT. UPDATE或DELETE语句,或者是无返回内容的SQL语句,如DDL语句。