JDBC基礎學習筆記


第一章:JDBC 概述

  第一節:JDBC 簡介

    JDBC(Java Data Base Connectivity,java 數據庫連接)是一種用於執行 SQL 語句的 JavaAPI,可以為多種關系 數據庫提供統一訪問,它由一組用 Java 語言編寫的類和接口組成。JDBC 提供了一種基准,據此可以構建更高 級的工具和接口,使數據庫開發人員能夠編寫數據庫應用程序。

  第二節:JDBC 原理

    JDBC 原理:JDBC 是以前 SUN 公司定義的一套訪問數據庫的接口(沒有具體實現),一套標准,具體的實現是由 各大數據庫廠家去實現,每個數據庫廠家都有自己的 JDBC 實現,也就是 JDBC 驅動實現類,Java 應用程序連接 指定數據庫,需要使用廠家提供的 JDBC 驅動才能連接。(這里其實就是 java 多態的一種體現,一個接口可以有 很多具體的實現)

 

 

第二章:JDBC 連接數據庫

  第一節:JDBC 連接數據庫步驟

    第一步:加載驅動;

       第二步:連接數據庫;

    第三步:使用語句操作數據庫;

    第四步:關閉數據庫連接,釋放資源;

  第二節:在項目里配置數據庫驅動

    右擊項目 -> Build Path -> Configure Build Path -> Add Exteranl JARs..

  第三節:加載數據驅動

    Mysql 驅動名:com.mysql.jdbc.Driver

    加載方式: Class.forName(驅動名);即Class.forName("com.mysql.jdbc.Driver");

  第四節:連接及關閉數據庫

    1,DriverManager 驅動管理類,主要負責獲取一個數據庫的連接;

static Connection getConnection(String url, String user, String password) 試圖建立到給定數據庫 URL 的連 接。

例如Connection con=DriverManager.getConnection("jdbc:mysql://localhost:3306/db_book", "root", "123456");

     2,MySQL 數據庫的連接地址格式

 jdbc:mysql://IP 地址:端口號/數據庫名稱
jdbc 協議:JDBC
URL 中的協議總是 jdbc ;
子協議:驅動程序名或數據庫連接機制(這種機制可由一個或多個驅動程序支持)的名稱,如 mysql; 子
名稱:一種標識數據庫的方法。必須遵循“//主機名端口/子協議”的標准 URL 命名約定,如 //localhost:3306/db_book

    3,Connection 接口 與特定數據庫的連接(會話)。

 void close() 立即釋放此 Connection 對象的數據庫和 JDBC 資源,而不是等待它們被自動釋放

 

 

第三章:使用 Statement 接口實現增,刪,改操作

    作用:用於執行靜態 SQL 語句並返回它所生成結果的對象。

    

利用Statement stmt=con.createStatement(); 獲取Statement對象。
int executeUpdate(String sql) 執行給定 SQL 語句,該語句可能為 INSERT、UPDATE 或DELETE 語句,或 者不返回任何內容的 SQL 語句(如 SQL DDL 語句)。
void close() 立即釋放此 Statement 對象的數據庫和 JDBC 資源,而不是等待該對象自動關閉時發生此操作。

    注:1.可以將Statemant與Connection的close寫在一個方法中

      如:

public void close(Statement stmt,Connection con)throws Exception{
		if(stmt!=null){
			stmt.close();
			if(con!=null){
				con.close();
			}
		}
	}

      2.stmt.executeUpdate(sql);會返回一個int類型的result,可以用這個判斷是否語句是否成功,成功的話會返回1。

 

 

第四章:使用 PreparedStatement 接口實現增,刪,改操作

  PreparedStatement 是 Statement 的子接口,屬於預處理操作,與直接使用 Statement 不同的是,PreparedStatement 在操作時,是先在數據表中准備好了一條 SQL 語句,但是此 SQL 語句的具體內容暫時不設置,而是之后再進 行設置。

(以后開發一般用 PreparedStatement,不用 Statement)

    寫入數據時可以這么做

	private static int addBook(Book book)throws Exception{
		Connection con=dbUtil.getCon(); // 獲取連接
		String sql="insert into t_book values(null,?,?,?,?)";
		PreparedStatement pstmt=con.prepareStatement(sql);
		pstmt.setString(1, book.getBookName());  // 給第一個坑設置值
		pstmt.setFloat(3, book.getPrice());  // 給第二個坑設置值
		pstmt.setString(2, book.getAuthor()); // 給第三個坑設置值
		pstmt.setInt(4, book.getBookTypeId());  // 給第四個坑設置值
		int result=pstmt.executeUpdate();
		dbUtil.close(pstmt, con);
		return result;
	}

    

 

 

