zoukankan      html  css  js  c++  java
  • JDBC接口规范

    前言

    JDBC(JavaDatabase Connectivity)表示Java查询引擎连接,由一组用Java编程语言编写的类和接口组成。JDBC为Java程序访问关系型查询引擎提供了编程接口,为查询引擎开发人员提供了一个标准的API,使他们能够用JavaAPI 来编写查询引擎应用程序,而不必为访问不同查询引擎编写不同的程序。

    随着J2SE版本的不断发展,JDBC规范也不断完善。发展到目前为止,JDBC规范已经发到3.0版本。该版本相对于以前的2.0版本又提供了很多新的特性,比如保存点、查询计划的参数信息、多结果集、自动生成键等。

    查询引擎 JDBC驱动程序基本实现了JDBC3.0规范,尤其针对JDBC3.0规范中的新增特性,给出了很好的支持。对于这些新的特性的支持,为用户提供了更为方便的编写查询引擎应用程序的方法,使得用户编写应用程序将更加高效,编写的应用程序也更加健壮。

    本规范结合查询引擎的特点,针对JDBC 的基本概念和基本技术,定义查询引擎JDBC标准规范。

    本规范适用于所有查询引擎的用户。


    1.2.1      建立连接

    打开一个与查询引擎的连接,需要调用DriverManager.getConnection()方法。通过调用该方法,可以取得一个Connection类的实例(Instance),这个实例就在应用程序和查询引擎建立了一个连接,使用这个连接,我们就能通过查询引擎系统操作各个节点了。要得到Connection的实例,就需要应用程序输入用户名、密码、查询引擎 JDBC驱动特定的连接语句以及想要连接的查询引擎库名称。用户将有两种连接方法来与查询引擎建立连接。

    1.        指定URL、用户名和密码

    下面这个方法用URL、用户名、密码作为参数:

    Class.forName(“com.scistor.swift.jdbc.Driver”);

    getConnection(String URL, String user, Stringpassword);

    URL的格式是:

    jdbc:swift://host/database

    jdbc:swift://host:port/database

    其中:

    参数

    参数说明

    host

    服务器的主机名。

    port

    服务器监听的端口号。缺省时是查询引擎默认的端口号(2003)

    database

    查询引擎库名。此处的database就是在安装时创建的查询引擎库所对应的名字

    比如想要连接查询引擎,它的URL、用户名、密码分别是:

           Stringurl = “jdbc:swift://localhost/SYSTEM”;

           Stringname = “SYSDBA”;

           Stringpassword = “SYSDBA”;

    那么就可以很容易的获得一个与查询引擎的连接了

           Connectioncon = DriverManager.getConnection(url,name,password);

    这就意味着用户通过用户名”SYSDBA”,密码”SYSDBA”连接到了本地的名称为“SYSTEM”的查询引擎。

    2.        指定URL和Properties对象

    指定URL的方法同上面一样,现在我们就来指定Properties对象:

    java.util.Properties info = newjava.util.Properties();

    info.setProperty(“user”,”SYSDBA”);

    info.setProperty(“password”,”SYSDBA”);

    现在就可以获得连接了:

    Connection con =DriverManager.getConnection(url,info);

    1.2.2      创建Statement对象

    一旦连接上了查询引擎,也就是说,已经获得了一个Connection的实例,那么就可以通过该Connection实例创建一个Statement对象。通过Statement对象来处理不同的SQL语句。我们就用前面获得的Connection实例con来创建一个Statement对象,下面就是一个创建Statement对象的例子:

    Statement stmt = con.createStatement();

    这个操作是完全遵循JDBC标准规范的,没有任何要处理关于特定查询引擎 JDBC驱动的地方。

    1.2.3      执行语句

    如果需要查询查询引擎中的数据,只需要调用Statement对象的executeQuery()方法。这个方法以SQL语句作为参数,方法执行完后返回一个JDBC的ResultSet对象。为了保持连续性,我们就使用上面已经创建的Statement对象。比如我们要从一张表名为TEMP的表中选出所有数据,我们只要简单的调用executeQurey()方法:

    ResultSet rs = stmt.executeQuery(“SELECT * FROMTEMP”);

    同上面一样,这个操作也是完全遵循JDBC标准规范的,没有任何要处理关于特定查询引擎 JDBC驱动的地方。

    注:假如我们已经在查询引擎中创建了一个名为TEMP的表,它有两列分别为ID(INT),VALUE(STRING)。后面的章节将多次使用到这个表。

    1.2.4      处理结果集

    一旦执行了SQL语句,获得了ResultSet对象,那么就可以通过调用Resulset对象中的next()操作遍历ResultSet操作,以获得每条记录。如果next()方法返回为true,那么就意味着现在有记录可以读取出来,接着就可以调用ResultSet对象的getXXX()方法来取得对应列的值,XXX代表了要取得的列的类型,该方法是以列序号或列名为参数的,下面就从上面获得的ResultSet对象中取得数据:

    while (rs.next())

    System.out.println(rs.getString(2));

    在这里TEMP表中第二列的类型STRING,所以我们使用了rs对象的getString()方法。当然这里也可以通过调用rs.getString(paramName)来获得值。这个方法也是遵循JDBC标准的。如果一直向下做遍历,当没有记录的时候,next()就会返回false。

    1.2.5      关闭Statement对象和结果集

    当不再需要使用Statement和Resultset数据之后,就必须显式的关闭已经创建的Statement对象。JDBC驱动程序没有自动地释放这些对象的功能,应用程序必须显式的调用Statement的close()方法和ResultSet的close()方法。一旦已经显式的关闭了已经创建的对象,就不能再使用这些对象了。如果已经不再使用某些Statement对象和Resultset对象,但是却不去释放它,那将会造成严重的内存泄漏。如果创建了大量的Statement和ResultSet对象,但是却不释放它们,应用程序可能最终会造成OUT OF MEMORY的后果。

    比如应用程序中的Statement对象是stmt,ResultSet对象是rs,就可以这样关闭它:

    rs.close();

    stmt.close();

    虽然关闭了Statement对象时,创建该Statement对象的Connection仍然与查询引擎保持连接,应用程序仍然可以用它创建其他的Statement对象。

    1.2.6      关闭与查询引擎的连接

    最后,当不再需要与查询引擎的连接时,就需要关闭Connection对象。调用Connection的close()方法,就会关闭连接,释放网络上的资源。

    con.close();

    1.3数据类型的映射

    JDBC驱动支持大多数由JDBC3.0规范所要求的类型。在类型映射中,我们将讨论JAVA类型、JDBC类型以及查询引擎类型是如何进行相互映射的。比如前台的String对应于JDBC类型中的那种,又对应于查询引擎中的那种类型。

    表3-1是查询引擎数据类型。

    序号

    类型

    描述

    有效范围

    1

    smallint

    整型数据

    [-32768, 32767]

    2

    int

    整型数据

    [-2147483648, 2147483647]

    3

    bigint

    整型数据

    [-9223372036854775808, 9223372036854775807]

    4

    double precision

    浮点双精度数

    [2.2250738585072014e-308,1.7976931348623158e+308]

    5

    real

    浮点精度数字

    [-1E+308, 1E+308]

    6

    text

    可变长度的字符数据

    最大长度为1G个字符

    7

    char(n)

    定长字符串

    长度为n

    8

    varchar(n)

    变长字符串

    最大长度为n

    9

    bytea

    变长的二进制字串

    理论上没有限制,可以达到4个G

    10

    boolean

    布尔类型

    TRUE/FALSE

    11

    timestamp

    时间戳

    ‘2013-01-01 00:00:00’

    查询引擎数据类型这一列列举了在查询引擎中的数据类型。

    JDBC 类型这一列列举JDBC标准支持的,并在java.sql.Types类中有定义的类型。

    标准JAVA类型这一列列举了在JAVA语言中定义的标准类型。

    表3-2 查询引擎数据类型、JDBC类型和标准JAVA类型之间的映射。

    序号

    查询引擎

    数据类型

    JDBC类型

    标准JAVA类型

    1

    smallint

    java.sql.Types.SMALLINT

    short

    2

    Int

    java.sql.Types.INT

    int

    3

    Bigint

    java.sql.Types.BIGINT

    long

    4

    double precision

    java.sql.Types.DOUBLE

    double

    5

    Real

    java.sql.Types.FLOAT

    double

    6

    Text

    java.sql.Types.VARCHAR

    java.lang.String

    7

    char(n)

    java.sql.Types.VARCHAR

    java.lang.String

    8

    varchar(n)

    java.sql.Types.VARCHAR

    java.lang.String

    9

    bytea

    java.sql.Types.BINARY

    byte[]

    10

    boolean

    java.sql.Types.BOOLEAN

    boolean

    11

    timestamp

    java.sql.Types.TIMESTAMP

    java.sql.Timestamp

    1.4处理SQL异常

    在运行应用程序的时候,可能会抛出很多异常。可能由于查询引擎没有打开导致连接不上,插入的数据类型不符,想要删除的表不存在等等。由JDBC抛出的异常大多是java.sql.SQLException或者它的子类的对象。这些异常有可能是从查询引擎中抛出来的,也有可能是从前台的JDBC驱动抛出的。比如上面提到的服务器连接不上就是由JDBC驱动抛出的异常,想要删除的表不存在就是由查询引擎中抛出的错误。

    那么如何处理这些由JDBC抛出的异常呢?由JDBC抛出的java.sql.SQLException和它的子类,一般都会包括错误描述,标准的SQL State和厂商特定的错误编码。错误描述、SQL State和错误编号会在附录中给出。

    java.sql.SQLException提供了获取这些信息的方法。

    通过调用SQLException的getMessage()方法,可以获得由JDBC驱动或者查询引擎报出的错误。通过这个错误描述,就可以知道错误的原因了。

    通过调用SQLException的getErrorCode()方法,可以获得由厂商特定错误编码,在有些情况下可能不返回错误描述,只返回一个空的字符串。

    通过调用SQLException的getState()的方法,可以获得标准的SQL State。SQL State是由5个数字组成的字符串。

    下面这例子打印出调用getMessage方法所得到的错误信息。

    try{

           <somecode>

    }

    catch(SQLException se){

           System.out.println(“错误信息:”+se.getMessage());

    }

    SQLException类也允许打印出堆栈式的出错信息。打印的内容将包括错误描述,和这个错误从抛出一直到被捕捉到所经过的所有被调用的方法。

    下面给出了如何打印出堆栈信息的方法。

    try{

           <somecode>

    }

    catch(SQLException se){

           se.printStackTrace();}

    第2章    查询引擎 JDBC驱动对于 JDBC规范的支持

    查询引擎 JDBC驱动是基于JDBC3.0规范而实现的。在以前的JDBC2.0规范中,将API分为核心API和扩展API。JDBC3.0规范包含了JDBC2.0规范的核心API以及JDBC2.0的扩展API,并添加了一些新的特性。查询引擎 JDBC驱动实现了JDBC3.0规范中的大部分接口,主要包括下列接口:

    l  java.sql.Dirver

    l  java.sql.Connection

    l  java.sql.Statement

    l  java.sql.ResultSet

    l  java.sql.DatabaseMetaData

    l  java.sql.ResultSetMetaData

    查询引擎 JDBC驱动对于上述每个接口的方法,基本上提供了实现。除了JDBC要求的基本特性之外,比如执行一般的SQL语句,可以对从结果集取得数据等,遵照JDBC3.0的规范,查询引擎 JDBC驱动还提供了一些JDBC的特殊特性:

    按照JDBC规范,提供了类型之间的相互转换,比如int和String之间的转化,String和java.sql.Date之间的转化,具体的内容,请参照《JDBC3.0规范》

    实现了对ResultSet的各种特性的支持,这些特性是在创建Statement对象、PreparedStatement对象和CallableStatement对象时指定的。

    Type包括:

    l  TYPE_FORWARDONLY

    Concurrency包括:

    l  CONCUR_READ_ONLY

    Holdability包括:

    l  不支持

    在查询引擎 JDBC驱动中对这些特性都给出了较好的实现。具体说明将在结果集一章中给出。

    允许用户在Statement和ResultSet中设置fetchSize,通过设置fetchSize,对于记录数很大的情况下,可以极大的降低对内存的使用量。

    第3章    执行SQL语句和处理结果集

    查询引擎 JDBC驱动提供了Statement对象用于发送SQL语句到查询引擎。

    3.1创建Statement对象

    建立了到查询引擎的连接之后,就可以使用该连接发送SQL语句。Statement对象通过Connection接口的方法createStatement创建,例如:

    Connection conn = DriverManager.getConnection(url,"SYSDBA","SYSDBA");

    Statement stmt = conn.createStatement();

    在创建Statement对象的时候,可以通过参数来指定产生结果集的属性,详见“结果集处理”一章。为了执行Statement对象,被发送到查询引擎的SQL语句将被作为参数提供给Statement的方法,例如:

    String sql = “SELECT * FROM TEMP”;

    ResultSet rs = stmt.executeQuery(sql);

    3.2使用Statement对象执行SQL语句

    Statement接口提供了三种执行SQL语句的方法:executeQuery、executeUpdate和execute。使用哪一个方法由SQL语句执行后产生的结果而决定。

    方法executeQuery用于产生单个结果集的语句,例如SELECT语句,执行executeQuery方法将返回一个结果集对象。方法executeUpdate用于执行INSERT、UPDATE或DELETE语句以及SQL DDL(数据定义语言)语句,例如CREATE TABLE和DROP TABLE。由于INSERT、UPDATE或DELETE语句的效果是修改表中若干行中的一列或多列,所以executeUpdate的返回值是一个整数,指示受影响的行数(即更新记录数);对于CREATETABLE或DROP TABLE等不操作行的语句,executeUpdate的返回值总是为零(我们把这个零返回值也视为更新记录数,即没有记录受到影响)。当被执行的SQL语句返回一个更新记录数、一个结果集、多结果集或者SQL语句的类型未知,则使用execute方法。下面的例子演示了以上方法的使用。

    使用executeQuery方法处理SQL数据查询语句:

    Statement stmt = conn.createStatement();

    String sql = “SELECT ID,VALUE FROM TEMP”;

    ResultSet rs = stmt.executeQuery(sql);

    while (rs.next()){

    // 处理获得的数据记录

    }

    使用executeUpdate方法处理SQL数据操纵语句:

    Statement stmt = conn.createStatement();

    String sql = “UPDATETEMPSETVALUE = ‘VALUE10’WHEREID = 10”

    int rows = stmt.executeUpdate(sql);

    if (rows >= 0) {

    //<some code>

    }

    使用executeUpdate方法处理SQL数据定义语句:

    Statement stmt = conn.createStatement();

    String sql = “CREATE TABLE TEST(ID INT, VALUEVARCHAR(50))”;

    int updcount = stmt.executeUpdate(sql);

    if (updcount== 0) {

    // <some code>

    }

    使用execute方法处理SQL语句:

    String sql;

    // 对字符串sql进行赋值,单条SQL语句

    ...

    Statement stmt = conn.createStatement();

    boolean b = stmt.execute(sql);

    if (b) {

    // 说明返回的是ResultSet对象

    ResultSet rs;

    rs = stmt.getResultSet();

    while (rs.next()) {

    //<some code>

    }

    }

    else {

    // 说明返回的是更新记录数

    int rows = stmt.getUpdateCount();

    if (rows >= 0) {

                  //<somecode>

    }

    }

    需要说明的是,执行上面提及的任一种方法都将关闭所调用的Statement对象的当前打开结果集(如果存在)。这意味着在重新执行Statement对象之前,需要完成对当前ResultSet对象的处理。

    3.3使用execute()方法

    当SQL语句执行后会返回ResultSet对象或更新记录数,通常使用execute方法。当同时执行多个SQL语句、执行某个存储过程或动态执行未知SQL字符串(即应用程序程序员在编译时未知)时,就有可能出现多个结果的情况,因此在这种情况下就需要使用execute(),因为execute()方法同时适用于对有ResultSet对象返回和有更新记录数返回的情况。

    如果不知道返回结果的类型,则可以通过execute方法的返回值来进行判断。如果结果是ResultSet对象,则方法execute返回true;如果结果类型是更新纪录数,则返回false。如果返回int,则意味着结果是更新记录数或执行的语句是DDL命令。在调用方法execute之后可以调用getResultSet()或getUpdateCount()。其中getResultSet()方法获得当前结果集,而getUpdateCount()获得记录的更新数。

    当SQL语句的返回结果不是结果集时,则方法getResultSet将返回null。这可能意味着结果是一个更新记录数或没有其它结果。在这种情况下,判断null真正含义的方法是调用方法getUpdateCount(),它将返回一个整数。这个整数为调用语句所影响的行数;如果为-1则表示结果是结果集或没有结果。如果方法getResultSet已返回null(表示结果不是ResultSet对象),则返回值-1表示没有其它结果。也就是说,当下列条件((stmt.getResultSet()==null)&&(stmt.getUpdateCount()==-1))为真时表示没有结果(或没有其它结果)。

    下面给了一个示例,用于执行未知sql语句的情况下作判断:

    boolean retVal = stmt.execute( sql);

    if (retVal){

           //有结果集返回

    ResultSet rs = stmt.getResultSet();

           //处理结果集

           //<somecode>

    }

    else {

           //说明可能有更新记录

           intupdateCount = stmt.getUpdateCount();

           if(updateCount != -1) {

                  //对有更新记录的情况作处理

                  //<somecode>

    }

    }

    3.4关闭Statement对象

    作为一种好的编程风格,对于不再使用的Statement对象应显式地关闭它们,这可以使得Statement对象使用的外部资源立即被释放。同时,应显示关闭由Statement对象所创建的Resultset对象,但是ResultSet对象使用的资源只有到垃圾收集机制启动时,才会真正的释放他们。所以,当一个对象不需要时,无论是ResultSet对象还是Statement对象,都应该尽早地释放他们。

    第4章    结果集(ResultSet)的特性

    本章内容包括:

    4.1概述

    在JDBC3.0规范中结果集的特性,包括可滚动性(scrollability)、可定位(positioning)、敏感性(sensitivity)、可更新性(updatability)和可保持性(holdability)。这些特性可以分为Type,Concurrency和Holdability三大类,下表为查询引擎对各特性的支持情况定义:

    ResultSet Types

    支持程度

    ResultSet Concurrency

    支持程度

    ResultSet Holdability

    支持程度

    TYPE_FORWARD_ONLY

    支持

    CONCUR_READ_ONLY

    支持

    HOLD_CURSOR_OVER_COMMIT

    不支持

    TYPE_SCROLL_INSENSITIVE

    不支持

    CONCUR_UPDATABLE

    不支持

    CLOSE_CURSOR_AT_COMMIT

    不支持

    TYPE_SCROLL_SENSITIVE

    不支持

     

     

     

     

    4.2设置结果集大小

    查询引擎 JDBC驱动提供了允许用户设置结果集大小(即上面结果集的敏感性中提到的窗口的大小)的方法。通过设置结果集的大小,驱动每次从查询引擎取得的记录数将不超过用户设置的大小。比如TEMP表的实际记录数有100万条,用户如果把它一次全部取出来,就会耗用大量的内存;用户可以设置结果集的大小,比如为1万,那么查询引擎 JDBC驱动将每次只从后台查询引擎取1万条。当用户作游标移动操作时,如果JDBC发现那条记录还没从查询引擎取出来,就会从查询引擎取出那条记录。

    stmt.setFetchSize(10000);

    ResultSet rs = stmt.executeQuery(“SELECT * FROMTEMP”);

    while(rs.next()) {

    //如果调用到第10001次,驱动程序会再从后台取10000条,把原来的记录

    //覆盖掉,这样内存中始终只是用了10000条记录内存的大小

    }

    在缺省情况下,即用户不设fetchSize时, JDBC驱动会将所有记录一次取出来。因此对于记录数极大的情况下(比如100万条)可能会耗用大量的内存。但是如果用户将fetchSize设得不够大,会增加网络的开销和查询引擎的查询操作,因此在这种情况下应用程序的执行速度将不如缺省的情况。用户对于内存耗用量和执行速度必须有一个折中的考虑,取得最好的平衡点。

    第5章    MetaData信息

    MetaData是一种重要的机制,可以供用户来获取相应对象(目标数据源、结果集,参数信息等)的详细描述信息。在JDBC驱动中,有三个接口专门提供相应的MetaData信息:

    DatabaseMetaData:用于描述查询引擎的元数据信息;

    ResultSetMetaData:用于描述ResultSet对象的元数据信息;

    ParameterMetaData:用于描述PreparedStatement、CallableStatement对象参数属性的元数据信息。

    下面将分别介绍这三个接口相应方法的使用。

    5.1DatabaseMetaData

    DatabaseMetaData接口的实现是为了给用户提供目标数据源的信息,应用程序根据接口中的各种方法得到相应的信息,进而决定如何与之交互。

    获取DatabaseMeta信息的步骤是:首先创建DatabaseMetaData对象:

    DatabaseMetaData dbmd = conn.getMetaData();

    利用dbmd对象,调用DatabaseMetaData接口的相应方法就可以获得查询引擎和JDBC驱动程序的一些信息,例如:

    int majorVersion = dbmd.getJDBCMajorVersion(); // 获得JDBC 驱动程序的主版本号

    DatabaseMetaData接口包括了超过150种的方法,根据提供信息的类型,可以把这些方法分为五类:

    提供数据源总体信息的方法:比如获得查询引擎的主版本号版本信息的getDatabaseMajorVersion();

    说明数据源是否支持某一特定特征的方法:比如根据方法supportsANSI92EntryLevelSQL()的返回值可以知道查询引擎是否支持ANSI92入门级SQL语法;

    说明数据源限制的方法:比如通过getMaxConnections()方法可以得到查询引擎支持的最大连接数;

    说明数据源支持哪些SQL对象,他们的属性是什么:比如getTables()、getPrimaryKeys()方法;

    说明数据源提供的事务支持:比如通过getDefaultTransactionIsolation()方法可以得到查询引擎缺省的事务隔离级别。

    建议支持接口如下:

    函数

    功能

    intgetJDBCMajorVersion()

    获取JDBC主版本号

    String getDatabaseProductName()

    获取系统名称

    String getDatabaseProductVersion()

    获取版本号

    String getDriverName()

    获取驱动名称

    String getDriverVersion()

    获取驱动版本号

    String getURL()

    获取引擎URL

    关于各种方法的具体说明请参阅JAVA2 SDK DOCUMENT。

    5.2ResultSetMetaData

    ResultSetMetaData接口提供的方法用于获取一个ResultSet对象各个列的类型和属性,比如列名、列数据类型、列所属的表、以及列是否允许值为 NULL等等。

    下面的例子演示了ResultSetMetaData的创建和使用:

    假如有一个表StudentInfo(StuIDINT,StuName VARCHAR(10)),下面的例子可以得到这个表的各个列的类型名称:

    String sql = “SELECT StuID, StuName FROMStudentInfo”;

    ResultSet rs = stmt.executeQuery(sql);

    ResultSetMetaData rsmd = rs.getMetaData();

    for(int i = 1; i <= rsmd.getColumnCount(); i++)

    {

                  //依次打印出列的类型名称

                  StringtypeName = rsmd.getColumnTypeName(i);

                  System.out.println(typeName);

    }

    建议支持接口如下:

    函数

    功能

    intgetColomnCount()

    获取字段个数

    String getColumnName(int column)

    根据结果集中字段索引获取字段名

    intgetColumnType(int column)

    获取字段的类型代码

    String getColumnTypeName(int column)

    获取字段类型的名称

    关于各种方法的具体说明请参阅JAVA2 SDK DOCUMENT。

    第6章    批处理

    批处理更新机制允许多个更新操作提交给数据源一次处理。相比于一次次单独执行更新,这样的处理方式可以大大的提高效率和性能。Statement、PreparedStatement对象均可以通过addBatch、executeBatch等方法使用批处理更新方式。

    6.1Statement中的批处理

    当一个Statement对象创建的时候,它的批处理队列是空的。通过调用addBatch()方法,可以将作为参数的SQL语句加入队列中。特别需要指出的是,遵照JDBC3.0规范,所有加入队列的SQL语句必须是执行后返回结果为更新记录数的语句(即insert,delete, update语句和DDL语句),否则将抛出SQLException异常。

    如果不打算提交批更新队列中的SQL语句,需要调用clearBatch方法来清空批处理队列。执行批处理更新使用executeBatch方法即可。需要注意的一点:在使用批处理更新之前必须先禁用AutoCommit模式。

    下面是一个例子:

    //改变auto-commit模式

    conn.setAutoCommit(false);

    Statementstmt = conn.createStatement();

    //设置SQL语句

    stmt.addBatch("INSERTINTO employee VALUES (1024, 'Joe Jones')");

    stmt.addBatch("INSERTINTO department VALUES (6, 'Shoe')");

    stmt.addBatch("INSERTINTO emp_dept VALUES (1024, 6)");

    //执行批处理更新

    int[]updateCounts = stmt.executeBatch();

    conn.commit();

    最后说明一点,在批处理队列当中不允许设置保存点(savepoint)。如果要设置,必须在第一条SQL语句被添加到批处理队列中之前。

    6.2PreparedStatement中的批处理

    在PreparedStatement对象中使用批处理更新机制,是指先对SQL语句执行查询优化,然后在批处理队列中置入多组输入参数,而后提交数据源一次处理。下面是一个例子:

    //改变auto-commit模式

    conn.setAutoCommit(false);

    Stringsql = “INSERT INTO TEMP(ID,VALUE) VALUES(?,?)”;

    //先做查询优化

    PreparedStatementpstmt = conn.prepareStatement("sql”);

    //设置参数值

    pstmt.setInt(1,200);

    pstmt.setString(2,"Tom Kaufmann");

    pstmt.addBatch();

    //设置参数值

    pstmt.setInt(1,300);

    pstmt.setString(2,"Mike Barnes");

    pstmt.addBatch();

    //执行,取得更新记录

    int[]updateCounts = pstmt.executeBatch();

    conn.commit();

    6.3批处理中的异常处理

    在批处理执行过程中,如果有一条语句执行出错,执行将不再继续下去,查询引擎JDBC将会抛出BatchUpdateException,该异常是SQLException的子类。在BatchUpdateException中提供了getUpdateCounts()方法,该方法的返回值是一个int数组。同前面executeBatch()方法一样,该返回数组是一个记录的更新数,数组中的每个值,都是相应SQL语句在查询引擎中更新的记录数。不过getUpdateCounts()返回的数组长度,为正确执行的SQL语句数,而不是批处理中所有的SQL语句数。因此,getUpdateCounts()中包含的记录更新数,将只包含正确执行的SQL语句,而不包含错误执行或没有执行到的SQL语句。

    第7章    B参考资料

    关于更详细的JDBC Driver 的信息,可以参考JAVA2 SDK DOCUMENT和JDBC3.0规范.可以在http://java.sun.com/products/jdbc/index.html获得相关文档。

  • 相关阅读:
    在VMware中为Red Hat配置静态ip并可访问网络-Windows下的VMware
    03-nginx虚拟主机配置
    解决nginx: [emerg] bind() to [::]:80 failed (98: Address already in use)
    02-nginx信号量
    RedHat Linux设置yum软件源为本地ISO
    01-nginx介绍及编译安装
    Linux.负载均衡
    01-MySQL优化大的思路
    10 华电内部文档搜索系统 search02
    10 华电内部文档搜索系统 search03
  • 原文地址:https://www.cnblogs.com/xiaodf/p/5027200.html
Copyright © 2011-2022 走看看