Java系列(二十一)__JDBC

Java系列(二十一)__JDBC


1、JDBC简介

JDBC指的是Java数据库连接,可以直接利用Java程序进行各种数据库连接及操作。JDBC在Java之中属于一个服务的概念,所谓的服务指的就是一组固定的类库以完成某些固定的操作,而所有的服务在使用的形式上都很固定。

         那么在进行JDBC操作的过程之中,重点在于数据库的连接上,而对于JDBC的连接主要可以见到三种:

· JDBC-ODBC桥连接:使用微软提供的ODBC技术进行数据库的连接,由于其是Java本身所支持的,所以版本永远是最新的,但是永远也是没人用的;

         |- 操作形式:程序 è JDBC è ODBC è 数据库,性能很差;

· JDBC连接:由各个数据库的生产商提供有数据库的驱动程序(根据JDBC标准开发的),由于其直接使用Java连接,所以性能较高;

         |- 操作形式:程序 è JDBC è 数据库,性能较高;

· 网络连接:通过网络协议连接网络上的数据库服务,这样的方式是开发之中主要使用的。

         在java.sql包之中提供有所有的JDBC开发类的支持,常用的:DriverManager类、Connection接口、Statement接口、PreparedStatement接口、ResultSet接口。


2、JDBC连接Oracle数据库

本次要连接的是Oracle数据库,所以必须首先启动Oracle的两个重要服务(监听、实例服务),随后还需要配置Oracle数据库的驱动程序。Oracle和DB2的驱动程序都是随着安装包提供的。

· 路径:D:\app\Teacher\product\11.2.0\dbhome_1\jdbc\lib\ojdbc6_g.jar


         一切准备工作就绪之后,就可以给出JDBC操作数据库的标准流程:

                   · 第一步:加载数据库驱动程序;

                            |- 驱动程序的加载主要是向容器之中加载,通过Class.forName()加载;

                            |- Oracle的驱动程序名称:oracle.jdbc.driver.OracleDriver

                   · 第二步:根据给定的数据库连接地址、用户名、密码连接数据库;

                            |- 连接需要的主要信息:

                                     |- 连接地址:jdbc:oracle:thin:@主机名称:端口号:SID;

                                               |- 连接mldn:jdbc:oracle:thin:@localhost:1521:MLDN

                                     |- 用户名:scott;

                                     |- 密码:tiger;

                            |- 连接数据库主要是利用DriverManager类完成,取得的连接对象使用Connection接口表示;

                   · 第三步:打开数据库连接之后可以通过SQL进行数据库操作;

                            |- 数据库的操作主要是CRUD,利用Statement、PreparedStatement、ResultSet操作SQL语句;

                   · 第四步:数据库属于资源操作,操作的最后一定要使用close()方法关闭

                            |- Connection、Statement、PreparedStatement、ResultSet都提供有关闭方法。

         由于JDBC是一个开发标准,所以来讲在JDBC之中,每一个数据库连接都使用一个Connection接口表示(一个数据库可以打开多个连接,那么就使用多个Connection接口对象表示)。而所有的连接都需要通过DriverManager类打开,此类定义了如下方法:

                   · 连接数据库:public static Connection getConnection(String url, String user, String password)

throws SQLException;

范例:连接数据库

package cn.mldn.demo;

import java.sql.Connection;

import java.sql.DriverManager;

public class TestDemo {

    private static final String DBDRIVER = "oracle.jdbc.driver.OracleDriver";

    private static final String DBURL = "jdbc:oracle:thin:@localhost:1521:mldn";

    private static final String DBUSER = "scott";

    private static final String PASSWORD = "tiger";