第五章: ResultSet 結果集

    第一節:ResultSet 結果集的引入

      當我們查詢數據庫時,返回的是一個二維的結果集,我們這時候需要使用 ResultSet 來遍歷結果集,獲取每一行 的數據。

    第二節:使用 ResultSet 遍歷查詢結果

boolean next() 將光標從當前位置向前移一行。 String getString(int columnIndex) 以 Java 編程語言中 String 的形式獲取此 ResultSet 對象的當前行中指定列 的值。 String getString(String columnLabel) 以 Java 編程語言中 String 的形式獲取此 ResultSet 對象的當前行中指 定列的值。

    讀取數據時可以分別以這三種形式:利用index,關鍵字,或者直接獲取一個對象。

private static void listBook() throws Exception {
        Connection con = dbUtil.getCon(); // 獲取連接
        String sql = "select * from t_book";
        PreparedStatement pstmt = con.prepareStatement(sql);
        ResultSet rs = pstmt.executeQuery(); // 返回結果集ResultSet//默認在第0行
        while (rs.next()) {
            int id = rs.getInt(1); // 獲取第一個列的值 編號id
            String bookName = rs.getString(2); // 獲取第二個列的值 圖書名稱 bookName
            float price = rs.getFloat(4); // 獲取第三列的值 圖書價格 price
            String author = rs.getString(3); // 獲取第四列的值 圖書作者 author
            int bookTypeId = rs.getInt(5); // 獲取第五列的值 圖書類別id
            System.out.println("圖書編號:" + id + " 圖書名稱:" + bookName + " 圖書價格:"
                    + price + " 圖書作者:" + author + " 圖書類別id:" + bookTypeId);
            System.out
                    .println("=======================================================================");

        }
    }
private static void listBook2() throws Exception {
        Connection con = dbUtil.getCon(); // 獲取連接
        String sql = "select * from t_book";
        PreparedStatement pstmt = con.prepareStatement(sql);
        ResultSet rs = pstmt.executeQuery(); // 返回結果集ResultSet
        while (rs.next()) {
            int id = rs.getInt("id"); // 獲取第一個列的值 編號id
            String bookName = rs.getString("bookName"); // 獲取第二個列的值 圖書名稱 bookName
            float price = rs.getFloat("price"); // 獲取第三列的值 圖書價格 price
            String author = rs.getString("author"); // 獲取第四列的值 圖書作者 author
            int bookTypeId = rs.getInt("bookTypeId"); // 獲取第五列的值 圖書類別id
            System.out.println("圖書編號:" + id + " 圖書名稱:" + bookName + " 圖書價格:"
                    + price + " 圖書作者:" + author + " 圖書類別id:" + bookTypeId);
            System.out
                    .println("=======================================================================");

        }
    }
private static List<Book> listBook3()throws Exception{
        List<Book> bookList=new ArrayList<Book>(); 
        Connection con = dbUtil.getCon(); // 獲取連接
        String sql = "select * from t_book";
        PreparedStatement pstmt = con.prepareStatement(sql);
        ResultSet rs = pstmt.executeQuery(); // 返回結果集ResultSet
        while (rs.next()) {
            int id = rs.getInt("id"); // 獲取第一個列的值 編號id
            String bookName = rs.getString("bookName"); // 獲取第二個列的值 圖書名稱 bookName
            float price = rs.getFloat("price"); // 獲取第三列的值 圖書價格 price
            String author = rs.getString("author"); // 獲取第四列的值 圖書作者 author
            int bookTypeId = rs.getInt("bookTypeId"); // 獲取第五列的值 圖書類別id
            Book book=new Book(id, bookName, price, author, bookTypeId);
            bookList.add(book);
        }
        return bookList;
    }

 

 

 

第六章: 處理大數據對象

大數據對象處理主要有 CLOB(character large object)和 BLOB(binary large object)兩種類型的字段;在 CLOB 中可以存儲大字符數據對象,比如長篇小說;在 BLOB 中可以存放二進制大數據對象,比如圖片,電影,音樂;

    第一節:處理 CLOB 數據

    

