1. 程式人生 > >Mybatis從入門到精通——從JDBC程式設計開始

Mybatis從入門到精通——從JDBC程式設計開始

[toc]

JDBC是什麼 (Java DataBase Connectivity)

jdbc是一種Java程式語言和各種資料庫之間資料庫無關連線的行業標準, JDBC API為基於SQL的資料庫訪問提供了呼叫級API

資料庫無關

在沒有JDBC之前,我們需要編寫不同的程式對接不同廠商的資料庫系統,像下圖所示,需要針對不同的資料庫api程式設計,可想而知,當我們需要更換資料庫系統而產生的大量重複工作,增加不必要的開發成本

圖片來至Java從初學到精通

而JDBC的出現,統一了Java程式訪問不同資料庫系統的api,應用程式通過呼叫JDBC來操作資料庫時,實際上是右資料庫系統廠商提供的JDBC驅動程式來完成的。這樣一來,即使要更換資料庫系統,也僅僅是更換相應的驅動程式就可以了。(本文使用mysql的驅動程式)

圖片來至Java從初學到精通

JDBC API主要完成以下三個工作:

  • 建立與資料庫的連線或訪問任何表格資料來源
  • 傳送SQL語句到資料庫
  • 處理資料返回的結果

這三個工作中都有其對應的jdbc api來完成各自的任務。應用程式可以使用這些api 來操作資料庫系統了

JDBC API

DriverManager

管理JDBC驅動的服務類,主要功能是獲取Connection物件(示例程式中的第2步)

getConnection方法

Connection getConnection(url,username,password)

  • 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物件

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 {
            //1、載入驅動
            Class.forName("com.mysql.jdbc.Driver");
            //2、獲取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();
        }
        //4、釋放資源 寫到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:小明
複製程式碼

業務邏輯程式碼中如果有錯誤,連線物件將執行回滾操作,保證資料的一致性。