• jdbc知识点(连接mysql)


    jdbc连接mysql

     

    1.JDBC简介

    JDBC:

      指 Java 数据库连接,是一种标准Java应用编程接口( JAVA API),用来连接 Java 编程语言和广泛的数据库。从根本上来说,JDBC 是一种规范,它提供了一套完整的接口,允许便携式访问到底层数据库

     

    常见的 JDBC 组件:

     JDBC 的 API 提供了以下接口和类:

      DriverManager :这个类管理一系列数据库驱动程序。匹配连接使用通信子协议从 JAVA 应用程序中请求合适的数据库驱动程序。识别 JDBC 下某个子协议的第一驱动程序将被用于建立数据库连接。

      Driver : 这个接口处理与数据库服务器的通信。你将很少直接与驱动程序互动。相反,你使用 DriverManager 中的对象,它管理此类型的对象。它也抽象与驱动程序对象工作相关的详细信息。

      Connection : 此接口具有接触数据库的所有方法。该连接对象表示通信上下文,即,所有与数据库的通信仅通过这个连接对象进行。

      Statement : 使用创建于这个接口的对象将 SQL 语句提交到数据库。除了执行存储过程以外,一些派生的接口也接受参数。

      ResultSet : 在你使用语句对象执行 SQL 查询后,这些对象保存从数据获得的数据。它作为一个迭代器,让您可以通过它的数据来移动。

      SQLException : 这个类处理发生在数据库应用程序的任何错误。

     

    JDBC 4.0 软件包:

      JDBC 4.0 主要包含 java.sql 包和 javax.sql 包,提供的主要类与数据源进行交互。

     

    2.JDBC SQL语法

    SQL语法:

      结构化查询语言(SQL)是一种标准化的语言,可以让你对数据库进行curd操作,如创建项目,读取内容,更新内容和删除项目。SQL 支持你可能会使用到的任何数据库,它可以让你编写独立于底层数据库的数据库代码

     

    创建数据库语法:create database 数据库名;
    如:create database hejh;
    删除数据库语法:drop database 数据库名;
    如:drop database hejh;

    注意:1.创建或删除数据库,必须有数据库服务器的管理员权限;

       2.删除数据库会把存储在该数据库中的数据一并删除。

    创建表语法:
      create table 表名(
          字段名1 字段类型1,
         字段名2 字段类型2,
        ......
      );
    建表示例:
      create table hejh(
        id int not null,
        age int not null,
        frist varchar(20),
        last varchar(20),
        primary key(id)
      );
    删除表语法:drop table 表名;
    如:drop table hejh;
    insert语法:insert into 表名 values(字段值1,字段值2,...);  --(这种方式默认插入所有字段的值) 
    如:insert into hejh values(1,22,'19990405','20190505');

     

    select语法:select 字段1,字段2,... from 表名  where 查询限制条件;
      如:select * from hejh where id=1;

    注意:WHERE 子句可以使用 =,!=,<,>,<=,>=,BETWEEN 和 LIKE 这些比较操作符。
    update语法:updata 表名 set 字段=字段新值 where 条件;
    如:update hejh set age=33 where id=1;
    注意:where子句可以使用=,!=,<,>,<=,>=,between和 like 这些比较操作符。
    delete语法:delete from 表名 where 条件;
    如:delete from hejh where id=1;
    注意:where子句可以使用=,!=,<,>,<=,>=,between 和 like 这些比较操作符

     3.设置JDBC使用环境

     

     在开始使用 JDBC 之前,必须设置 JDBC 环境。(以mysql、windows系统为例)

      1.安装jdk,配置环境变量;

      2.安装mysql数据库;

      3.安装eclipse;

     

    4.JDBC简单示例

    创建数据库:hejh;

      create database hejh;

      

    创建用户表:user表

    create table user(
        id int(5) not null,
        username varchar(20) not null,
        gender varchar(4),
        primary key(id)
    );

     

    初始化数据:

     

    创建JDBC应用程序

    构建一个 JDBC 应用程序包括以下六个步骤:

    • 导入数据包:导入含有需要进行数据库编程的 JDBC 类的包。大多数情况下,使用 import java.sql.就足够了。

    • 注册 JDBC 驱动器:需要你初始化一个驱动器,以便于你打开一个与数据库的通信通道。

    • 打开连接:需要使用 DriverManager.getConnection() 方法创建一个 Connection 对象,它代表与数据库的物理连接。

    • 执行查询:需要使用类型声明的对象建立并提交一个 SQL 语句到数据库。

    • 提取结果数据:要求使用适当的 ResultSet.getXXX() 方法从结果集中检索数据。

    • 清理环境:依靠 JVM 的垃圾收集来关闭所有需要明确关闭的数据库资源。

     

    查看数据库hejh中user表的数据有3条:

     java源码如下:

    package com.hejh.day0506;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    
    import org.junit.Test;
    
    public class JdbcTest1 {
        
        static final String driver = "com.mysql.jdbc.Driver";
        static final String url = "jdbc:mysql://localhost/hejh";
        static final String user = "root";
        static final String password = "root";
        
        //开启junit局部测试
        @Test
        public void run() {
            
            ResultSet rs=null;
            Statement st = null;
            Connection conn =null;
            
           try {
                //注册驱动
                Class.forName(driver);
                
                //获取连接
                conn = DriverManager.getConnection(url, user, password);
                
                //获取sql执行对象
                st =  conn.createStatement();
                
                //编写sql语句
                String sql = "select * from user";
                
                //执行sql语句,返回一个结果集
                rs =  st.executeQuery(sql);
                
              //处理结果集
                while(rs.next()) {
                    int id = rs.getInt("id");
                    String name = rs.getString("username");
                    String gender = rs.getString("gender");
                    System.out.println("["+id+","+name+","+gender+"]");
                }
                
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
           //关闭资源,后开启的先关闭
    try { if(rs!=null) { rs.close(); }else { rs=null; } } catch (SQLException e) { e.printStackTrace(); } if(st!=null) { try { st.close(); } catch (SQLException e) { e.printStackTrace(); } }else { st=null; } if(conn!=null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } }else { conn=null; } } } }

    junit局部测试结果如下:

    第一个jdbc案例完成。

     

    4.JDBC 驱动类型

    什么是 JDBC 驱动程序?

      JDBC 驱动实现了 JDBC API 中定义的接口,该接口用于与数据库服务器进行交互。例如,使用 JDBC 驱动程序可以让你打开数据库连接,并通过发送 SQL 或数据库命令,然后通过 Java 接收结果。java.sql 包中附带的 JDK,包含了定义各种类与他们的行为和实际实现,这些类都在第三方驱动程序中完成。第三方供应商在他们的数据库驱动程序中都实现了 java.sql.Driver 接口。

     

    JDBC驱动程序类型:

      JDBC 驱动程序的实现,因为各种各样的操作系统和 Java 运行在硬件平台的不同而不同。Sun 公司将实现类型分为四类:

        1.JDBC-ODBC桥驱动程序

        2.JDBC-Native API

        3.JDBC-Net纯Java

        4.100%纯Java

    具体参见资料:https://www.w3cschool.cn/jdbc/j3xk1myd.html

      

    该使用哪种驱动程序?

      如果你正在访问一个数据库,如 Oracle,Sybase 或 IBM,首选的驱动程序是类型4。

      如果你的 Java 应用程序同时访问多个数据库类型,类型3是首选的驱动程序。

      类型2驱动程序是在你的数据库没有提供类型3或类型4驱动程序时使用的。

      类型1驱动程序不被认为是部署级的驱动程序,它存在的目的通常仅用于开发和测试。

     

     5.JDBC连接数据库

     

    编写建立一个 JDBC 连接的程序是相当简单的,下面是简单的四个步骤:

    • 导入 JDBC 包:在你的 Java 代码中,用 import 语句添加你所需的类。

    • 注册 JDBC 驱动程序:这一步会导致 JVM 加载所需的驱动程序到内存中执行,因此它可以实现你的 JDBC 请求。

    • 数据库 URL 制定:这是用来创建格式正确的地址指向你想要连接的数据库。

    • 创建连接对象:最后,代码调用 DriverManager 对象的 getConnection() 方法来建立实际的数据库连接。

     

    1.导入jar包

      import 语句告诉 Java 编译器在哪里可以找到你在代码中引用的类,这些引用放置在你的源代码起始位置。使用标准的 JDBC 包,它允许你选择,插入,更新和删除 SQL 表中的数据,添加以下引用到您的源代码中。

    import java.sql.*;
    import javax.sql.*;

    2.注册JDBC驱动程序  

      方法1 - Class.forName()

       注册一个驱动程序中最常用的方法是使用 Java 的Class.forName() 方法来动态加载驱动程序的类文件到内存中,它会自动将其注册。这种方法更优越一些,因为它允许你对驱动程序的注册信息进行配置,便于移植。

    //注册驱动
    Class.forName(“com.mysql.jdbc.Driver”);//会报异常

      方法2 - DriverManager.registerDriver() 

      你注册一个驱动程序的第二种方法是使用静态 staticDriverManager.registerDriver() 方法。如果你使用的是不兼容 JVM 的非 JDK,比如微软提供的,你必须使用 registerDriver() 方法

    try {
       Driver myDriver = new oracle.jdbc.driver.OracleDriver();
       DriverManager.registerDriver( myDriver );
    }
    catch(ClassNotFoundException ex) {
       System.out.println("Error: unable to load driver class!");
       System.exit(1);
    }

     3.数据库url制定

      当你加载了驱动程序之后,你可以通过 DriverManager.getConnection() 方法建立一个连接。

    为方便参考,以下列出了三个加载 DriverManager.getConnection() 方法:

    • getConnection(String url)
    • getConnection(String url, Properties prop)
    • getConnection(String url, String user, String password)

      在这里,每个格式需要一个数据库 URL ,数据库 URL 是指向数据库的地址。在建立一个数据连接的时候,大多数会在配置一个数据库 URL 时遇到问题。下表列出了常用的 JDBC 驱动程序名和数据库URL。

    RDBMSJDBC 驱动程序名称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

     URL 格式所有加粗的部分都是静态的,你需要将剩余部分按照你的数据库实际情况进行设置

     

    4.创建连接对象 

     调用适当的用户名和密码以及 getConnection() 方法来获得一个 Connection 对象

    static final String url = "jdbc:mysql://localhost/hejh";
    static final String user = "root";
    static final String password = "root";

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

    使用数据库 URL 和 Properties 对象:

      第三种 DriverManager.getConnection() 方法调用需要数据库 URL 和 Properties 对象-

    DriverManager.getConnection(String url, Properties info);

      Properties 对象保存了一组关键数值。它通过调用 getConnection() 方法,将驱动程序属性传递给驱动程序。使用下面的代码可以建立与上述示例相同的连接:

    import java.util.*;
    
    String URL = "jdbc:mysql://localhost/hejh";
    Properties info = new Properties( );
    info.put( "user", "username" );
    info.put( "password", "password" );
    
    Connection conn = DriverManager.getConnection(URL, info);

    5.关闭 JDBC 连接

      在 JDBC 程序的末尾,必须明确关闭所有连接到数据库的连接,以结束每个数据库会话。但是,如果忘了,Java 垃圾收集器也会关闭连接,它会完全清除过期的对象。依托垃圾收集器,特别是在数据库编程,是非常差的编程习惯。你应该养成用 close()方法关闭连接对象的习惯。为了确保连接被关闭,你可以在代码中的 'finally' 程序块中执行。 无论异常是否发生,finally 程序是肯定会被执行的。要关闭上面打开的连接,应该调用 close()方法,如下所示:

    finally {
                try {
                    if(rs!=null) {
                        rs.close();
                    }else {
                            rs=null;
                        }    
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                if(st!=null) {
                    try {
                        st.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }else {
                    st=null;
                }
                if(conn!=null) {
                    try {
                        conn.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }else {
                    conn=null;
                }
            }

    6.JDBC Statement 对象

     

    1.Statement 对象

      获得了数据库的连接,就可以和数据库进行交互了。JDBC 的 Statement,CallableStatement 和 PreparedStatement 接口定义的方法和属性,可以发送 SQL 命令或 PL/SQL 命令到数据库,并从数据库接收数据。在数据库中,它们还定义了帮助 Java 和 SQL 数据类型之间转换数据差异的方法。下表提供了每个接口的用途概要,根据实际目的决定使用哪个接口。

    接口推荐使用
    Statement 可以正常访问数据库,适用于运行静态 SQL 语句。 Statement 接口不接受参数。
    PreparedStatement 计划多次使用 SQL 语句, PreparedStatement 接口运行时接受输入的参数。
    CallableStatement 适用于当你要访问数据库存储过程的时候, CallableStatement 接口运行时也接受输入的参数。

     

    创建 Statement 对象:

    使用 Statement 对象执行 SQL 语句之前,需要用 Connection 对象创建一个 Statement()对象,如下面的示例所示:

    Statement stmt = null;
    try {
       stmt = conn.createStatement( );
       . . .
    }
    catch (SQLException e) {
       . . .
    }
    finally {
       . . .
    }

    当创建了一个 Statement 对象之后,可以用它的三个执行方法的任一方法来执行 SQL 语句:

    • boolean execute(String SQL) : 如果 ResultSet 对象可以被检索,则返回的布尔值为 true ,否则返回 false 。当你需要使用真正的动态 SQL 时,可以使用这个方法来执行 SQL DDL 语句。

    • int executeUpdate(String SQL) : 返回执行 SQL 语句影响的行的数目。使用该方法来执行 SQL 语句,是希望得到一些受影响的行的数目,例如,INSERT,UPDATE 或 DELETE 语句。

    • ResultSet executeQuery(String SQL) : 返回一个 ResultSet 对象。当你希望得到一个结果集时使用该方法,就像你使用一个 SELECT 语句。

     

    关闭 Statement 对象:

      正如关闭一个 Connection 对象来节约数据库资源,出于同样的原因你也应该关闭 Statement 对象。简单的调用 close() 方法就可以完成这项工作。如果关闭了 Connection 对象,那么它也会关闭 Statement 对象。然而,你应该始终明确关闭 Statement 对象,以确保真正的清除。

    Statement stmt = null;
    try {
       stmt = conn.createStatement( );
       . . .
    }
    catch (SQLException e) {
       . . .
    }
    finally {
       stmt.close();//会报异常
    }

    PreparedStatement 对象:

      PreparedStatement 接口扩展了 Statement 接口,它让你用一个常用的 Statement 对象增加几个高级功能。这个 statement 对象可以提供灵活多变的动态参数。创建 PreparedStatement 对象:

    PreparedStatement pstmt = null;
    try {
       String SQL = "update user set age = ? where id = ?";
       pstmt = conn.prepareStatement(SQL);
      psmt.setInt(1,22);
      psmt.setInt(2,1); . . . }
    catch (SQLException e) { . . . } finally { . . . }

      JDBC 中所有的参数都被用 ? 符号表示,这是已知的参数标记。在执行 SQL 语句之前,你必须赋予每一个参数确切的数值。setXXX() 方法将值绑定到参数,其中 XXX 表示你希望绑定到输入参数的 Java 数据类型。如果你忘了赋予值,你将收到一个 SQLException。每个参数标记映射它的序号位置。第一标记表示位置 1 ,下一个位置为 2 等等。这种方法不同于 Java 数组索引是从 0 开始的。所有的 Statement对象 的方法都与数据库交互,(a) execute(),(b) executeQuery(),及 (c) executeUpdate() 也能被 PreparedStatement 对象引用。然而,这些方法被 SQL 语句修改后是可以输入参数的。

    关闭 PreparedStatement 对象

      关闭 PreparedStatement 对象,简单的调用 close() 方法可以完成这项工作。如果你关闭了 Connection 对象,那么它也会关闭 PreparedStatement 对象。然而,你应该始终明确关闭 PreparedStatement 对象,以确保真正的清除。

    PreparedStatement pstmt = null;
    try {
       String SQL = "Update Employees SET age = ? WHERE id = ?";
       pstmt = conn.prepareStatement(SQL);
       . . .
    }
    catch (SQLException e) {
       . . .
    }
    finally {
       pstmt.close();//会报异常
    }

    CallableStatement 对象:

      正如一个 Connection 对象可以创建 Statement 对象和 PreparedStatement 对象,它也可以创建被用来执行调用数据库存储过程的 CallableStatement 对象。

     在 MySQL 的 EMP 数据库中创建相同的存储过程:

    DELIMITER $$
    
    DROP PROCEDURE IF EXISTS `EMP`.`getEmpName` $$
    CREATE PROCEDURE `EMP`.`getEmpName` 
       (IN EMP_ID INT, OUT EMP_FIRST VARCHAR(255))
    BEGIN
       SELECT first INTO EMP_FIRST
       FROM Employees
       WHERE ID = EMP_ID;
    END $$
    
    DELIMITER ;

      三种类型的参数有:IN,OUT 和 INOUT。PreparedStatement 对象只使用 IN 参数。CallableStatement 对象可以使用所有的三个参数。这里是每个参数的定义:

    参数描述
    IN 在 SQL 语句创建的时候该参数是未知的。你可以用 setXXX() 方法将值绑定到IN参数中。
    OUT 该参数由 SQL 语句的返回值提供。你可以用 getXXX() 方法获取 OUT 参数的值。
    INOUT 该参数同时提供输入输出的值。你可以用 setXXX() 方法将值绑定参数,并且用 getXXX() 方法获取值。

     下面的代码片段展示了基于存储过程如何使用 Connection.prepareCall() 方法来实例化 CallableStatement 对象。

    CallableStatement cstmt = null;
    try {
       String SQL = "{call getEmpName (?, ?)}";
       cstmt = conn.prepareCall (SQL);
       . . .
    }
    catch (SQLException e) {
       . . .
    }
    finally {
       . . .
    }

     7.结果集

     结果集:

      SQL 语句从数据库查询中获取数据,并将数据返回到结果集中。SELECT 语句是一种标准的方法,它从一个数据库中选择行记录,并显示在一个结果集中。 java.sql.ResultSet 接口表示一个数据库查询的结果集。一个 ResultSet 对象控制一个光标指向当前行的结果集。术语“结果集”是指包含在 ResultSet 对象中的行和列的数据。

    ResultSet 接口的方法可细分为三类:

    • 导航方法:用于移动光标。
    • 获取方法:用于查看当前行被光标所指向的列中的数据。
    • 更新方法:用于更新当前行的列中的数据。这些更新也会更新数据库中的数据。

      光标的移动基于 ResultSet 的属性。用相应的语句生成 ResultSet 对象时,同时生成 ResultSet 的属性。JDBC 提供了连接方法通过下列创建语句来生成你所需的 ResultSet 对象:

    • createStatement(int RSType, int RSConcurrency);
    • prepareStatement(String SQL, int RSType, int RSConcurrency);
    • prepareCall(String sql, int RSType, int RSConcurrency);

    第一个参数表示 ResultSet 对象的类型,第二个参数是两个 ResultSet 常量之一,该常量用于判断该结果集是只读的还是可修改的

     

    ResultSet的类型:

      可能的 RSType 如下所示。如果你不指定 ResultSet 类型,将自动获得的值是 TYPE_FORWARD_ONLY。

    类型描述
    ResultSet.TYPE_FORWARD_ONLY 光标只能在结果集中向前移动。
    ResultSet.TYPE_SCROLL_INSENSITIVE 光标可以向前和向后移动。当结果集创建后,其他人对数据库的操作不会影响结果集的数据。
    ResultSet.TYPE_SCROLL_SENSITIVE. 光标可以向前和向后移动。当结果集创建后,其他人对数据库的操作会影响结果集的数据。

     

    ResultSet的并发性:

      RSConcurrency 的值如下所示,如果你不指定并发类型,将自动获得的值是 CONCUR_READ_ONLY。

    并发性描述
    ResultSet.CONCUR_READ_ONLY 创建一个只读结果集,这是默认的值。
    ResultSet.CONCUR_UPDATABLE 创建一个可修改的结果集。

    示例可以如下所示,初始化一个 Statement 对象,来创建一个只能前进而且只读的 ResultSet 对象:

    try {
       Statement stmt = conn.createStatement( ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
    }
    catch(Exception ex) {
       ....
    }
    finally {
       ....
    }

    导航结果集:

      在 ResultSet 接口中包括如下几种方法涉及移动光标-

    S.N.方法 & 描述
    1 public void beforeFirst() throws SQLException

    将光标移动到第一行之前。

    2 public void afterLast() throws SQLException

    将光标移动到最后一行之后。

    3 public boolean first() throws SQLException

    将光标移动到第一行。

    4 public void last() throws SQLException

    将光标移动到最后一行。

    5 public boolean absolute(int row) throws SQLException

    将光标移动到指定的第 row 行。

    6 public boolean relative(int row) throws SQLException

    将光标移动到当前指向的位置往前或往后第 row 行的位置。

    7 public boolean previous() throws SQLException

    将光标移动到上一行,如果超过结果集的范围则返回 false。

    8 public boolean next() throws SQLException

    将光标移动到下一行,如果是结果集的最后一行则返回 false。

    9 public int getRow() throws SQLException

    返回当前光标指向的行数的值。

    10 public void moveToInsertRow() throws SQLException

    将光标移动到结果集中指定的行,可以在数据库中插入新的一行。当前光标位置将被记住。

    11 public void moveToCurrentRow() throws SQLException

    如果光标处于插入行,则将光标返回到当前行,其他情况下,这个方法不执行任何操作。

     

    查看结果集:

    ResultSet接口中含有几十种从当前行获取数据的方法。每个可能的数据类型都有一个 get 方法,并且每个 get 方法有两个版本-

    • 一个需要列名。
    • 一个需要列的索引。

    例如,如果你想查看的列包含一个 int 类型,你需要在 ResultSet 中调用 getInt()方法-

    S.N.方法 & 描述
    1 public int getInt(String columnName) throws SQLException

    返回当前行中名为 columnName 的列的 int 值。

    2 public int getInt(int columnIndex) throws SQLException

    返回当前行中指定列的索引的 int 值。列索引从 1 开始,意味着行中的第一列是 1 ,第二列是 2 ,以此类推。

    同样的,在 ResultSet 接口中还有获取八个 Java 原始类型的 get 方法,以及常见的类型,比如 java.lang.String,java.lang.Object 和java.net.URL。

    也有用于获取 SQL 数据类型 java.sql.Date, java.sql.Time, java.sql.Timestamp, java.sql.Clob,java.sql.Blob 中的方法。查看文档可以了解使用这些 SQL 数据类型的更多的信息。

     

    更新的结果集:

    ResultSet 接口包含了一系列的更新方法,该方法用于更新结果集中的数据。用 get 方法可以有两个更新方法来更新任一数据类型:

    • 一个需要列名。
    • 一个需要列的索引。

    例如,要更新一个结果集的当前行的 String 列,你可以使用任一如下所示的 updateString()方法-

    S.N.方法 & 描述
    1 public void updateString(int columnIndex, String s) throws SQLException

    将指定列的字符串的值改为 s。

    2 public void updateString(String columnName, String s) throws SQLException

    类似于前面的方法,不同之处在于指定的列是用名字来指定的,而不是它的索引。

    八个原始数据类型都有其更新方法,比如 String,Object,URL,和在 java.sql 包中的 SQL 数据类型。

    更新结果集中的行将改变当前行的列中的 ResultSet 对象,而不是基础数据库中的数据。要更新数据库中一行的数据,你需要调用以下的任一方法:

    S.N.方法 & 描述
    1 public void updateRow()

    通过更新数据库中相对应的行来更新当前行。

    2 public void deleteRow()

    从数据库中删除当前行。

    3 public void refreshRow()

    在结果集中刷新数据,以反映数据库中最新的数据变化。

    4 public void cancelRowUpdates()

    取消对当前行的任何修改。

    5 public void insertRow()

    在数据库中插入一行。本方法只有在光标指向插入行的时候才能被调用。

     

    8.JDBC数据类型

     

      JDBC 驱动程序在将 Java 数据类型数据发送到数据库之前,会将其转换为相应的 JDBC 类型数据,对于大多数数据类型都采用了默认的映射关系。例如,一个 Java int 数据类型转换为 SQL INTEGER。通过默认的映射关系来提供驱动程序之间的一致性。当你调用 PreparedStatement 中的 setXXX()方法或 CallableStatement 对象或 ResultSet.updateXXX()方法时, Java 数据类型会转换为默认的 JDBC 数据类型,如下表概述。

    SQLJDBC/JavasetXXXupdateXXX
    VARCHAR java.lang.String setString updateString
    CHAR java.lang.String setString updateString
    LONGVARCHAR java.lang.String setString updateString
    BIT boolean setBoolean updateBoolean
    NUMERIC java.math.BigDecimal setBigDecimal updateBigDecimal
    TINYINT byte setByte updateByte
    SMALLINT short setShort updateShort
    INTEGER int setInt updateInt
    BIGINT long setLong updateLong
    REAL float setFloat updateFloat
    FLOAT float setFloat updateFloat
    DOUBLE double setDouble updateDouble
    VARBINARY byte[ ] setBytes updateBytes
    BINARY byte[ ] setBytes updateBytes
    DATE java.sql.Date setDate updateDate
    TIME java.sql.Time setTime updateTime
    TIMESTAMP java.sql.Timestamp setTimestamp updateTimestamp
    CLOB java.sql.Clob setClob updateClob
    BLOB java.sql.Blob setBlob updateBlob
    ARRAY java.sql.Array setARRAY updateARRAY
    REF java.sql.Ref SetRef updateRef
    STRUCT java.sql.Struct SetStruct updateStruct


      JDBC 3.0 增强了对 BLOB,CLOB,ARRAY 和 REF 数据类型的支持。 ResultSet 对象现在有 UPDATEBLOB(),updateCLOB(), updateArray(),和 updateRef()方法,通过这些方法你可以直接操作服务器上的相应数据。

    你能用 setXXX()方法和 updateXXX()方法将 Java 类型转换为特定的 JDBC 数据类型。你能用 setObject()方法和 updateObject()方法将绝大部分的 Java 类型映射到 JDBC 数据类型。

      ResultSet 对象为任一数据类型提供相应的 getXXX()方法,该方法可以获取任一数据类型的列值。上述任一方法的使用需要列名或它的顺序位置。

    SQLJDBC/JavasetXXXgetXXX
    VARCHAR java.lang.String setString getString
    CHAR java.lang.String setString getString
    LONGVARCHAR java.lang.String setString getString
    BIT boolean setBoolean getBoolean
    NUMERIC java.math.BigDecimal setBigDecimal getBigDecimal
    TINYINT byte setByte getByte
    SMALLINT short setShort getShort
    INTEGER int setInt getInt
    BIGINT long setLong getLong
    REAL float setFloat getFloat
    FLOAT float setFloat getFloat
    DOUBLE double setDouble getDouble
    VARBINARY byte[ ] setBytes getBytes
    BINARY byte[ ] setBytes getBytes
    DATE java.sql.Date setDate getDate
    TIME java.sql.Time setTime getTime
    TIMESTAMP java.sql.Timestamp setTimestamp getTimestamp
    CLOB java.sql.Clob setClob getClob
    BLOB java.sql.Blob setBlob getBlob
    ARRAY java.sql.Array setARRAY getARRAY
    REF java.sql.Ref SetRef getRef
    STRUCT java.sql.Struct SetStruct getStruct

     

    日期和时间数据类型:

      java.sql.Date 类映射 SQL DATE 类型,java.sql.Time 类和 java.sql.Timestamp 类也分别映射 SQL TIME 数据类型和 SQL TIMESTAMP 数据类型。以下示例显示了日期和时间类如何转换成标准的 Java 日期和时间值,并匹配成 SQL 数据类型所要求的格式。

    package com.hejh.day0507;
    import java.util.Date;
    
    public class TimeTest {
        public static void main(String[] args) {
            
            //java util 打印当前具体时间
            Date utilDate = new Date();
            long utilTime = utilDate.getTime();
            System.out.println("java util date:"+utilDate.toString());//java util date:Tue May 07 17:14:53 CST 2019
            
            //sql 打印当前时间(某年-某月-某日)
            java.sql.Date sqlDate  = new java.sql.Date(utilTime);
            System.out.println("java sql date:"+sqlDate.toString());//java sql date:2019-05-07
            
            //sql  打印当前时间(时:分:秒)
            java.sql.Time sqlTime  = new java.sql.Time(utilTime);
            System.out.println("java sql time:"+sqlTime.toString());//java sql time:17:34:33
            
            //sql 打印当前具体时间(某年-某月-某日 时:分:秒)
            java.sql.Timestamp sqlTimeStamp  = new java.sql.Timestamp(utilTime);
            System.out.println("java sql Timestamp:"+sqlTimeStamp.toString());//java sql Timestamp:2019-05-07 17:36:44.176    
        }
    }

    处理 NULL 值:

    SQL 使用 NULL 值和 Java 使用 null 是不同的概念。那么,你可以使用三种策略来处理 Java 中的 SQL NULL 值:

    • 避免使用返回原始数据类型的 getXXX()方法。
    • 使用包装类的基本数据类型,并使用 ResultSet 对象的 wasNull()方法来测试收到 getXXX()方法返回的值是否为 null,如果是 null,该包装类变量则被设置为 null。
    • 使用原始数据类型和 ResultSet 对象的 wasNull()方法来测试通过 getXXX()方法返回的值,如果是 null,则原始变量应设置为可接受的值来代表 NULL。

    下面是一个处理 NULL 值的示例:

    Statement stmt = conn.createStatement( );
    String sql = "SELECT id, first, last, age FROM Employees";
    ResultSet rs = stmt.executeQuery(sql);
    
    int id = rs.getInt(1);
    if( rs.wasNull( ) ) {
       id = 0;
    }

     9.JDBC事务

    事务: 

      如果 JDBC 连接是处于自动提交模式下,该模式为默认模式,那么每句 SQL 语句都是在其完成时提交到数据库。对简单的应用程序来说这种模式相当好,但有三个原因你可能想关闭自动提交模式,并管理你自己的事务:

    • 为了提高性能
    • 为了保持业务流程的完整性
    • 使用分布式事务

    你可以通过事务在任意时间来控制以及更改应用到数据库。它把单个 SQL 语句或一组 SQL 语句作为一个逻辑单元,如果其中任一语句失败,则整个事务失败。

      若要启用手动事务模式来代替 JDBC 驱动程序默认使用的自动提交模式的话,使用 Connection 对象的的 setAutoCommit()方法。如果传递一个布尔值 false 到 setAutoCommit()方法,你就关闭自动提交模式。你也可以传递一个布尔值 true 将其再次打开。例如,如果有一个名为 conn 的 Connection 对象,以下的代码将关闭自动提交模式:

    conn.setAutoCommit(false);//关闭自动提交模式

     提交和回滚:

       当完成修改,并且要提交修改,可以在 connection 对象里调用 commit()方法,如下所示:

    conn.commit( );

      

    在默认情况下,事务自动提交,源码和数据库数据如下:

    package com.hejh.day0508;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;
    
    import org.junit.Test;
    
    public class AffairTest {
        
        static final String driver = "com.mysql.jdbc.Driver";
        static String url = "jdbc:mysql://localhost/hejh";
        static final String username = "root";
        static final String password = "root";
        
        @Test
        public void run() {
            Connection conn = null;
            PreparedStatement ps = null;
            try {
                Class.forName(driver);
                conn = DriverManager.getConnection(url, username, password);
                String sql = "update user set username = ?  where id = ? ";
                
                ps = conn.prepareStatement(sql);
                ps.setString(1,"hejh11");
                ps.setInt(2, 1);
                int i = ps.executeUpdate();
                System.out.println("影响了:"+i+"行");        //影响了:1行
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                try {
                    if(ps!=null) {
                        ps.close();
                    }else {
                        ps=null;
                    }        
                } catch (Exception e) {
                    e.printStackTrace();
                }
                try {
                    if(conn!=null) {
                        conn.close();
                   }else {
                            conn=null;
                        }
                } catch (SQLException e) {
                            e.printStackTrace();
                        }
                    
            }//finally
        }
    }

    设置为手动提交,运行下面的源码(替换try-catch部分代码),数据库数据刷新结果如下:

    try {
                Class.forName(driver);
                conn = DriverManager.getConnection(url, username, password);
                String sql = "update user set username = ?  where id = ? ";
                //在执行sql之前,设置事务为手动提交
                conn.setAutoCommit(false);//手动提交事务,数据不会发生变化
                ps = conn.prepareStatement(sql);
                ps.setString(1,"hejh111");
                ps.setInt(2, 1);
                int i = ps.executeUpdate();
                System.out.println("影响了:"+i+"行");        //影响了:1行
            } catch (Exception e) {
                e.printStackTrace();
            }

     设置为手动提交,并且在sql执行后,手动提交一下事务,运行下面的源码(替换try-catch部分代码),数据库数据刷新结果如下:

    try {
                Class.forName(driver);
                conn = DriverManager.getConnection(url, username, password);
                String sql = "update user set username = ?  where id = ? ";
                //在执行sql之前,设置事务为手动提交
                conn.setAutoCommit(false);//手动提交事务,数据不会发生变化
                ps = conn.prepareStatement(sql);
                ps.setString(1,"hejh111");
                ps.setInt(2, 1);
                int i = ps.executeUpdate();
                //sql语句执行后,手动提交事务,使sql生效
                conn.commit();
                System.out.println("影响了:"+i+"行");        //影响了:1行
            } catch (Exception e) {
                e.printStackTrace();
            }

     另外,用名为 conn 的连接回滚数据到数据库,

    conn.rollback( );//可以放在catch块中

    还原点:

      新的 JDBC 3.0 还原点接口提供了额外的事务控制。大部分现代的数据库管理系统的环境都支持设定还原点,例如 Oracle 的 PL/SQL。当你在事务中设置一个还原点来定义一个逻辑回滚点。如果在一个还原点之后发生错误,那么可以使用 rollback 方法来撤消该还原点之后所做的修改。

    Connection 对象有两个新的方法来管理还原点:

    • setSavepoint(String savepointName): 定义了一个新的还原点,返回一个 Savepoint 对象。

    • releaseSavepoint(Savepoint savepointName): 删除一个还原点。请注意,参数是一个 Savepoint 对象,这个对象通常是由 setSavepoint() 方法生成的一个还原点。

    有一个 rollback (String savepointName) 方法,该方法可以回滚到指定的还原点。下面的例子说明了如何使用 Savepoint 对象:

    package com.hejh.day0508;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;
    import java.sql.Savepoint;
    
    import org.junit.Test;
    
    public class SavePointTest {
    	
    	@Test
    	public void save() throws SQLException {
    		Connection conn = null;
    		 PreparedStatement ps =null;
    		 Savepoint beforeInsert = null;
    		try {
    			Class.forName("com.mysql.jdbc.Driver");
    			//prepareStatement插入的中文参数有可能会出现问号,可以在这里指定一下字符编码为utf-8
    			conn  = DriverManager.getConnection("jdbc:mysql://localhost/hejh?useUnicode=true&characterEncoding=UTF-8",
                                                                 "root", "root"); //设置一个还原点 beforeInsert = conn.setSavepoint(); String sql = "insert into user values(?,?,?)"; ps = conn.prepareStatement(sql); ps.setInt(1,4); ps.setString(2, "hejh222"); ps.setString(3, "男"); int i = ps.executeUpdate(); System.out.println("插入了:"+i+"行数据"); } catch (Exception e) { //回滚到还原点BeforeInsert处 conn.rollback(beforeInsert); e.printStackTrace(); }finally { try { if(ps!=null) { ps.close(); }else { ps = null; } } catch (SQLException e) { e.printStackTrace(); } try { if(beforeInsert!=null) { conn.releaseSavepoint(beforeInsert); }else { beforeInsert=null; } } catch (SQLException e) { e.printStackTrace(); } try { if(conn!=null) { conn.close(); }else { conn=null; } } catch (SQLException e) { e.printStackTrace(); } } } }

      

     10.JDBC异常

     异常:

      异常处理可以允许你处理一个异常情况,例如可控方式的程序定义错误。当异常情况发生时,将抛出一个异常。抛出这个词意味着当前执行的程序停止,控制器被重定向到最近的适用的 catch 子句。如果没有适用的 catch 子句存在,那么程序执行被终止。JDBC 的异常处理是非常类似于 Java 的异常处理,但对于 JDBC,最常见的异常是 java.sql.SQLException

    SQLException:

      SQLException 异常在驱动程序和数据库中都可能出现。当出现这个异常时,SQLException 类型的对象将被传递到 catch 子句。传递的 SQLException 对象具有以下的方法,以下的方法可用于检索该异常的额外信息:

    方法描述
    getErrorCode( ) 获取与异常关联的错误号。
    getMessage( ) 获取 JDBC 驱动程序的错误信息,该错误是由驱动程序处理的,或者在数据库错误中获取 Oracl 错误号和错误信息。
    getSQLState( ) 获取 XOPEN SQLstate 字符串。对于 JDBC 驱动程序错误,使用该方法不能返回有用的信息。对于数据库错误,返回第五位的 XOPEN SQLstate 代码。该方法可以返回 null。
    getNextException( ) 获取异常链的下一个 Exception 对象。
    printStackTrace( ) 打印当前异常或者抛出,其回溯到标准的流错误。
    printStackTrace(PrintStream s) 打印该抛出,其回溯到你指定的打印流。
    printStackTrace(PrintWriter w) 打印该抛出,其回溯到你指定的打印写入。

    通过利用可从 Exception 对象提供的信息,你可以捕获异常并继续运行程序。这是一个 try 块的一般格式:

    try {
       // 可能出现异常的代码
    }
    catch(Exception ex) {
       //异常的捕捉和处理
    }
    finally {// 必须执行的操作,想数据库的资源关闭,
    }
    package com.hejh.day0508;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;
    import java.sql.Savepoint;
    
    import org.junit.Test;
    
    public class ExceptionTest {
        
        @Test
        public void save() throws SQLException {
            Connection conn = null;
             PreparedStatement ps =null;
             Savepoint beforeInsert = null;
            try {
                Class.forName("com.mysql.jdbc.Driver");
                //1.数据库用户名和密码不符(root,hejh),实际用户名密码为(root,root)
                conn  = DriverManager.getConnection("jdbc:mysql://localhost/hejh?useUnicode=true&characterEncoding=UTF-8", "root", "hejh");
                
                String sql = "insert into user values(?,?,?)";
                 ps = conn.prepareStatement(sql);
                 ps.setInt(1,4);
                 ps.setString(2, "hejh200");
                 ps.setString(3, "男");
                int i =  ps.executeUpdate();
                System.out.println("插入了:"+i+"行数据");
            } catch (Exception e) {
                //2.在这里捕获异常,并将异常信息打印到控制台
                e.printStackTrace();
            }finally {
                try {
                    if(ps!=null) {
                        ps.close();
                    }else {
                        ps = null;
                    }                
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                try {
                    if(beforeInsert!=null) {
                        conn.releaseSavepoint(beforeInsert);
                    }else {
                        beforeInsert=null;
                    }
                    
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                try {
                    if(conn!=null) {
                        conn.close();
                    }else {
                        conn=null;
                    }
                    
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }         
        }    
        
    }

    出现以下异常:

    java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: YES)
    ......

     11.JDBC批处理

     批处理:

      批处理是指你将关联的 SQL 语句组合成一个批处理,并将他们当成一个调用提交给数据库。当你一次发送多个 SQL 语句到数据库时,可以减少通信的资源消耗,从而提高了性能。

    • JDBC 驱动程序不一定支持该功能。你可以使用 DatabaseMetaData.supportsBatchUpdates() 方法来确定目标数据库是否支持批处理更新。如果你的JDBC驱动程序支持此功能,则该方法返回值为 true。

    • Statement,PreparedStatement 和 CallableStatement 的 addBatch() 方法用于添加单个语句到批处理。

    • executeBatch() 方法用于启动执行所有组合在一起的语句。

    • executeBatch() 方法返回一个整数数组,数组中的每个元素代表了各自的更新语句的更新数目。

    • 正如你可以添加语句到批处理中,你也可以用 clearBatch() 方法删除它们。此方法删除所有用 addBatch() 方法添加的语句。但是,你不能有选择性地选择要删除的语句。

    Statement 对象执行批处理:

    使用 Statement 对象来使用批处理所需要的典型步骤如下所示-

    • 使用 createStatement() 方法创建一个 Statement 对象。
    • 使用 setAutoCommit() 方法将自动提交设为 false。
    • 被创建的 Statement 对象可以使用 addBatch() 方法来添加你想要的所有SQL语句。
    • 被创建的 Statement 对象可以用 executeBatch() 将所有的 SQL 语句执行。
    • 最后,使用 commit() 方法提交所有的更改。

    批量执行3条insert语句,示例如下:

    package com.hejh.day0508;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    import java.sql.Statement;
    
    import org.junit.Test;
    import org.omg.Messaging.SyncScopeHelper;
    
    //批处理
    public class Batching {
        
        @Test
        public void test() {
            Connection conn = null;
            Statement st = null;
            try {
                //注册驱动
                Class.forName("com.mysql.jdbc.Driver");
                
                //获取链接
                conn = DriverManager.getConnection("jdbc:mysql://localhost/hejh?useUnicode=true&characterEncoding=UTF-8", "root", "root");
                
                //设置为:手动提交事务
                conn.setAutoCommit(false);
                
                //编写3个insert sql语句
                String sql1 = "insert into user values(4,'sss','女')";
              String sql2 = "insert into user values(5,'www','男')";
              String sql3 = "insert into user values(6,'yyy','女')";
                
                //获取statement对象
                st = conn.createStatement();
                
                //添加sql语句到批处理
                st.addBatch(sql1);
                st.addBatch(sql2);
                st.addBatch(sql3);
                
                //执行批处理,返回一个整数数组,数组中的每个元素代表了各自的更新语句的更新数目
                int[] arr = st.executeBatch();
                
                //事务提交,使sql语句生效
                conn.commit();
                
                //处理数组
                System.out.print("影响行数为:");
                for(int i=0;i<arr.length;i++) {
                    System.out.print(arr[i]+"  ");//影响行数为:1  1  1  
                }
                
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                try {
                    if(st!=null) {
                        st.close();
                    }else {
                        st = null;
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                try {
                    if(conn!=null) {
                        conn.close();
                    }else {
                        conn = null;
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            
            
        }
        
    }

    批处理和 PrepareStatement 对象:

    使用 prepareStatement 对象来使用批处理需要的典型步骤如下所示:

    • 使用占位符创建 SQL 语句。
    • 使用任一 prepareStatement() 方法创建 prepareStatement 对象。
    • 使用 setAutoCommit() 方法将自动提交设为 false。
    • 被创建的 Statement 对象可以使用 addBatch() 方法来添加你想要的所有 SQL 语句。
    • 被创建的 Statement 对象可以用 executeBatch() 将所有的 SQL 语句执行。
    • 最后,使用 commit() 方法提交所有的更改。

     示例如下:

    package com.hejh.day0508;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;
    
    import org.junit.Test;
    
    public class PrepareStatementBatching {
        
        @Test
        public void test() {
            Connection conn = null;
            PreparedStatement ps = null;
            try {
                //注册驱动
                Class.forName("com.mysql.jdbc.Driver");
                
                //获取链接
                conn = DriverManager.getConnection("jdbc:mysql://localhost/hejh?useUnicode=true&characterEncoding=UTF-8", "root", "root");
                
                //设置为:手动提交事务
                conn.setAutoCommit(false);
                
                //编写sql语句
                String sql = "update user set username=? where id=?";
                            
                //获取statement对象
                ps = conn.prepareStatement(sql);
                
                //添加第一个sql语句到批处理
                ps.setString(1, "s");
                ps.setInt(2, 4);
                ps.addBatch();
                //添加第二个sql语句到批处理
                ps.setString(1, "w");
                ps.setInt(2, 5);
                ps.addBatch();
                //添加第三个sql语句到批处理
                ps.setString(1, "y");
                ps.setInt(2, 6);
                ps.addBatch();
                
                //执行批处理,返回一个整数数组,数组中的每个元素代表了各自的更新语句的更新数目
                int []arr  = ps.executeBatch();
                
                //提交事务,使sql语句生效
                conn.commit();
                
                //处理数组 
               System.out.print("分别影响了:");
            for(int i=0;i<arr.length;i++) {
                System.out.print(arr[i]+"  ");  //分别影响了:1行   1行   1行 
            }
                
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                try {
                    if(ps!=null) {
                        ps.close();
                    }else {
                        ps = null;
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                try {
                    if(conn!=null) {
                        conn.close();
                    }else {
                        conn = null;
                    }
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }        
        }    
    }

    12.JDBC流数据

    流数据:

        PreparedStatement 对象必须具备使用输入和输出流来提供参数数据的能力。这使你能够将整个文件存储到数据库列中,这样数据库就能存储大型数据,例如 CLOB 和 BLOB 数据类型。

    用于流数据有下列几种方法:

    • setAsciiStream(): 该方法是用来提供较大的 ASCII 值。
    • setCharacterStream(): 该方法是用来提供较大的 UNICODE 值。
    • setBinaryStream(): 该方法是用来提供较大的二进制值。

    setXXXStream()方法需要一个额外的参数,该参数是除了参数占位符的文件大小。这个参数通知驱动程序通过使用流有多少数据被发送到数据库中。

    假如我们到要上传一个名为 hejh.xml 的 XML 文件到数据库的表中。下面是该 XML 文件的内容

    <?xml version="1.0"?>
    <hejh>
        <id>1</id>
        <username>hjh</username>
        <gender>男</gender>
    </hejh>

    将该 xml_data.xml文件和要运行的示例保存在相同的目录的。这个示例将创建一个数据库表 xml_data ,然后 xml_data.xml 将被上传到该表中。

    将下面的示例拷贝并粘帖到 JDBCStreamingDate.java 中,编译并运行它,如下所示:

    package com.hejh.day0509;
    
    import java.io.ByteArrayOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    
    public class JDBCStreamingDate {
        public static void main(String[] args)throws SQLException, IOException {
            Connection conn = null;
            Statement st  = null;
            PreparedStatement pps = null;
            ResultSet rs = null;
            try {
                //注册驱动
                Class.forName("com.mysql.jdbc.Driver");            
                //获取连接
                conn = DriverManager.getConnection("jdbc:mysql://localhost/hejh?useUnicode=true&characterEncoding=UTF-8", "root", "root");            
                //获取 Statement 对象,来创建一张xml_data表
                st = conn.createStatement();
                createXMLTable(st);            
                //将xml_data.xml文件读取进来
                File file = new File("src/xml_data.xml");
                long fileLength  = file.length();
                FileInputStream fis = new FileInputStream(file);            
                //获取  对象,给表插入数据,并执行sql
                String sql = "insert into xml_data values(?,?)";
                pps = conn.prepareStatement(sql);
                pps.setInt(1, 100);
                pps.setAsciiStream(2, fis,(int)fileLength );
                pps.execute();            
                //关闭输入流
                fis.close();                
                String selectSql = "select data from xml_data where id =100";
                rs = st.executeQuery(selectSql);
                InputStream is = null;
                ByteArrayOutputStream bos = null;
                if(rs.next()) {
                    is = rs.getAsciiStream(1);    
                    int c ;
                    //获取输出流,将带数据的hejh.xml文件输出
                    bos = new ByteArrayOutputStream();
                    while((c=is.read())!=-1) {
                        bos.write(c);
                    }
                }            
                System.out.println(bos.toString());
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }finally {//关闭资源
                if(rs!=null) {
                    rs.close();
                }else {
                    rs = null;
                }
                if(pps!=null) {
                    pps.close();
                }else {
                    pps = null;
                }
                if(st!=null) {
                    st.close();
                }else {
                    st = null;
                }
                if(conn!=null) {
                    conn.close();
                }else {
                    conn = null;
                }        
            }    
        }
    
        //创建一张表,表名xml_data
        public static void createXMLTable(Statement st) throws SQLException {
            //sql语句,创建一张表xml_data
            
            String createTable = "create table xml_data(id int,data long)";
            //删除表xml_data
            String dropTable  = "drop table xml_data";    
            //在建表前,应该先删除表,如果存在相同的表名的话
            try {
                st.execute(dropTable);
            } catch (SQLException e) {
                e.printStackTrace();
            }    
            //创建表
            st.executeUpdate(createTable);        
        }    
    }

    console输出为:

    <?xml version="1.0" encoding="UTF-8"?>
    <hejh>
        <id>1</id>
        <username>hjh</username>
        <gender>男</gender>
    </hejh>

    数据库表现为:

    本博文参考w3cschool网JDBC指南一文,附上网址:https://www.w3cschool.cn/jdbc/bgqu1my6.html

  • 相关阅读:
    忆2011年的秋天:一个人的项目
    横看成岭侧成峰,远近高低各不同——从面试官的角度谈面试
    使用Scratch进行少儿编程
    初识少儿编程
    升级openssl
    CentOS设置虚拟网卡做NAT方式和Bridge方式桥接
    iptables conntrack有什么用
    nohup和&的区别
    Linux就这个范儿 第12章 一个网络一个世界
    一个由INode节点爆满引起的业务故障
  • 原文地址:https://www.cnblogs.com/hejh/p/10811847.html
Copyright © 2020-2023  润新知