JDBC学习总结(一)

1、JDBC概述
    JDBC是一种可以执行SQL语句并可返回结果的Java API,其全称是Java DataBase Connectivity,也是一套面向对象的应用程序接口API,它由一组用Java编程语言编写的类和接口组成,制定了统一的访问各类关系数据库的标准接口,为各种常用数据库提供了标准接口的实现,通过它可访问各类关系数据库,使开发者能够用纯Java API来编写数据库应用程序。JDBC API中定义了一些Java类,分别用来表示与数据库的连接(Connections)、SQL语句(SQL Statements)、结果集(Result Set)以及其他的数据库对象,使得Java程序能方便地与数据库交互并处理所得的结果。
    
2、JDBC数据类型
JDBC类型 Java类型
CAHR String
VARCHAR String
LONGVARCHAR String
NUMERIC java.math.BigDecimal
DECIMAL java.math.BigDecimal
BIT Boolean
BOOLEAN Boolean
TINYINT byte
SMALLINT short
INTEGET int
BIGINT long
REAL float
FLOAT double
BOUBLE double
BINARY byte[]
VARBONARY byte[]
LONGVARBINARY byte[]
DATE java.sql.Date
TIME java.sql.Time
TIMESTAMP java.sql.Timestamp
CLOB Clob
BLOB Blob
ARRAY Array
DISTINCT mapping of underlying type
STRUCT struct
REF Ref
DATALINK java.net.URL
JAVA_OBJECT underlying Java class
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3、JDBC连接数据库
1)加载JDBC驱动程序
    通过java.lang.Class类的静态方法forName(String className)实现。
 try{
        Class.forName("com.mysql.jdbc.Driver");
    }catch(ClassNotFoundException e){
        System.out.println("找不到驱动程序类");
        e.printStackTrace();
    }
 当成功加载后,会将Driver类的实例注册到DriverManager类中。
 
2)提供JDBC连接的URL
    连接URL定义了连接数据库时的协议、子协议、数据源标识。协议在JDBC中总是以jdbc开始;子协议是连接的驱动程序或是数据库管理系统的名称,例如MYSQL就是mysql;数据源标识就是找出数据库来源的地址和连接端口。
jdbc:mysql://localhost:3306/test?userUnicode=true&characterEncoding=gbk.
        useUnicode=true表示使用Unicode字符集,如果参数characterEncoding设置为gb2312或GBK,本参数必须设置为true。
 
3)创建数据库的连接
    要连接数据库,可以向java.sql.DriverManager 请求并获得 Connection对象,该对象就代表一个数据库连接,可以使用DriverManger的getConnection(String url,String userName, String password)方法传入指定的欲连接的数据库的路径、数据库的用户名和密码来获得。
 String url = "jdbc:mysql://localhost:3306/test?userUnicode=true&characterEncoding=gbk";
    String userName = "root";
    String password = "123456";
    try{
        Connection conn = DriverManager.getConnection(url,userName,password);
    }catch(SQLException e){
        System.out.println("Failed to get connection: "+e.getMessage());
        e.printStackTrace();
    }
 
4)创建一个Statement
    要执行SQL语句,必须获得java.sql.Statement实例,Statement实例又可以分为以下3种类型:
        · 执行静态SQL语句,通常通过Statement实例实现;
        · 执行动态SQL语句,通常通过PreparedStatement实例实现;
        · 执行数据库存储过程,通常通过CallableStatement实例实现。
Statement stmt = conn.createStatement();
PreparedStatement pstmt = conn.preparedStatement(sql);
CallableStatement cstmt = conn.prepareCall("{CALL demoSp(?,?)}");

5)执行SQL语句

    Statement接口提供了三种执行SQL语句的方法:executeQuery、executeUpdate和execute,具体事宜哪一个,由SQL语句所产生的内容来决定。
    1)ResultSet executeQuery(String sqlString):执行查询数据库的SQL,如SELECT语句,返回一个结果集(ResultSet)对象。
    2)int executeUpdate(String sqlString):用于执行INSET、UPDATE或DELETE语句以及SQL DDL(数据定义语言)语句,例如CREATE TABLE和DROP TABLE。INSET、UPDATE或DELETE的效果是修改表中零行或多行中的一列或多列,所以executeUpdate的返回值是一个整数,表示受影响的行数(即更新及数)。对于CREATE TABLE或DROP TABLE等不操作行的语句,executeUpdate的返回值总为零。
    3)execute(sqlString):用于执行返回多个结果集、多个更新技术或二者组合的语句。
ResultSet rs = stmt.executeQuery("SELECT * FROM ...");
int rows = stmt.executeUpdate("INSERT INTO ...");
boolean flag = stmt.execute(String sqlString);
 
6)处理结果
    执行的结果可能会出现如下两种情况:
        · 执行更新返回的是本次操作影响到的记录数;
        · 执行查询返回的结果是一个ResultSet对象。
    ResultSet包含符合SQL语句中条件的所有行,并且它通过一套get方法提供了对这些行中数据的访问。
    (1)使用结果集(ResultSet)对象的访问方法获取数据。
        · next():用于移动到ResultSet中的下一行,使下一行成为当前行;
        · first():将光标移动到此ResultSet对象的第一行;
        · last():将光标移到到此ResultSet对象的最后一行;
        · previous():将光标移动到此ResultSet对象的上一行。
    (2)通过字段名或列索引取得数据:
