JDBC編程指南

[toc]java

JDBC是什麼 (Java DataBase Connectivity)

jdbc是一種Java編程語言和各類數據庫之間 數據庫無關鏈接的行業標準,
JDBC API爲基於SQL的數據庫訪問提供了調用級API

數據庫無關

在沒有JDBC以前,咱們須要編寫不一樣的程序對接不一樣廠商的數據庫系統,像下圖所示,須要針對不一樣的數據庫api編程,可想而知,當咱們須要更換數據庫系統而產生的大量重複工做,增長沒必要要的開發成本mysql

圖片來至Java從初學到精通

而JDBC的出現,統一了Java程序訪問不一樣數據庫系統的api,應用程序經過調用JDBC來操做數據庫時,其實是右數據庫系統廠商提供的JDBC驅動程序來完成的。這樣一來,即便要更換數據庫系統,也僅僅是更換相應的驅動程序就能夠了。(本文使用mysql的驅動程序)sql

圖片來至Java從初學到精通

JDBC API主要完成如下三個工做:

  • 創建與數據庫的鏈接或訪問任何表格數據源
  • 發送SQL語句到數據庫
  • 處理數據返回的結果

這三個工做中都有其對應的jdbc api來完成各自的任務。應用程序可使用這些api 來操做數據庫系統了數據庫

JDBC API

DriverManager

管理JDBC驅動的服務類,主要功能是獲取Connection對象(示例程序中的第2步)編程

getConnection方法

Connection getConnection(url,username,password)api

  • url寫法:jdbc:mysql://localhost:3306/mydb

本地數據庫簡寫:jdbc:mysql:///mydb框架

  • jdbc:協議
  • mysql:子協議
  • localhost:主機名
  • 3306:端口號
  • mydb:數據庫名稱

Connection

數據庫鏈接對象,每一個Connection對象表示一個鏈接會話。編程語言

Connection的經常使用方法

1. 返回Statement對象

  • Statement createStatement()
  • PreparedStatement PreparedStatement(String sql):Statement的子類,將SQL語句提交到數據庫進行預編譯
  • CallableStatement prepareCall(String sql)Statement的子類,處理存儲過程

2. 處理事務的經常使用方法

  • void setAutoCommit(boolean autoCommit):設置是否自動提交,默認true
  • void commit:提交事務
  • void rollback:事務回滾
  • Savepoint setSavepoint:建立一個保存點
  • Savepoint setSavepoint(Stirng name):指定名稱來建立一個保存點
  • void rollback(Savepoint savepoint):將事務回滾到指定的保存點
  • void setTransactionIsolation(int level):設置事務隔離級別

Statement

執行具體的SQL語句,以及執行DDL、DCL、DML語句。性能

Statement子類 PreparedStatement

預編譯的Statement對象ui

SQL語句一次編譯屢次執行

容許數據庫預編譯SQL語句(常帶有參數或者叫佔位符),這樣一來,之後每次只須要改變SQL命令的參數,而不須要每次都編譯SQL語句,性能獲得了提高

PreparedStatement主要方法
  • void setXXX(int parmIndex,XXX value):設置預編譯語句的參數

Statement經常使用方法

  • ResultSet executeQuery(String sql):只能執行查詢語句,返回ResultSet
  • int executeUpdate(String sql):主要用於執行DML語句的,返回受影響行數。
  • boolean execute(String sql):執行任何SQL語句
  • addBatch(String sql):添加到批處理
  • executeBatch():執行批處理
  • clearBatch():清空批處理

ResultSet

結果集:查詢結果的封裝

ResultSet主要方法

移動指針的方法
  • next():移動指針到ResultSet記錄的下一行,若是存在該條記錄返回true
  • .......
獲取當前行、指定列的值
  • getInt()、getString()針對不一樣數據類型的方法,
  • 通用的兩個泛型方法<T> T getObject(int columnIndex,Class<T> type)、<T> T getObject(String columnLabel,Class<T> type)

JDBC實際操做

建庫建表的SQL語句

-- 建庫
CREATE DATABASE `mydb` CHARACTER SET utf8 COLLATE utf8_general_ci;
-- 建表
CREATE TABLE IF NOT EXISTS `user`(
   `id` INT UNSIGNED AUTO_INCREMENT,
   `username` VARCHAR(100) NOT NULL,
   `password` VARCHAR(40) NOT NULL,
   `name` VARCHAR(40) NOT NULL,
   PRIMARY KEY ( `id` )
)ENGINE=InnoDB DEFAULT CHARSET=utf8;

示例程序框架

咱們會在業務邏輯代碼start的地方開始具體的執行操做

public void excute() throws SQLException {
        Connection conn = null;
        PreparedStatement smt = null;
        ResultSet resultset = null;
        try {
            //一、加載驅動
            Class.forName("com.mysql.jdbc.Driver");
            //二、獲取Connection對象
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb?characterEncoding=utf-8", "root", "******");
            if (conn != null) {
                System.out.println("鏈接成功");
            }
            conn.setAutoCommit(false);
            //業務邏輯代碼start
            //插入數據操做
            String insertSql = "insert into user(username,password,name) values(?,?,?)";
            smt = conn.prepareStatement(insertSql);
            smt.setString(1, "xiaoming");
            smt.setString(2, "123");
            smt.setString(3, "小明");
            int result = smt.executeUpdate();
            if (result > 0) {
                System.out.println("添加成功");
            }
            smt.clearParameters();

            //修改數據操做
            String updateSql = "update user set name=? where id=?";
            smt = conn.prepareStatement(updateSql);
            smt.setString(1, "小牛");
            smt.setInt(2, 2);
            int updateResult = smt.executeUpdate();
            if (updateResult > 0) {
                System.out.println("修改爲功");
            }
            smt.clearParameters();

            //查詢數據操做
            String sql = "select *from user where id =?";
            smt= conn.prepareStatement(sql);
            smt.setInt(1,3);
            resultset = smt.executeQuery();
            while (resultset.next()) {
                int uid = resultset.getInt("id");
                System.out.println(String.format("id:%s,username:%s,password:%s,name:%s", uid, 
                        resultset.getString("username"), 
                        resultset.getString("password"), 
                        resultset.getString("name")));
            }
            //業務邏輯代碼end
        conn.commit();
        } catch (Exception e) {
            System.out.println(e);
            conn.rollback();
        }
        //四、釋放資源 寫到finally裏面,防止報錯不能執行資源回收
        finally {
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (smt != null) {
                try {
                    smt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (resultset != null) {
                try {
                    resultset.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }

執行結果

鏈接成功
添加成功
修改爲功
id:3,username:xiaoming,password:123,name:小明

業務邏輯代碼中若是有錯誤,鏈接對象將執行回滾操做,保證數據的一致性。