JDBC简介:
JDBC 的全称是 Java Database Connectivity,叫做 Java
数据库连接。它包括了一组与数据库交互的api,还有与数据库进行通信的驱动程序。
对于不同的数据库,我们需要知道不同数据库对外提供的系统
API,这就影响了我们程序的扩展和跨平台的实现。
那么有没有一种方法来对不同的数据库接口进行统一呢?那么这里木木就要向大家介绍分层的思想。我们只需要和最上层接口进行交互,剩下的部分就交给其他各层去处理,我们的任务就变的轻松简单许多。
ODBC 是 Open Database Connect
即开放数据库互连的简称,它是微软于1991年提出的一个用于访问数据库的统一接口标准,是应用程序和数据库系统之间的中间层。我们的应用程序在调用数据的时候,就无需去管具体的数据库,直接由应用程序访问
ODBC 就可以了。
而在 Java 上面只有一种数据库连接统一接口——JDBC。JDBC
为数据库开发人员提供了一个标准的
API,据此可以构建更高级的工具和接口使数据库开发人员能够用纯 Java API
编写数据库应用程序。
Java数据与jdbc数据对比:
SQL | JDBC/Java | setter | updater | getter |
---|---|---|---|---|
VARCHAR | java.lang.String | setString | updateString | getString |
CHAR | java.lang.String | setString | updateString | getString |
LONGVARCHAR | java.lang.String | setString | updateString | getString |
BIT | boolean | setBoolean | updateBoolean | getBoolean |
NUMERIC | java.math.BigDecimal | setBigDecimal | updateBigDecimal | getBigDecimal |
TINYINT | byte | setByte | updateByte | getByte |
SMALLINT | short | setShort | updateShort | getShort |
INTEGER | int | setInt | updateInt | getInt |
BIGINT | long | setLong | updateLong | getLong |
REAL | float | setFloat | updateFloat | getFloat |
FLOAT | float | setFloat | updateFloat | getFloat |
DOUBLE | double | setDouble | updateDouble | getDouble |
VARBINARY | byte[] | setBytes | updateBytes | getBytes |
BINARY | byte[] | setBytes | updateBytes | getBytes |
DATE | java.sql.Date | setDate | updateDate | getDate |
TIME | java.sql.Time | setTime | updateTime | getTime |
TIMESTAMP | java.sql.Timestamp | setTimestamp | updateTimestamp | getTimestamp |
CLOB | java.sql.Clob | setClob | updateClob | getClob |
BLOB | java.sql.Blob | setBlob | updateBlob | getBlob |
ARRAY | java.sql.Array | setARRAY | updateARRAY | getARRAY |
REF | java.sql.Ref | setRef | updateRef | getRef |
STRUCT | java.sql.Struct | setStruct | updateStruct | getStruct |
java 程序访问数据库
package com.shiyanlou;
import java.sql.\*;
public class JdbcTest {
// JDBC 驱动器名称 和数据库地址
static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
//数据库的名称为 EXAMPLE
static final String DB_URL = "jdbc:mysql://localhost/EXAMPLE";
// 数据库用户和密码
static final String USER = "root";
static final String PASS = "";
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
try{
//注册JDBC 驱动程序
Class.forName("com.mysql.jdbc.Driver");
//打开连接
System.out.println("Connecting to database...");
conn = DriverManager.getConnection(DB_URL,USER,PASS);
//执行查询
System.out.println("Creating statement...");
stmt = conn.createStatement();
String sql;
sql = "SELECT id, name, age FROM Students";
ResultSet rs = stmt.executeQuery(sql);
//得到和处理结果集
while(rs.next()){
//检索
int id = rs.getInt("id");
int age = rs.getInt("age");
String name = rs.getString("name");
//显示
System.out.print("ID: " + id);
System.out.print(", Age: " + age);
System.out.print(", Name: " + name);
System.out.println();
}
//清理环境
rs.close();
stmt.close();
conn.close();
}catch(SQLException se){
// JDBC 操作错误
se.printStackTrace();
}catch(Exception e){
// Class.forName 错误
e.printStackTrace();
}finally{
//这里一般用来关闭资源的
try{
if(stmt!=null)
stmt.close();
}catch(SQLException se2){
}
try{
if(conn!=null)
conn.close();
}catch(SQLException se){
se.printStackTrace();
}
}
System.out.println("Goodbye!");
}
}
}
二、结构
JDBC API 是 Java 开发工具包(JDK)的组成部份,由三部分组成:
-
JDBC 驱动程序管理器
-
JDBC 驱动程序测试工具包
-
JDBC-ODBC 桥
a. JDBC 驱动程序管理器是 JDBC 体系结构的支柱,其主要作
用是把 Java 应用程序连接到正确的 JDBC 驱动程序上。
b. JDBC 驱动程序测试工具包为 JDBC 驱动程序的运行提供一定的可信度,只有通过 JDBC
驱动程序测试包的驱动程序才被认为是符合 JDBC 标准的。
c.
JDBC-ODBC 桥使 ODBC 驱动程序可被用作 JDBC 驱动程序。其目标是为方便实现访问某些不常见的 DBMS(数据库管理系统),它的实现为 JDBC 的快速发展提供了一条途径。
JDBC既支持数据库访问的两层模型,也支持三层模型。
1、数据库访问的两层模型
2、数据库访问的三层模型
JDBC 驱动程序实现 JDBC API 中定义的接口,用于与数据库服务器进行交互。JDBC
驱动程序可以打开数据库连接,并通过发送 SQL 或数据库命令,然后在收到结果与 Java
进行交互。
JDBC 驱动程序的实现因为各种各样的操作系统和 Java
运行在不同的硬件平台上而不同。JDBC 驱动类型可以归结为以下几类:
- JDBC-ODBC 桥接 ODBC 驱动程序:它是将 JDBC 翻译成 ODBC,然后使用一个 ODBC
驱动程序与数据库进行通信。当 Java
刚出来时,这是一个有用的驱动程序,因为大多数的数据库只支持 ODBC
访问,但现在建议使用此类型的驱动程序仅用于实验用途或在没有其他选择的情况。
- 本地 API 用 Java 来编写的驱动程序:这种类型的驱动程序把客户机 API 上的 JDBC
调用转换为 Oracle、Sybase、 Informix、DB2 或其它 DBMS 的调用。
- JDBC 网络纯 Java 驱动程序:这种驱动程序将 JDBC 转换为与 DBMS
无关的网络协议,这是最为灵活的 JDBC
驱动程序。它是一个三层的方法来访问数据库,在 JDBC
客户端使用标准的网络套接字与中间件应用服务器进行通信。然后由中间件应用服务器进入由
DBMS 所需要的的调用格式转换,并转发到数据库服务器。
- 本地协议纯 Java 驱动程序:这种类型的驱动程序将 JDBC 调用直接转换为 DBMS
所使用的专用网络协议。是 Intranet
访问的一个很实用的解决方法。它是直接与供应商的数据库进行通信,通过 socket
连接一个纯粹的基于 Java
的驱动程序。这是可用于数据库的最高性能的驱动程序,并且通常由供应商本身提供。
MySQL 的 Connector/Java
的驱动程序是一个类型4驱动程序。因为他们的网络协议的专有性的,数据库厂商通常提供类型4的驱动程序。
通常情况下如果正在访问一个类型的数据库,如Oracle,Sybase或IBM,首选驱动程序是类型4。
如果Java应用程序同时访问多个数据库类型,类型3是首选的驱动程序。
第2类驱动程序是在类型3或类型4驱动程序还没有提供数据库的情况下显得非常有用。
类型1驱动程序不被认为是部署级别的驱动程序,它通常仅用于开发和测试目的。
连接:
涉及到建立一个 JDBC 连接的编程主要有四个步骤:
-
导入 JDBC 驱动:
只有拥有了驱动程序我们才可以注册驱动程序完成连接的其他步骤。 -
注册 JDBC 驱动程序:这一步会导致 JVM
加载所需的驱动类实现到内存中,然后才可以实现 JDBC 请求。 -
数据库 URL 指定:创建具有正确格式的地址,指向到要连接的数据库。
-
创建连接对象:最后,代码调用 DriverManager 对象的 getConnection()
方法来建立实际的数据库连接。
接下来我们便详细讲解这四步。
2.3.1 导入 JDBC 驱动
我们已经在上一节课为同学们就相应的方法做了详细的介绍,不清楚的同学可以查看上一节实验课的内容。
2.3.2 注册 JDBC 驱动程序
我们在使用驱动程序之前,必须注册你的驱动程序。注册驱动程序的本质就是将我们将要使用的数据库的驱动类文件动态的加载到内存中,然后才能进行数据库。比如我们使用的
Mysql 数据库。我们可以通过以下两种方式来注册我们的驱动程序。
1、方法1——Class.forName():
动态加载一个类最常用的方法是使用Java的Class.forName()方法,通过使用这个方法来将数据库的驱动类动态加载到内存中,然后我们就可以使用。
使用Class.forName()来注册 Mysql 驱动程序:
try {
Class.forName("com.mysql.jdbc.Driver");
}
}
catch(ClassNotFoundException ex) {
System.out.println("Error: unable to load driver class!");
System.exit(1);
}
}
2、方法2——DriverManager.registerDriver():
Driver driver = new com.mysql.jdbc.Driver();
DriverManager.registerDriver(driver);
2.3.3 指定数据库连接URL
当加载了驱动程序,便可以使用 DriverManager.getConnection() 方法连接到数据库了。
这里给出 DriverManager.getConnection() 三个重载方法:
getConnection(String url)
getConnection(String url, Properties prop)
getConnection(String url, String user, String password)
数据库的URL是指向数据库地址。下表列出了下来流行的JDBC驱动程序名和数据库的URL。
RDBMS | JDBC驱动程序的名称 | URL |
---|---|---|
Mysql | com.mysql.jdbc.Driver | jdbc:mysql://hostname/ databaseName |
Oracle | oracle.jdbc.driver.OracleDriver | jdbc:oracle:thin:@hostname:port Number:databaseName |
DB2 | COM.ibm.db2.jdbc.net.DB2Driver | jdbc:db2:hostname:port Number/databaseName |
Sybase | com.sybase.jdbc.SybDriver | jdbc:sybase:Tds:hostname: port Number/databaseName |
2.3.4 创建连接对象
下面三种形式DriverManager.getConnection()方法来创建一个连接对象,以 Mysql
为例。getConnection()最常用形式要求传递一个数据库URL,用户名 username和密码
password。
1、使用数据库URL的用户名和密码
String URL = "jdbc:mysql://localhost/EXAMPLE";
String USER = "username";
String PASS = "password"
Connection conn = DriverManager.getConnection(URL, USER, PASS);
2、只使用一个数据库URL
然而,在这种情况下,数据库的URL,包括用户名和密码。
String URL = "jdbc:mysql://localhost/EXAMPLE?user=root\&password=0909";
//Mysql URL的参数设置详细可以查阅相关资料
Connection conn = DriverManager.getConnection(URL);
3、使用数据库的URL和一个Properties对象
import java.util.\*;
String URL = "jdbc:mysql://localhost/EXAMPLE";
Properties pro = new Properties( );
//Properties对象,保存一组关键字-值对
pro.put( "user", "root" );
pro.put( "password", "" );
Connection conn = DriverManager.getConnection(URL, pro);
4、关闭JDBC 连接
conn.close();
jdbc接口:
通过使用 JDBC Statement, CallableStatement 和 PreparedStatement
接口定义的方法和属性,使可以使用 SQL 或 PL/SQL
命令和从数据库接收数据。它们还定义了许多方法,帮助消除Java
和数据库之间数据类型的差异。
接口 | 应用场景 |
---|---|
Statement | 当在运行时使用静态 SQL 语句时(Statement接口不能接受的参数) |
CallableStatement | 当要访问数据库中的存储过程时(CallableStatement对象的接口还可以接受运行时输入参数) |
PreparedStatement | 当计划多次使用 SQL 语句时(PreparedStatement 接口接收在运行时输入参数) |
statement:
创建一个 Statement 对象了。我们需要使用 Connection 对象的 createStatement()
方法进行创建。
Statement stmt = null;
try {
stmt = conn.createStatement( );
. . .
}
}
catch (SQLException e) {
. . .
}
}
finally {
. . .
}
}
一旦创建了一个Statement对象,我们就可以用它来执行SQL语句了,首先我们先来看看
Statement 里面有哪些方法吧!
方法 | 说明 |
---|---|
boolean execute(String SQL) | 如果 ResultSet 对象可以被检索返回布尔值 true,否则返回 false。使用这个方法来执行 SQL DDL 语句,或当需要使用真正的动态 SQL |
int executeUpdate(String SQL) | 用于执行 INSERT、UPDATE 或 DELETE 语句以及 SQLDDL(数据定义语言)语句。返回值是一个整数,指示受影响的行数(即更新计数) |
ResultSet executeQuery(String SQL) | 返回 ResultSet 对象。用于产生单个结果集的语句,例如 SELECT 语句 |
正如关闭一个 Connection 对象来释放数据库连接资源,出于同样的原因,也应该关闭
Statement 对象。
Statement stmt = null;
try {
stmt = conn.createStatement( );
. . .
}
}
catch (SQLException e) {
. . .
}
}
finally {
stmt.close();
}
}
注:如果关闭了 Connection 对象首先它会关闭 Statement 对象,然而应该始终明确关闭
Statement 对象,以确保正确的清除。
PreparedStatement:
PreparedStatement 接口扩展了 Statement 接口,有利于高效地执行多次使用的 SQL
语句。我们先来创建一个 PreparedStatement 对象。 Statement 为一条 SQL
语句生成执行计划。如果要执行两条 SQL
语句,会生成两个执行计划。一万个查询就生成一万个执行计划!
select colume from table where colume=1;
select colume from table where colume=2;
PreparedStatement 用于使用绑定变量重用执行计划。
select colume from table where colume=:x;
通过 set 不同数据,只需要生成一次执行计划,并且可以重用。
PreparedStatement pstmt = null;
try {
<!--在JDBC中所有的参数都被代表?符号,这是已知的参数标记。在执行SQL语句之前,必须提供值的每一个参数。
-->
String SQL = "Update Students SET age = ? WHERE id = ?";
stmt = conn.prepareStatement(SQL);
. . .
}
}
<!--setXXX()方法将值绑定到参数,其中XXX表示希望绑定到输入参数值的 Java
数据类型。如果忘了提供值,将收到一个 SQLException。-->
catch (SQLException e) {
. . .
}
}
finally {
//同理,我们需要关闭 PreparedStatement 对象
pstmt.close();
}
}
说了这么多,我们还是来看代码吧。即上一次我们创建的数据库
EXAMPLE,我们继续在Test项目下修改JdbcTest.java:
package com.shiyanlou;
import java.sql.\*;
public class JdbcTest {
// JDBC 驱动器的名称和数据库地址
static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
static final String DB_URL = "jdbc:mysql://localhost/EXAMPLE";
static final String USER = "root";
static final String PASS = "";
public static void main(String[] args) {
Connection conn = null;
PreparedStatement stmt = null;
try{
//注册 JDBC 驱动器
Class.forName("com.mysql.jdbc.Driver");
//打开连接
System.out.println("Connecting to database...");
conn = DriverManager.getConnection(DB_URL,USER,PASS);
//执行查询
System.out.println("Creating statement...");
//这里我们要更改一个同学的年龄,参数待定
String sql = "UPDATE Students set age=? WHERE id=?";
stmt = conn.prepareStatement(sql);
//将值绑定到参数,参数从左至右序号为1,2...
stmt.setInt(1, 22); // 绑定 age 的值(序号为1)
stmt.setInt(2, 1); // 绑定 ID 的值
// 更新 ID 为1的同学的年龄
int rows = stmt.executeUpdate();
System.out.println("被影响的行数 : " + rows );
// 查询所有记录,并显示.
sql = "SELECT id, name, age FROM Students";
ResultSet rs = stmt.executeQuery(sql);
//处理结果集
while(rs.next()){
//检索
int id = rs.getInt("id");
int age = rs.getInt("age");
String name = rs.getString("name");
//显示
System.out.print("ID: " + id);
System.out.print(", Age: " + age);
System.out.print(", Name: " + name);
System.out.println();
}
//清理
rs.close();
stmt.close();
conn.close();
}catch(SQLException se){
se.printStackTrace();
}catch(Exception e){
e.printStackTrace();
}finally{
try{
if(stmt!=null)
stmt.close();
}catch(SQLException se2){
}
try{
if(conn!=null)
conn.close();
}catch(SQLException se){
se.printStackTrace();
}
}
System.out.println("Goodbye!");
}
}
}
运行结果:
ResultSet接口
方法可分为三类:
-
导航方法:用于移动光标
-
获取方法:用于查看当前行的光标所指向的列中的数据
-
更新方法:用于更新当前行的列中的数据
JDBC 提供下列连接方法来创建所需的ResultSet语句:
createStatement(int RSType, int RSConcurrency);
prepareStatement(String SQL, int RSType, int RSConcurrency);
prepareCall(String sql, int RSType, int RSConcurrency);
RSType 表示 ResultSet 对象的类型,RSConcurrency 是 ResultSet
常量,用于指定一个结果集是否为只读或可更新。
ResultSet 的类型,如果不指定 ResultSet 类型,将自动获得一个是
TYPE_FORWARD_ONLY:
类型 | 描述 |
---|---|
ResultSet.TYPE_FORWARD_ONLY | 游标只能向前移动的结果集 |
ResultSet.TYPE_SCROLL_INSENSITIVE | 游标可以向前和向后滚动,但不及时更新,就是如果数据库里的数据修改过,并不在ResultSet中反应出来 |
ResultSet.TYPE_SCROLL_SENSITIVE | 游标可以向前和向后滚动,并及时跟踪数据库的更新,以便更改ResultSet中的数据 |
并发性的ResultSet,如果不指定任何并发类型,将自动获得一个为 CONCUR_READ_ONLY
并发 | 描述 |
---|---|
ResultSet.CONCUR_READ_ONLY | 创建结果集只读。这是默认的 |
ResultSet.CONCUR_UPDATABLE | 创建一个可更新的结果集 |
如初始化一个 Statement 对象来创建一个双向、可更新的ResultSet对象:
try {
Statement stmt = conn.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
}
}
catch(Exception ex) {
....
}
}
finally {
....
}
}
方法 | 说明 |
---|---|
public void beforeFirst() throws SQLException | 将光标移动到正好位于第一行之前 |
public void afterLast() throws SQLException | 将光标移动到刚刚结束的最后一行 |
public boolean first() throws SQLException | 将光标移动到第一行 |
public void last() throws SQLException | 将光标移动到最后一行 |
public boolean absolute(int row) throws SQLException | 将光标移动到指定的行 |
public boolean relative(int row) throws SQLException | 从它目前所指向向前或向后移动光标行的给定数量 |
public boolean previous() throws SQLException | 将光标移动到上一行。上一行关闭的结果集此方法返回false |
public boolean next() throws SQLException | 将光标移动到下一行。如果没有更多的行结果集中的此方法返回false |
public int getRow() throws SQLException | 返回的行号,该光标指向的行 |
public void moveToInsertRow() throws SQLException | 将光标移动到一个特殊的行,可以用来插入新行插入到数据库中的结果集。当前光标位置被记住 |
public void moveToCurrentRow() throws SQLException | 移动光标返回到当前行,如果光标在当前插入行,否则,这个方法不执行任何操作 |
public int getInt(String columnName) throws SQLException | 当前行中名为 ColumnName 列的值 |
public int getInt(int columnIndex) throws SQLException | 当前行中指定列的索引的值。列索引从1开始,意味着一个行的第一列是1,行的第二列是2,依此类推 |
public void updateString(int columnIndex, String s) throws SQLException | 指定列中的字符串更改为s的值 |
public void updateString(String columnName, String s) throws SQLException | 类似于前面的方法,不同之处在于由它的名称,而不是它的索引指定的列 |
public void updateRow() | 通过更新数据库中相应的行更新当前行 |
public void deleteRow() | 从数据库中删除当前行 |
public void refreshRow() | 刷新在结果集的数据,以反映最新变化在数据库中 |
public void cancelRowUpdates() | 取消所做的当前行的任何更新 |
public void insertRow() | 插入一行到数据库中。当光标指向插入行此方法只能被调用 |
当然还有 getString()等等。
什么也不说了,我们还是看代码吧,代码继续再上节实验的基础上修改!
package com.shiyanlou;
import java.sql.\*;
public class JdbcTest {
// JDBC 驱动器名称 和数据库地址
static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
//数据库的名称为 EXAMPLE
static final String DB_URL = "jdbc:mysql://localhost/EXAMPLE";
// 数据库用户和密码
static final String USER = "root";
static final String PASS = "";
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
try{
//注册JDBC 驱动程序
Class.forName("com.mysql.jdbc.Driver");
//打开连接
System.out.println("Connecting to database...");
conn = DriverManager.getConnection(DB_URL,USER,PASS);
System.out.println("Creating statement...");
//创建所需的ResultSet,双向,只读
stmt = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
String sql;
sql = "SELECT id, name, age FROM Students";
ResultSet rs = stmt.executeQuery(sql);
// 将光标移到最后一行
System.out.println("Moving cursor to the last...");
rs.last();
//处理结果集
System.out.println("Displaying record...");
int id = rs.getInt("id");
int age = rs.getInt("age");
String name = rs.getString("name");
//显示
System.out.print("ID: " + id);
System.out.print(", Age: " + age);
System.out.print(", Name: " + name);
System.out.println();
// 将光标移到第一行
System.out.println("Moving cursor to the first row...");
rs.first();
System.out.println("Displaying record...");
id = rs.getInt("id");
age = rs.getInt("age");
name = rs.getString("name");
//显示
System.out.print("ID: " + id);
System.out.print(", Age: " + age);
System.out.print(", Name: " + name);
//将光标移至下一行
System.out.println("Moving cursor to the next row...");
rs.next();
System.out.println("Displaying record...");
id = rs.getInt("id");
age = rs.getInt("age");
name = rs.getString("name");
// 显示
System.out.print("ID: " + id);
System.out.print(", Age: " + age);
System.out.print(", Name: " + name);
rs.close();
stmt.close();
conn.close();
}catch(SQLException se){
se.printStackTrace();
}catch(Exception e){
e.printStackTrace();
}finally{
try{
if(stmt!=null)
stmt.close();
}catch(SQLException se2){
}
try{
if(conn!=null)
conn.close();
}catch(SQLException se){
se.printStackTrace();
}
}
System.out.println("Goodbye!");
}
}
}
运行结果:
![](media/8d2bc050af066a77c4063a98a885b948.png)
事务(自动提交和手动提交):
我们在编写 java 程序的时候,在默认情况下,JDBC 连接是在自动提交模式下,即每个
SQL
语句都是在其完成时提交到数据库。但有时候我们为了提高程序运行的性能或者保持业务流程的完整性,以及使用了分布式事务管理方式,这个时候我们可能想关闭自动提交而自己管理和控制自己的事务。
让多条SQL在一个事务中执行,并且保证这些语句是在同一时间共同执行的时候,我们就应该为这多条语句定义一个事务。一个事务是把单个
SQL 语句或一组 SQL
语句作为一个逻辑单元,并且如果事务中任何语句失败,则整个事务失败。
如果我们要启动一个事务,而不是让 JDBC 驱动程序默认使用 auto-commit
模式支持。这个时候我们就要使用 Connection 对象的 setAutoCommit()
方法。我们传递一个布尔值 false 到 setAutoCommit()
中,就可以关闭自动提交。反之我们传入一个 true 便将其重新打开。
例如:
Connection conn = null;
conn = DriverManager.getConnection(URL);
/
//关闭自动提交
c
conn.setAutoCommit(false);
我们关闭了自动提交后,如果我们要提交数据库更改怎么办呢?这时候就要用到我们的提交和回滚了。我们要提交更改,可以调用
commit() 方法:
conn.commit();
尤其不要忘记,在catch块内添加回滚事务,表示操作出现异常,撤销事务:
conn.rollback();
**jdbc异常处理:**
JDBC 的异常处理非常类似于Java Exception处理。JDBC 最常见的异常处理的是
java.sql.SQLException,所以今天我们就来学习 SQLException 方法。
| **方法** | **描述** |
|-----------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| getErrorCode() | 获取此 SQLException 对象的特定于供应商的异常代码 |
| getNextException() | 通过 setNextException(SQLException ex) 获取链接到此 SQLException 对象的异常 |
| getSQLState() | 获取此 SQLException 对象的 SQLState。对于 JDBC 驱动程序的错误,没有有用的信息从该方法返回。对于一个数据库错误,则返回五位 XOPEN SQLSTATE 代码。这种方法可以返回 null |
| iterator() | 返回在链接的 SQLExceptions 上进行迭代的迭代器 |
| setNextException(SQLException ex) | 将 SQLException 对象添加到链接的末尾 |
**jabc批量处理:**
接下来我们来看看如何进行批处理操作:
1. 使用createStatement()方法创建一个Statement对象
2. 设置使用自动提交为 false
3. 添加任意多个SQL 语句到批量处理,使用addBatch()方法
4. 使用executeBatch()方法,将返回一个整数数组,数组中的每个元素代表了各自的更新语句的更新计数
5. 最后,提交使用commit()方法的所有更改
我们来看看示例:
// 创建 statement 对象
S
Statement stmt = conn.createStatement();
// 关闭自动提交
c
conn.setAutoCommit(false);
// 创建 SQL 语句
String SQL = "INSERT INTO Students (id, name, age) VALUES(6,'Mike', 21)";
// 将 SQL 语句添加到批处理中
s
stmt.addBatch(SQL);
// 创建更多的 SQL 语句
String SQL = "INSERT INTO Students (id, name, age) VALUES(7, 'Angle', 23)";
// 将 SQL 语句添加到 批处理中
s
stmt.addBatch(SQL);
// 创建整数数组记录更新情况
int[] count = stmt.executeBatch();
//提交更改
c
conn.commit();
当然我们也可以使用 prepareStatement 对象进行批处理操作,SQL
语句依然可以使用占位符,示例如下:
// 创建 SQL 语句
S
String SQL = "INSERT INTO Employees (id, name, age) VALUES(?, ?, ?)";
// 创建 PrepareStatement 对象
P
PreparedStatemen pstmt = conn.prepareStatement(SQL);
//关闭自动连接
c
conn.setAutoCommit(false);
// 绑定参数
p
pstmt.setInt( 1, 8 );
p
pstmt.setString( 2, "Cindy" );
p
pstmt.setInt( 3, 17 );
// 添入批处理
p
pstmt.addBatch();
// 绑定参数
p
pstmt.setInt( 1, 9 );
p
pstmt.setString( 2, "Jeff" );
p
pstmt.setInt( 3, 22 );
// 添入批处理
p
pstmt.addBatch();
//创建数组记录更改
i
int[] count = pstmt.executeBatch();
//提交更改
c
conn.commit();