    public static void main(String[] args) throws Exception {

        Connection conn = null; // 每一个Connection对象都表示一个连接

        Class.forName(DBDRIVER); // 加载数据库驱动程序

        conn = DriverManager.getConnection(DBURL, DBUSER, PASSWORD); // 连接数据库

        System.out.println(conn);   // 如果不为null表示已连接

        conn.close() ;

    }

}

         那么通过以上的程序就可以发现,只要是想取得数据库的连接必须使用DriverManager类,那么今天连接的是Oracle,有可能明天连接的是mysql,或者是世界上近千种数据库,那么在连接的时候,只要遵守了JDBC的开发标准,都可以采用之前完全相同的方式进行连接,于是现在的代码就行成了这样的结构。

         所以DriverManager类严格来讲就是一个工厂类,通过此类之中的getConnection()方法,只要传入了正确的连接地址、用户名、密码,就可以取得一个指定的Connection接口对象(这个时候Connection子类完全是由各个数据库生产商根据Connection接口标准制定的。)

         所谓的数据库连接对数据库而言实际上就是程序建立了若干个Socket连接而已。




3、Statement

当取得了Connection接口对象之后,下面就可以利用Connection打开数据库的操作接口Statement,在Connection接口里面定义有一个取得Statement接口对象的方法:public Statement createStatement() throws SQLException。

         而取得了Statement接口后就可以进行两类操作:

                   · 数据库更新操作:public int executeUpdate(String sql) throws SQLException,返回更新行数;

                   · 数据库查询操作:public ResultSet executeQuery(String sql) throws SQLException。

范例:编写数据库创建脚本

-- 删除对象

DROP SEQUENCE myseq ;

DROP TABLE member ;

-- 创建对象

CREATE SEQUENCE myseq ;

CREATE TABLE member (

         mid             NUMBER ,

         name          VARCHAR2(20) NOT NULL ,

         birthday      DATE ,

         note            CLOB ,

         CONSTRAINT mid_pk PRIMARY KEY(mid)

) ;

         下面将使用Statement实现数据库操作。但是Statement使用的是标准SQL语句,所以对于日期的处理要使用TO_DATE()函数。

3.1、实现更新操作

         更新操作一共分为三类:增加、修改、删除。

范例:增加新数据

         · SQL语法:INSERT INTO 表名称(字段,字段,…) VALUES (值 , 值 , …) ;

package cn.mldn.demo;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.Statement;

public class TestDemo {

    private static final String DBDRIVER = "oracle.jdbc.driver.OracleDriver";

    private static final String DBURL = "jdbc:oracle:thin:@localhost:1521:mldn";

    private static final String DBUSER = "scott";

    private static final String PASSWORD = "tiger";

    public static void main(String[] args) throws Exception {

        Connection conn = null; // 每一个Connection对象都表示一个连接

        Statement stmt = null ; // 定义数据库操作对象

        Class.forName(DBDRIVER); // 加载数据库驱动程序

        conn = DriverManager.getConnection(DBURL, DBUSER, PASSWORD); // 连接数据库

        stmt = conn.createStatement() ; // 创建Statement对象

        // 如果在编写SQL过程之中出现换行,请一定要保证前后各加一个空格

        String sql = " INSERT INTO member(mid,name,birthday,note) "

                + " VALUES (myseq.nextval,'小刁大笨', "

                + " TO_DATE('1911-11-11','yyyy-mm-dd'),'笨的没人样了。。。天生神棍') " ;

        int len = stmt.executeUpdate(sql) ; // 执行SQL

        System.out.println("更新行数:" + len);

        conn.close() ;

    }

}

范例:修改数据

         · SQL语法:UPDATE 表名称 SET 字段=值, … WHERE 修改条件;

package cn.mldn.demo;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.Statement;

public class TestDemo {

    private static final String DBDRIVER = "oracle.jdbc.driver.OracleDriver";

    private static final String DBURL = "jdbc:oracle:thin:@localhost:1521:mldn";

    private static final String DBUSER = "scott";

    private static final String PASSWORD = "tiger";

    public static void main(String[] args) throws Exception {

        Connection conn = null; // 每一个Connection对象都表示一个连接

        Statement stmt = null ; // 定义数据库操作对象

        Class.forName(DBDRIVER); // 加载数据库驱动程序

        conn = DriverManager.getConnection(DBURL, DBUSER, PASSWORD); // 连接数据库

        stmt = conn.createStatement() ; // 创建Statement对象

        // 如果在编写SQL过程之中出现换行,请一定要保证前后各加一个空格

        String sql = " UPDATE member SET name='小谢子',note='小刁子很吊,好贱', "

                + " birthday=SYSDATE WHERE mid IN (5,7,9,10,20) " ;

        int len = stmt.executeUpdate(sql) ; // 执行SQL

        System.out.println("更新行数:" + len);

        conn.close() ;

    }

}