package com.java1234.jdbc.chap06.sec01;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import com.java1234.jdbc.model.Book;
import com.java1234.jdbc.util.DbUtil;

public class Demo1 {

private static DbUtil dbUtil=new DbUtil();
    
    /**
     * 添加圖書
     * @param book
     * @return
     * @throws Exception
     */
    private static int addBook(Book book)throws Exception{
        Connection con=dbUtil.getCon(); // 獲取連接
        String sql="insert into t_book values(null,?,?,?,?,?)";
        PreparedStatement pstmt=con.prepareStatement(sql);
        pstmt.setString(1, book.getBookName());  // 給第一個坑設置值
        pstmt.setFloat(3, book.getPrice());  // 給第二個坑設置值
        pstmt.setString(2, book.getAuthor()); // 給第三個坑設置值
        pstmt.setInt(4, book.getBookTypeId());  // 給第四個坑設置值
        File context=book.getContext(); // 獲取文件
        InputStream inputStream=new FileInputStream(context);

        pstmt.setAsciiStream(5, inputStream,(int)context.length());  // 給第五個坑設置值
        int result=pstmt.executeUpdate();
        dbUtil.close(pstmt, con);
        return result;
    }
    
    public static void getBook(int id)throws Exception{
        Connection con=dbUtil.getCon();
        String sql="select * from t_book where id=?";
        PreparedStatement pstmt=con.prepareStatement(sql);
        pstmt.setInt(1, id);
        ResultSet rs=pstmt.executeQuery();
        if(rs.next()){
            String bookName=rs.getString("bookName");
            float price=rs.getFloat("price");
            String author=rs.getString("author");
            int bookTypeId=rs.getInt("bookTypeId");
            Clob c=rs.getClob("context");
            String context=c.getSubString(1, (int) c.length());
            System.out.println("圖書名稱:"+bookName);
            System.out.println("圖書價格:"+price);
            System.out.println("圖書作者:"+author);
            System.out.println("圖書類型ID:"+bookTypeId);
            System.out.println("圖書內容:"+context);
        }
        
        dbUtil.close(pstmt, con);
    }
    
    public static void main(String[] args)throws Exception {
//        String str="C:\\152.txt";  
//        String location=str.replace("\\\\", "/");  
//        File context=new File(location);
//        System.out.println(location);
//        Book book=new Book("helloWorld", 100, "小鋒", 1,context);
//        int result=addBook(book);
//        if(result==1){
//            System.out.println("添加成功!");
//        }else{
//            System.out.println("添加失敗!");
//        }
        getBook(6);
    }
}

 

 

       第二節:處理 BLOG 數據

    

package com.java1234.jdbc.chap06.sec02;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.sql.Blob;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import com.java1234.jdbc.model.Book;
import com.java1234.jdbc.util.DbUtil;

public class Demo1 {

private static DbUtil dbUtil=new DbUtil();
    
    /**
     * 添加圖書
     * @param book
     * @return
     * @throws Exception
     */
    private static int addBook(Book book)throws Exception{
        Connection con=dbUtil.getCon(); // 獲取連接
        String sql="insert into t_book values(null,?,?,?,?,?,?)";
        PreparedStatement pstmt=con.prepareStatement(sql);
        pstmt.setString(1, book.getBookName());  // 給第一個坑設置值
        pstmt.setFloat(3, book.getPrice());  // 給第二個坑設置值
        pstmt.setString(2, book.getAuthor()); // 給第三個坑設置值
        pstmt.setInt(4, book.getBookTypeId());  // 給第四個坑設置值
        File context=book.getContext(); // 獲取文件
        InputStream inputStream=new FileInputStream(context);
        pstmt.setAsciiStream(5, inputStream,(int)context.length());  // 給第五個坑設置值
        
        File pic=book.getPic(); // 獲取圖片文件
        InputStream inputStream2=new FileInputStream(pic);
        pstmt.setBinaryStream(6, inputStream2, (int)pic.length()); // 給第六個坑設置值
        int result=pstmt.executeUpdate();
        dbUtil.close(pstmt, con);
        return result;
    }
    