String name = rs.getString("name");
String pass = rs.getString(1);
     (3)使用行和光标。ResultSet维护指向当前数据行的光标。每调用一次next()方法,光标向下移动一行,初始化位置为第一行记录之前,因此第一次应先调用next()将光标置于第一行上,使它成为当前行。随着每次调用next(),导致光标向下移动一行,按照从上到下的顺序获得ResultSet行。在ResultSet对象或Statement对象关闭之前,光标一直保持有效。       
 
7)关闭JDBC对象
    在操作完成之后,要把所使用的JDBC对象全部关闭,以释放JDBC资源,关闭的顺序是声明顺序的反序。
    1)关闭记录集;
    2)关闭声明;
    3)关闭连接对象。
finally{
        //关闭记录集
        if (null != rs){
            try{
                rs.close();
            }catch (SQLException e){
                e.printStackTrace();
            }
        }
        //关闭声明
        if (null != stmt){
            try {
                stmt.close();
            }catch (SQLException e){
                e.printStackTrace();
            }
        }
        //关闭连接对象
        if (null != conn){
            try{
                conn.close();
            }catch (SQLException e){
                e.printStackTrace();
            }
        }
    }
 
4、JDBC事务控制
    所谓事务,是指一组原子操作(一组SQL语句的执行)的工作单元。这个工作单元中的所有原子操作在进行期间,与其他事务隔离,免于因数据来源的交相更新而发生混乱,事务中的所有原子操作要么全部执行成功,要么全部失败。
    1)设置事务的提交方式为非自动提交:
conn.setAutoCommit(false);

 2)将需要添加事务的代码放在try、catch块中:

try{
    //需要添加事务的业务代码
    ...
}catch(SQLException e){
    ...
}

  3)在try块内添加提交操作,表示操作无异常,提交事务:

conn.commit(); 

  4)在catch块内添加回滚事务,表示操作出现异常,撤销事务:

conn.rollback();

  5)设置事务提交方式为自动提交:

conn.setAutoCommit(true);

  在JDBC处理事务的过程中,也可以设置事务的回滚点,当事务回滚的时候,自动回滚到保存点。

Savepoint savepoint = conn.setSavepoint();
conn.rollback(savepoint);
stmt.releaseSavepoint(savepoint);

    注意:如要数据表支持事务,则在MySQL中建立的表类型为InnoDB。

package com.yyq;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
/**
 * Created by gao on 16-4-12.
 */
public class Transaction {
    public static final String Driver = "com.mysql.jdbc.Driver";
    public static final String URL = "jdbc:mysql://localhost:3306/test";
    public static final String USER_NAME = "root";
    public static final String PASSWORD = "123456";
    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        String sql = "INSERT INTO student(name,score,class) values(?,null,null)";
        String sql2 = "delete from student where id = 69";
        try {
            Class.forName(Driver);
            conn = DriverManager.getConnection(URL, USER_NAME, PASSWORD);
            conn.setAutoCommit(false);
            pstmt = conn.prepareStatement(sql);
            pstmt.setString(1,"testing");
            System.out.println("第一条语句执行....");
            pstmt.executeUpdate();
            pstmt = conn.prepareStatement(sql2);
            System.out.println("第二条语句执行....");
            pstmt.executeQuery();
            conn.commit();
            System.out.println("提交事务");
        }catch (ClassNotFoundException e){
            System.out.println("找不到驱动程序类");
            e.printStackTrace();
        }catch (SQLException e){
            try{
                conn.rollback();
                System.out.println("回退事务....");
                e.printStackTrace();
            }catch (SQLException e1){
                e1.printStackTrace();
            }
        }finally {
            try{
                conn.setAutoCommit(true);
            }catch (SQLException e){
                e.printStackTrace();
            }
            if (null != pstmt){
                try{
                    pstmt.close();
                }catch (SQLException e){
                    e.printStackTrace();
                }
            }
            if (null != conn){
                try {
                    conn.close();
                }catch (SQLException e){
                    e.printStackTrace();
                }
            }
        }
    }
}

 

5、JDBC批量处理
    Statement的execute()等方法一次只能执行一条SQL语句,如果同时有多条SQL语句要执行的话,可以实现addBatch()方法将要执行的SQL语句加入进来,然后执行executeBatch()方法,这样就可以在一次方法调用中执行多条SQL语句,以提高执行效率。但是批处理中执行的语句只能是更新语句(inset、delete、update),否则会抛出异常。
try {
            conn.setAutoCommit(false);
            Statement stmt = conn.createStatement();
            stmt.addBatch("....");
            stmt.addBatch("....");
            .....
            stmt.executeBatch();
            conn.commit();
        }catch (SQLException e){
            try {
                conn.rollback();
            }catch (SQLException e1){
                e1.printStackTrace();
            }
            e.printStackTrace();
        }finally {
            try {
                conn.setAutoCommit(true);
            }catch (SQLException e){
                e.printStackTrace();
            }
            //关闭资源
        }

 

posted @ 2016-04-13 15:19  我是一名老菜鸟  阅读(942)  评论(0编辑  收藏  举报