范例:删除数据

         · SQL语法:DELETE FROM 表名称 WHERE 删除条件;

package cn.mldn.demo;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.Statement;

public class TestDemo {

    private static final String DBDRIVER = "oracle.jdbc.driver.OracleDriver";

    private static final String DBURL = "jdbc:oracle:thin:@localhost:1521:mldn";

    private static final String DBUSER = "scott";

    private static final String PASSWORD = "tiger";

    public static void main(String[] args) throws Exception {

        Connection conn = null; // 每一个Connection对象都表示一个连接

        Statement stmt = null ; // 定义数据库操作对象

        Class.forName(DBDRIVER); // 加载数据库驱动程序

        conn = DriverManager.getConnection(DBURL, DBUSER, PASSWORD); // 连接数据库

        stmt = conn.createStatement() ; // 创建Statement对象

        // 如果在编写SQL过程之中出现换行,请一定要保证前后各加一个空格

        String sql = " DELETE FROM member WHERE mid IN (2,4,6,8,10) " ;

        int len = stmt.executeUpdate(sql) ; // 执行SQL

        System.out.println("更新行数:" + len);

        conn.close() ;

    }

}

         这个时候可以清楚的发现,整个操作过程之中,唯一改变的只是SQL语句。

3.2、实现查询操作

         更新操作主要是返回更新的数据行数,但是如果是查询操作,则需要把查询结果返回,而查询结果一般都是以“行、列集合”的形式返回的,所以就必须有一种结构,可以容纳这些行和列,于是就有了ResultSet接口,即:所有查询的返回值都保存在了ResultSet集合之中。


范例:查询数据

package cn.mldn.demo;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.ResultSet;

import java.sql.Statement;

import java.util.Date;

public class TestDemo {

    private static final String DBDRIVER = "oracle.jdbc.driver.OracleDriver";

    private static final String DBURL = "jdbc:oracle:thin:@localhost:1521:mldn";

    private static final String DBUSER = "scott";

    private static final String PASSWORD = "tiger";

    public static void main(String[] args) throws Exception {

        Connection conn = null; // 每一个Connection对象都表示一个连接

        Statement stmt = null ; // 定义数据库操作对象

        Class.forName(DBDRIVER); // 加载数据库驱动程序

        conn = DriverManager.getConnection(DBURL, DBUSER, PASSWORD); // 连接数据库

        stmt = conn.createStatement() ; // 创建Statement对象

        // 如果在编写SQL过程之中出现换行,请一定要保证前后各加一个空格

        String sql = " SELECT mid,name,birthday,note FROM member " ;

        ResultSet rs = stmt.executeQuery(sql) ; // 执行查询操作

        // 每次循环是操作返回的一行记录

        while (rs.next()) { // 移动游标,同时判断是否有数据

            int mid = rs.getInt("mid") ;

            String name = rs.getString("name") ;

            Date birthday = rs.getDate("birthday") ;

            String note = rs.getString("note") ;

            System.out.println(mid + "," + name + "," + birthday + "," + note);

        }

        conn.close() ;

    }

}

         但是很多的时候在进行列访问的时候也会采用索引的形式取得数据。

    while (rs.next()) { // 移动游标,同时判断是否有数据

        int mid = rs.getInt(1) ;

        String name = rs.getString(2) ;

        Date birthday = rs.getDate(3) ;

        String note = rs.getString(4) ;

        System.out.println(mid + "," + name + "," + birthday + "," + note);

    }

         在日后编写SQL的时候明确的写上列名称,而后就可以利用索引来取得数据,这是最为常用的方式。





4、PreparedStatement

虽然可以利用Statement操作数据库,但是如果在开发之中,Statement是不可能使用的,以增加数据为例,在本表之中姓名、生日、介绍应该由用户自己输入。

范例:问题引出

package cn.mldn.demo;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.Statement;

public class TestDemo {

    private static final String DBDRIVER = "oracle.jdbc.driver.OracleDriver";