    public static void getBook(int id)throws Exception{
        Connection con=dbUtil.getCon();
        String sql="select * from t_book where id=?";
        PreparedStatement pstmt=con.prepareStatement(sql);
        pstmt.setInt(1, id);
        ResultSet rs=pstmt.executeQuery();
        if(rs.next()){
            String bookName=rs.getString("bookName");
            float price=rs.getFloat("price");
            String author=rs.getString("author");
            int bookTypeId=rs.getInt("bookTypeId");
            Clob c=rs.getClob("context");
            String context=c.getSubString(1, (int)c.length());
            Blob b=rs.getBlob("pic");
            FileOutputStream out=new FileOutputStream(new File("d:/pic2.jpg"));
            out.write(b.getBytes(1, (int)b.length()));
            out.close();
            System.out.println("圖書名稱:"+bookName);
            System.out.println("圖書價格:"+price);
            System.out.println("圖書作者:"+author);
            System.out.println("圖書類型ID:"+bookTypeId);
            System.out.println("圖書內容:"+context);
        }
        dbUtil.close(pstmt, con);
    }
    
    public static void main(String[] args)throws Exception {
//        String str="C:\\152.txt";  
//        String location=str.replace("\\\\", "/");  
//        File context=new File(location);
//        String str1="C:\\123.jpg";
//        String str2=str1.replace("\\\\", "/");  
//        File pic=new File(str2);
//        Book book=new Book("helloWorld", 100, "小鋒", 1,context,pic);
//        int result=addBook(book);
//        if(result==1){
//            System.out.println("添加成功!");
//        }else{
//            System.out.println("添加失敗!");
//        }
        getBook(11);
    }
}

    注意:1.利用下面這種方式對文件進行讀取,防止目錄出現問題,一般出現問題,除了是文件名錯誤外,還有就是復制會帶來額外的東西,我們需要手打。

String str="C:\\152.txt";  
String location=str.replace("\\\\", "/");  
File context=new File(location);

       2.寫入數據時,注意第三行的第三個值要強轉成int類型,而且對於CLOG數據,使用setAsciiStream,對於BLOG 數據,要使用setBinaryStream進行寫入

File context=book.getContext(); // 獲取文件
InputStream inputStream=new FileInputStream(context);
pstmt.setAsciiStream(5, inputStream,(int)context.length()); 

      

File context=book.getContext(); // 獲取文件
InputStream inputStream=new FileInputStream(context);
pstmt.setAsciiStream(5, inputStream,(int)context.length());  // 給第五個坑設置值
		
File pic=book.getPic(); // 獲取圖片文件
InputStream inputStream2=new FileInputStream(pic);
pstmt.setBinaryStream(6, inputStream2, (int)pic.length()); // 給第六個坑設置值

      3.讀取數據時,對於CLOG數據,用下面這種方法。

Clob c=rs.getClob("context");
String context=c.getSubString(1, (int) c.length());

            對於BLOG 數據,用接下來這種方法,也就是直接寫成多媒體格式。    

Blob b=rs.getBlob("pic");
FileOutputStream out=new FileOutputStream(new File("d:/pic2.jpg"));
out.write(b.getBytes(1, (int)b.length()));
out.close();

  

 

 

第七章: 使用 CallableStatement 接口調用存儲過程

    CallableStatement 主要是調用數據庫中的存儲過程,CallableStatement 也是 PreparedStatement 接口的子接口。在使用 CallableStatement 時可以接收存儲過程的返回值

    void registerOutParameter(int parameterIndex, int sqlType) 按順序位置 parameterIndex 將 OUT 參數注冊為 JDBC 類型 sqlType。

    

private static String getBookNameById(int id)throws Exception{
		Connection con=dbUtil.getCon();  // 獲取數據庫連接
		String sql="{CALL pro_getBookNameById1(?,?)}";
		CallableStatement cstmt=con.prepareCall(sql);
		cstmt.setInt(1, id); // 設置第一個參數
		cstmt.registerOutParameter(2, Types.VARCHAR);  // 設置返回類型
		cstmt.execute();
		String bookName=cstmt.getString(1);  // 獲取返回值//這里不僅可以利用index,利用關鍵字也可以。
		dbUtil.close(cstmt, con);
		return bookName;
	}
	

  注意:sql語句外的大括號。

 

 

 

第八章: 使用元數據分析數據庫

    第一節:使用 DatabaseMetaData 獲取數據庫基本信息

      DatabaseMetaData 可以得到數據庫的一些基本信息,包括數據庫的名稱、版本,以及得到表的信息。

      String getDatabaseProductName() 獲取此數據庫產品的名稱。 int getDriverMajorVersion() 獲取此 JDBC 驅動程序的主版本號。

      int getDriverMinorVersion() 獲取此 JDBC 驅動程序的次版本號。