    private static final String DBURL = "jdbc:oracle:thin:@localhost:1521:mldn";

    private static final String DBUSER = "scott";

    private static final String PASSWORD = "tiger";

    public static void main(String[] args) throws Exception {

        String name = "Mr'SMITH" ;

        String birthday = "2012-12-25" ;

        String note = "荒唐的世界末日" ;

        Connection conn = null; // 每一个Connection对象都表示一个连接

        Statement stmt = null ; // 定义数据库操作对象

        Class.forName(DBDRIVER); // 加载数据库驱动程序

        conn = DriverManager.getConnection(DBURL, DBUSER, PASSWORD); // 连接数据库

        stmt = conn.createStatement() ; // 创建Statement对象

        // 如果在编写SQL过程之中出现换行,请一定要保证前后各加一个空格

        String sql = " INSERT INTO member(mid,name,birthday,note) "

                + " VALUES (myseq.nextval,'"+name+"', "

                + " TO_DATE('"+birthday+"','yyyy-mm-dd'),'"+note+"') " ;

        System.out.println(sql);

        int len = stmt.executeUpdate(sql) ; // 执行SQL

        System.out.println("更新行数:" + len);

        conn.close() ;

    }

}

INSERT INTO member(mid,name,birthday,note)  VALUES (myseq.nextval,'Mr'SMITH',  TO_DATE('2012-12-25','yyyy-mm-dd'),'荒唐的世界末日')

Exception in thread "main" java.sql.SQLSyntaxErrorException: ORA-00917: 缺失逗号

         此时的程序中由于SQL需要拼凑的原因,那么用户一旦输入了一些敏感的字符,就有可能造成错误,严重的就有可能出现严重的安全漏洞,所以就得出结论:拼凑的SQL不能用。

         在实际的开发之中永恒不会有人去使用Statement,而都使用Statement的子接口:PreparedStatement(预处理)。提升操作的性能。那么现在如果要使用PreparedStatement接口,则就必须通过Connection接口中的新方法实例化对象:

                   · 方法:public PreparedStatement prepareStatement(String sql) throws SQLException ;

         当取得了PreparedStatement接口对象之后,就可以利用新的方法操作:

                   · 更新操作:public int executeUpdate() throws SQLException;

                   · 查询操作:public ResultSet executeQuery() throws SQLException。

         而最为重要的是,在创建PreparedStatement的时候所需要设置的内容都要通过一个占位符“?”表示,而在执行更新和查询之前,需要使用一系列的setXxx()方法设置“?”的数据。

         但是在进行setDate()方法操作的时候需要注意一点:操作的是java.sql.Date,而不是java.util.Date。java.sql.Date是java.util.Date的子类,而在java.util.Date下一共有三个子类,而且这三个子类都是保存在java.sql包之中:Date(保存日期)、Time(保存时间)、TimeStamp(时间戳,日期 + 时间)。

范例:实现数据增加

package cn.mldn.demo;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.PreparedStatement;

import java.util.Date;

public class TestDemo {

    private static final String DBDRIVER = "oracle.jdbc.driver.OracleDriver";

    private static final String DBURL = "jdbc:oracle:thin:@localhost:1521:mldn";

    private static final String DBUSER = "scott";

    private static final String PASSWORD = "tiger";

    public static void main(String[] args) throws Exception {

        String name = "Mr'SMITH" ;

        Date birthday = new Date() ;

        String note = "荒唐的世界末日" ;

        Connection conn = null; // 每一个Connection对象都表示一个连接

        PreparedStatement pstmt = null   // 定义数据库操作对象

        Class.forName(DBDRIVER); // 加载数据库驱动程序

        conn = DriverManager.getConnection(DBURL, DBUSER, PASSWORD); // 连接数据库

        // 如果在编写SQL过程之中出现换行,请一定要保证前后各加一个空格

        String sql = " INSERT INTO member(mid,name,birthday,note) "

                + " VALUES (myseq.nextval,?,?,?) " ;

        pstmt = conn.prepareStatement(sql) ;    // 创建PreparedStatement接口对象

        pstmt.setString(1, name);

        pstmt.setDate(2, new java.sql.Date(birthday.getTime()));

        pstmt.setString(3, note);

        int len = pstmt.executeUpdate() ;   // 执行SQL

        System.out.println("更新行数:" + len);

        conn.close() ;

    }

}

         在开发之中为了保证更新的质量,所有的操作一定使用的是PreparedStatement,以上做的只是一个增加(修改和删除也一样),而重点在于下面的查询操作上。

范例:查询全部数据

package cn.mldn.demo;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.util.Date;

public class TestDemo {

    private static final String DBDRIVER = "oracle.jdbc.driver.OracleDriver";

    private static final String DBURL = "jdbc:oracle:thin:@localhost:1521:mldn";

    private static final String DBUSER = "scott";

    private static final String PASSWORD = "tiger";

    public static void main(String[] args) throws Exception {

        Connection conn = null; // 每一个Connection对象都表示一个连接

        PreparedStatement pstmt = null   // 定义数据库操作对象

        Class.forName(DBDRIVER); // 加载数据库驱动程序

        conn = DriverManager.getConnection(DBURL, DBUSER, PASSWORD); // 连接数据库

        // 如果在编写SQL过程之中出现换行,请一定要保证前后各加一个空格

        String sql = " SELECT mid,name,birthday,note FROM member " ;

        pstmt = conn.prepareStatement(sql) ;

        ResultSet rs = pstmt.executeQuery() ;

        while (rs.next()) {

            int mid = rs.getInt(1) ;

            String name = rs.getString(2) ;

            Date birthday = rs.getDate(3) ;

            String note = rs.getString(4) ;

            System.out.println(mid + "," + name + "," + birthday + "," + note);

        }

        conn.close() ;

    }

}

范例:根据编号查询,查询指定编号的数据,此时只会返回单行多列数据。

package cn.mldn.demo;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.util.Date;

public class TestDemo {

    private static final String DBDRIVER = "oracle.jdbc.driver.OracleDriver";

    private static final String DBURL = "jdbc:oracle:thin:@localhost:1521:mldn";

    private static final String DBUSER = "scott";

    private static final String PASSWORD = "tiger";

    public static void main(String[] args) throws Exception {

        int mid = 15 ;  // 查询数据

        Connection conn = null; // 每一个Connection对象都表示一个连接

        PreparedStatement pstmt = null   // 定义数据库操作对象

        Class.forName(DBDRIVER); // 加载数据库驱动程序

        conn = DriverManager.getConnection(DBURL, DBUSER, PASSWORD); // 连接数据库

        // 如果在编写SQL过程之中出现换行,请一定要保证前后各加一个空格

        String sql = " SELECT mid,name,birthday,note "

                + " FROM member WHERE mid=?" ;

        pstmt = conn.prepareStatement(sql) ;

        pstmt.setInt(1, mid);

        ResultSet rs = pstmt.executeQuery() ;

        if (rs.next()) {

            mid = rs.getInt(1) ;

            String name = rs.getString(2) ;

            Date birthday = rs.getDate(3) ;

            String note = rs.getString(4) ;

            System.out.println(mid + "," + name + "," + birthday + "," + note);

        } else {

            System.out.println("没有数据返回!");

        }

        conn.close() ;

    }

}

范例:模糊查询

package cn.mldn.demo;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.util.Date;

public class TestDemo {

    private static final String DBDRIVER = "oracle.jdbc.driver.OracleDriver";

    private static final String DBURL = "jdbc:oracle:thin:@localhost:1521:mldn";

    private static final String DBUSER = "scott";

    private static final String PASSWORD = "tiger";

    public static void main(String[] args) throws Exception {

        String keyWord = "谢" ;

        Connection conn = null; // 每一个Connection对象都表示一个连接

        PreparedStatement pstmt = null   // 定义数据库操作对象

        Class.forName(DBDRIVER); // 加载数据库驱动程序

        conn = DriverManager.getConnection(DBURL, DBUSER, PASSWORD); // 连接数据库

        // 如果在编写SQL过程之中出现换行,请一定要保证前后各加一个空格

        String sql = " SELECT mid,name,birthday,note "

                + " FROM member WHERE name LIKE ?" ;

        pstmt = conn.prepareStatement(sql) ;

        pstmt.setString(1, "%" + keyWord + "%");    // 在此写%

        ResultSet rs = pstmt.executeQuery() ;

        while (rs.next()) {

            int mid = rs.getInt(1) ;

            String name = rs.getString(2) ;

            Date birthday = rs.getDate(3) ;

            String note = rs.getString(4) ;

            System.out.println(mid + "," + name + "," + birthday + "," + note);

        }

        conn.close() ;

    }

}

         如果在执行模糊查询的时候不设置任何的关键字,表示查询全部。

范例:分页显示

package cn.mldn.demo;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.util.Date;

public class TestDemo {

    private static final String DBDRIVER = "oracle.jdbc.driver.OracleDriver";

    private static final String DBURL = "jdbc:oracle:thin:@localhost:1521:mldn";

    private static final String DBUSER = "scott";

    private static final String PASSWORD = "tiger";

    public static void main(String[] args) throws Exception {

        int currentPage = 2;

        int lineSize = 5;

        String keyWord = "";

        Connection conn = null; // 每一个Connection对象都表示一个连接

        PreparedStatement pstmt = null; // 定义数据库操作对象

        Class.forName(DBDRIVER); // 加载数据库驱动程序

        conn = DriverManager.getConnection(DBURL, DBUSER, PASSWORD); // 连接数据库

        // 如果在编写SQL过程之中出现换行,请一定要保证前后各加一个空格

        String sql = "SELECT * FROM ("

                + " SELECT mid,name,birthday,note,ROWNUM rn "

                + " FROM member WHERE name LIKE ? AND ROWNUM<=?) temp "

                + " WHERE temp.rn>? ";

        pstmt = conn.prepareStatement(sql);

        pstmt.setString(1, "%" + keyWord + "%"); // 在此写%

        pstmt.setInt(2, currentPage * lineSize);

        pstmt.setInt(3, (currentPage - 1) * lineSize);

        ResultSet rs = pstmt.executeQuery();

        while (rs.next()) {

            int mid = rs.getInt(1);

            String name = rs.getString(2);

            Date birthday = rs.getDate(3);

            String note = rs.getString(4);

            System.out.println(mid + "," + name + "," + birthday + "," + note);

        }

        conn.close();

    }

}

范例:统计数据行

package cn.mldn.demo;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

public class TestDemo {

    private static final String DBDRIVER = "oracle.jdbc.driver.OracleDriver";

    private static final String DBURL = "jdbc:oracle:thin:@localhost:1521:mldn";

    private static final String DBUSER = "scott";

    private static final String PASSWORD = "tiger";

    public static void main(String[] args) throws Exception {

        String keyWord = "";

        Connection conn = null; // 每一个Connection对象都表示一个连接

        PreparedStatement pstmt = null; // 定义数据库操作对象

        Class.forName(DBDRIVER); // 加载数据库驱动程序

        conn = DriverManager.getConnection(DBURL, DBUSER, PASSWORD); // 连接数据库

        // 如果在编写SQL过程之中出现换行,请一定要保证前后各加一个空格

        String sql = "SELECT COUNT(mid) FROM member WHERE name LIKE ?";

        pstmt = conn.prepareStatement(sql);

        pstmt.setString(1, "%" + keyWord + "%"); // 在此写%

        ResultSet rs = pstmt.executeQuery();

        if (rs.next()) {    // 永恒有数据返回

            System.out.println(rs.getInt(1));

        }

        conn.close();

    }

}

         以上所给出的几个基本的数据库操作,一定要拿下,明天就要用。





5、批处理与事务处理

以上所使用的开发模式是JDBC 1.0提出来的,而现在的JDBC的版本是4.0(没人用),而且从JDBC 2.0开始就已经提出了许多新的特征:可滚动结果集、使用结果集更新数据、批处理,这之中唯一有点用处的就是批处理操作,所谓的批处理指的是一次性向数据库之中发出多条更新指令,在Statement和PreparedStatement接口里面都有对应的方法:

         · Statement接口定义的方法:

                   |- 增加批处理语句:public void addBatch(String sql) throws SQLException;

                   |- 执行批处理:public int[] executeBatch() throws SQLException;

                            |- 返回的是每一条SQL语句影响的数据行数量

         · PreparedStatement接口定义的方法:

                   |- 增加批处理:public void addBatch() throws SQLException。

范例:利用Statement来观察问题

package cn.mldn.demo;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.Statement;

public class TestDemo {

    private static final String DBDRIVER = "oracle.jdbc.driver.OracleDriver";

    private static final String DBURL = "jdbc:oracle:thin:@localhost:1521:mldn";

    private static final String DBUSER = "scott";

    private static final String PASSWORD = "tiger";

    public static void main(String[] args) throws Exception {

        Connection conn = null; // 每一个Connection对象都表示一个连接

        Statement stmt = null; // 定义数据库操作对象

        Class.forName(DBDRIVER); // 加载数据库驱动程序

        conn = DriverManager.getConnection(DBURL, DBUSER, PASSWORD); // 连接数据库

        stmt = conn.createStatement() ;

        stmt.addBatch("INSERT INTO member(mid,name) VALUES (myseq.nextval,'张三')");

        stmt.addBatch("INSERT INTO member(mid,name) VALUES (myseq.nextval,'张三')");

        stmt.addBatch("INSERT INTO member(mid,name) VALUES (myseq.nextval,'张三')");

        stmt.addBatch("INSERT INTO member(mid,name) VALUES (myseq.nextval,'张三')");

        stmt.addBatch("INSERT INTO member(mid,name) VALUES (myseq.nextval,'张三')");

        int result [] = stmt.executeBatch() ;

        for (int x = 0 ; x < result.length ; x ++) {

            System.out.print(result[x] + "、");

        }

        conn.close();

    }

}

         但是如果说现在有这样一种情况,以上五个要执行SQL语句属于一个完整业务,即:要求所有的SQL一起成功或者是一起失败。但是默认情况下,JDBC中的事务都是自动提交的,所以如果中间出现了错误,那么之前没有错的正常执行,很明显这不符合要求,所以必须手工的进行事务处理,而所有的事务处理命令都在Connection接口中定义:

                   · 提交事务:public void commit() throws SQLException;

                   · 回滚事务:public void rollback() throws SQLException;

                   · 设置自动提交与否:public void setAutoCommit(boolean autoCommit) throws SQLException。

范例:使用事务处理

package cn.mldn.demo;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.Statement;

public class TestDemo {

    private static final String DBDRIVER = "oracle.jdbc.driver.OracleDriver";

    private static final String DBURL = "jdbc:oracle:thin:@localhost:1521:mldn";

    private static final String DBUSER = "scott";

    private static final String PASSWORD = "tiger";

    public static void main(String[] args) throws Exception {

        Connection conn = null; // 每一个Connection对象都表示一个连接

        Statement stmt = null; // 定义数据库操作对象

        Class.forName(DBDRIVER); // 加载数据库驱动程序

        conn = DriverManager.getConnection(DBURL, DBUSER, PASSWORD); // 连接数据库

        stmt = conn.createStatement() ;

        conn.setAutoCommit(false);// 取消自动提交

        try {

        stmt.addBatch("INSERT INTO member(mid,name) VALUES (myseq.nextval,'张三')");

        stmt.addBatch("INSERT INTO member(mid,name) VALUES (myseq.nextval,'张三')");

        stmt.addBatch("INSERT INTO member(mid,name) VALUES (myseq.nextval,'张三')");

        stmt.addBatch("INSERT INTO member(mid,name) VALUES (myseq.nextval,'张三')");

        stmt.addBatch("INSERT INTO member(mid,name) VALUES (myseq.nextval,'张三')");

        int result [] = stmt.executeBatch() ;

        for (int x = 0 ; x < result.length ; x ++) {

            System.out.print(result[x] + "、");

        }

        conn.commit(); // 提交事务

        } catch (Exception e) {

            e.printStackTrace();

            conn.rollback();

        }

        conn.close();

    }

}

         因为日后的开发之中,事务都是自动处理的,用户只需要编写代码就行了。






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值