public static void main(String[] args)throws Exception {
		DbUtil dbUtil=new DbUtil();
		Connection con=dbUtil.getCon();
		DatabaseMetaData dmd=con.getMetaData(); // 獲取元數據
		System.out.println("數據庫名稱:"+dmd.getDatabaseProductName());
		System.out.println("數據庫版本:"+dmd.getDriverMajorVersion()+"."+dmd.getDriverMinorVersion());
		
	}

  

    第二節:使用 ResultSetMetaData 獲取 ResultSet

      ResultSetMetaData 可獲取關於 ResultSet 對象中列的基本信息;

      int getColumnCount() 返回此 ResultSet 對象中的列數。

      String getColumnName(int column) 獲取指定列的名稱。

      int getColumnTypeName(int column) 獲取指定列的 SQL 類型名稱。

	public static void main(String[] args) throws Exception{
		DbUtil dbUtil=new DbUtil();
		Connection con=dbUtil.getCon();
		String sql="select * from t_book";
		PreparedStatement pstmt=con.prepareStatement(sql);
		ResultSetMetaData rsmd=pstmt.getMetaData();
		int num=rsmd.getColumnCount(); // 獲取元數據列的總數
		for(int i=1;i<=num;i++){
			System.out.println(rsmd.getColumnName(i)+","+rsmd.getColumnTypeName(i));
		}
	}

  

 

 

 

第九章: JDBC 事務處理

    第一節:事務的概念

      事務處理在數據庫開發中有着非常重要的作用,所謂事務就是所有的操作要么一起成功,要么一起失敗,事務 本身具有原子性(Atomicity)、一致性(Consistency)、隔離性或獨立性(Isolation)、持久性(Durability)4 個特 性,這 4 個特性也被稱為 ACID 特征。

原子性:原子性是事務最小的單元,是不可再分隔的單元,相當於一個個小的數據庫操作,這些操作必須同時 成功,如果一個失敗了,則一切的操作將全部失敗。

一致性:指的是在數據庫操作的前后是完全一致的,保證數據的有效性,如果事務正常操作則系統會維持有效 性,如果事務出現了錯誤,則回到最原始狀態,也要維持其有效性,這樣保證事務開始時和結束時系統處於一 致狀態。

隔離性:多個事務可以同時進行且彼此之間無法訪問,只有當事務完成最終操作時,才可以看到結果;

持久性:事務完成之后,它對於系統的影響是永久性的。該修改即使出現致命的系統故障也將一直保持。

 

package com.java1234.jdbc.chap09.sec04;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Savepoint;

import com.java1234.jdbc.util.DbUtil;

public class Demo1 {
    
    private static DbUtil dbUtil=new DbUtil();

    /**
     * 轉出
     * @param con
     * @param accountName
     * @param account
     * @throws Exception
     */
    private static void outCount(Connection con,String accountName,int account)throws Exception{
        String sql="update t_account set accountBalance=accountBalance-? where accountName=?";
        PreparedStatement pstmt=con.prepareStatement(sql);
        pstmt.setInt(1, account);
        pstmt.setString(2, accountName);
        pstmt.executeUpdate();
    }
    
    /**
     * 轉入
     * @param con
     * @param accountName
     * @param account
     * @throws Exception
     */
    private static void inCount(Connection con,String accountName,int account)throws Exception{
        String sql="update t_account set account=accountBalance+? where accountName=?";
        PreparedStatement pstmt=con.prepareStatement(sql);
        pstmt.setInt(1, account);
        pstmt.setString(2, accountName);
        pstmt.executeUpdate();
    }
    
    
    public static void main(String[] args) {
        Connection con=null;
        Savepoint sp=null;
        try {
            con=dbUtil.getCon(); 
            con.setAutoCommit(false); // 取消自動提交
            System.out.println("張三開始向李四轉賬!");
            int account=500;
            outCount(con, "張三", account);
            //sp=con.setSavepoint(); // 設置一個保存點
            inCount(con, "李四", account);
            System.out.println("轉賬成功!");
        } catch (Exception e) {
            try {
                con.rollback(); // 回滾到sp保存點
            } catch (SQLException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            try {
                con.commit();  // 提交事務
                con.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

 

    第二節:MySQL 對事務的支持

      


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM