初識JDBC

JDBC


  • idea第一次使用過程當中會出現使用時區錯誤,設置時區後解決問題

  • 概念:JAVA DataBase Connectivity -java 數據庫鏈接,java語言操做數據庫java

  • JDBC本質:sun公司定義的一套JAVA鏈接各類關係型數據庫的規則(接口),並無進行實現,而是由每一個數據庫廠商實現了這個接口,而且提供數據庫驅動jar包。咱們可使用這套接口(JDBC)編程,真正執行代碼的是驅動jar包中的實現類。mysql

  • JDBC 快速入門spring

    package cn.learn.jdbc;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    import java.sql.Statement;
    
    public class JdbcDemo01 {
        public static void main(String[] args) {
            //1.導入廠商jar包,複製包到新建文件夾lib,再add as Library
            /*
                mysql廠商的jar包在5版本后里的META-INF中已經註冊驅動,可 以不寫
                Class.forName("com.mysql.jdbc.Driver");
            */
            Statement statement = null;
            Connection conn = null;
            try {
                //2.註冊驅動,加載進內存
                Class.forName("com.mysql.jdbc.Driver");
                //3.獲取數據庫鏈接對象
                conn = DriverManager.getConnection("jdbc:mysql://   localhost:3306/db1","root","123");
                //4.定義SQL語句,語句不加分號
                String sql = " insert into student(id,name) values  (8,'小白白') ";
                //5.獲取執行sql的對象,Statement
                statement = conn.createStatement();
                //6.執行SQL
                int count = statement.executeUpdate(sql);
                //7.處理結果,
                if(count == 1){
                    System.out.println("處理成功");
                }
            } catch (SQLException | ClassNotFoundException e) {
                e.printStackTrace();
            }finally {
                //8.釋放資源,若是在第5步以前出現異常,執行進來statement 爲空,則會出現空指針異常
                if (statement != null) {
                    try {
                        statement.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
                if(conn != null){
                    try {
                        conn.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
    
                }
            }
        }
    }

詳解JDBC中的對象

Connection -數據庫鏈接對象


  • java.sql 接口 Connectionsql

  • 功能
    1. 獲取執行sql的對象,其中方法:
      • Statement createStatement()
        建立一個 Statement 對象來將 SQL 語句發送到數據庫
      • PreparedStatement prepareStatement(String sql)
        建立一個 PreparedStatement 對象來將參數化的 SQL 語句發送到數據庫。
    2. 管理事務:
      • 開啓事務方法:
        void setAutoCommit(boolean autoCommit)
        將此鏈接的自動提交模式設置爲給定狀態,參數false即爲手動提交,開啓事務數據庫

      • 提交事務:void commit()編程

      • 回滾事務:void rollback()安全

    3. 最後資源須要關閉,以避免形成內存泄漏。

DriverManager - 驅動管理對象


  • java.sql 類 DriverManagerapp

  • 功能:
    1. 註冊驅動
      • 方法:框架

        static void registerDriver(Driver driver) 向 DriverManager 註冊給定驅動程序dom

        而Class.forName("com.mysql.jdbc.Driver");
        經過查看源碼,在com.mysql.jdbc.Driver類中存在靜態代碼塊

        public class Driver extends NonRegisteringDriver implements java.sql.Driver {
        //
        // Register ourselves with the DriverManager
        //
        static {
            try {
                java.sql.DriverManager.registerDriver(new Driver());
            } catch (SQLException E) {
                throw new RuntimeException("Can't register driver!");
            }
        }
    2. 獲取數據庫鏈接:
      • 靜態方法:

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

      • 參數:
        1. URL:指定鏈接的路徑
          • 語法:
            url:jdbc:mysql://ip地址(域名):端口號/數據庫名稱(本機默認端口是3306可簡寫爲///數據庫名稱)
            user:用戶名
            password: 密碼

Statement -執行sql對象


  • public interface Statement extends Wrapper
  • 用於執行靜態 SQL 語句並返回它所生成結果的對象。

  • 執行sql
    1. int executeUpdate(String sql)
      執行給定 SQL 語句,該語句可能爲 INSERT、UPDATE 或 DELETE 語句,或者不返回任何內容的 SQL 語句(如 SQL DDL 語句)。
      注意:返回值int是影響的行數,可由此來判斷是否執行成功
    2. ResultSet executeQuery(String sql)
      執行給定的DQL語句,返回ResultSet結果集對象。
    3. 資源須要關閉
    package cn.learn.jdbc;
    
    import java.sql.*;
    
    public class JdbcDemo01 {
        public static void main(String[] args) {
            //1.導入廠商jar包,複製包到新建文件夾lib,再add as Library
            /*
                mysql廠商的jar包在5版本后里的META-INF中已經註冊驅動,可 以不寫
                Class.forName("com.mysql.jdbc.Driver");
            */
            Statement statement = null;
            Connection conn = null;
            ResultSet count = null;
            try {
                //2.註冊驅動,加載進內存
                Class.forName("com.mysql.jdbc.Driver");
                //3.獲取數據庫鏈接對象
                conn = DriverManager.getConnection("jdbc:mysql:///  db1","root","123");
                //4.定義SQL語句,語句不加分號
                String sql = " select * from student ";
                //5.獲取執行sql的對象,Statement
                statement = conn.createStatement();
                //6.執行SQL
                count = statement.executeQuery(sql);
                //7.處理結果,打印在控制檯
                //7.1 先讓光標移動一行,進入數據區域
                while(count.next()){
                    System.out.print(count.getInt(1)+"-----");
                    System.out.print(count.getString(2)+"-----");
                    System.out.print(count.getInt(3)+"-----");
                    System.out.print(count.getDouble(4)+"-----");
                    System.out.println(count.getDate(5));
                }
    
    
            } catch (SQLException | ClassNotFoundException e) {
                e.printStackTrace();
            }finally {
                //8.釋放資源,若是在第5步以前出現異常,執行進來statement 爲空,則會出現空指針異常
                if (statement != null) {
                    try {
                        statement.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
                if(conn != null){
                    try {
                        conn.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
    
                }
                if(count != null){
                    try {
                        count.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
    
                }
            }
    
        }
    }
    
    /*
    
    1-----小白-----15-----85.6-----1996-02-03
    2-----小王-----13-----88.2-----null
    3-----as-----88-----89.2-----null
    8-----小白白-----0-----0.0-----null
    9-----小白-----15-----75.6-----1996-02-03
     */

抽取JDBC工具類 : JDBCUtils


  • 目的:簡化書寫
  • 分析:
    1. 註冊驅動也抽取
    2. 抽取一個方法獲取鏈接對象
      • 需求:不想傳遞參數(麻煩),還得保證工具類的通用性。
      • 解決:配置文件
        jdbc.properties
        url=
        user=
        password=
    3. 抽取一個方法釋放資源
  • 代碼實現:
public class JDBCUtils {
    private static String url;
    private static String user;
    private static String password;
    private static String driver;
    /**
     * 文件的讀取,只須要讀取一次便可拿到這些值。使用靜態代碼塊
     */
    static{
        //讀取資源文件,獲取值。
        try {
            //1. 建立Properties集合類。
            Properties pro = new Properties();

            //獲取src路徑下的文件的方式--->ClassLoader 類加載器
            ClassLoader classLoader = JDBCUtils.class.getClassLoader();
            URL res  = classLoader.getResource("jdbc.properties");
            String path = res.getPath();
            System.out.println(path);
            pro.load(new FileReader(path));

            //3. 獲取數據,賦值
            url = pro.getProperty("url");
            user = pro.getProperty("user");
            password = pro.getProperty("password");
            driver = pro.getProperty("driver");
            //4. 註冊驅動
            Class.forName(driver);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }


    /**
     * 獲取鏈接
     * @return 鏈接對象
     */
    public static Connection getConnection() throws SQLException {

        return DriverManager.getConnection(url, user, password);
    }

    /**
     * 釋放資源
     * @param stmt
     * @param conn
     */
    public static void close(Statement stmt,Connection conn){
        if( stmt != null){
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

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


    /**
     * 釋放資源
     * @param stmt
     * @param conn
     */
    public static void close(ResultSet rs,Statement stmt, Connection conn){
        if( rs != null){
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if( stmt != null){
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

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

}
  • 練習:
    • 需求:
      1. 經過鍵盤錄入用戶名和密碼
      2. 判斷用戶是否登陸成功
        • select * from user where username = "" and password = "";
        • 若是這個sql有查詢結果,則成功,反之,則失敗
    • 步驟:
      1. 建立數據庫用戶表 user
      CREATE TABLE USER(
              id INT PRIMARY KEY AUTO_INCREMENT,
              username VARCHAR(32),
              PASSWORD VARCHAR(32)
      
          );
          INSERT INTO USER VALUES(NULL,'zhangsan','123');
          INSERT INTO USER VALUES(NULL,'lisi','234');
      1. 代碼實現:
      public class JDBCDemo9 {
              public static void main(String[] args) {
                  //1.鍵盤錄入,接受用戶名和密碼
                  Scanner sc = new Scanner(System.in);
                  System.out.println("請輸入用戶名:");
                  String username = sc.nextLine();
                  System.out.println("請輸入密碼:");
                  String password = sc.nextLine();
                  //2.調用方法
                  boolean flag = new JDBCDemo9().login(username, password);
                  //3.判斷結果,輸出不一樣語句
                  if(flag){
                      //登陸成功
                      System.out.println("登陸成功!");
                  }else{
                      System.out.println("用戶名或密碼錯誤!");
                  }
      
      
              }
      
      
      
              /**
               * 登陸方法
               */
              public boolean login(String username ,String password){
                  if(username == null || password == null){
                      return false;
                  }
                  //鏈接數據庫判斷是否登陸成功
                  Connection conn = null;
                  prepareStatement pstmt =  null;
                  ResultSet rs = null;
                  //1.獲取鏈接
                  try {
                      conn =  JDBCUtils.getConnection();
                      //2.定義sql
                      String sql = "select * from user where username = ? and password = ?";
                      //3.獲取執行sql的對象
                      pstmt = conn.prepareStatement(sql);
                      //設置通配符傳給須要的對象
                      pstmt.setString(1,username);
                      pstmt.setString(2,password);
                      //4.執行查詢,不須要傳參
                      rs = pstmt.executeQuery();
                      //5.判斷
                     /* if(rs.next()){//若是有下一行,則返回true
                          return true;
                      }else{
                          return false;
                      }*/
                     return rs.next();//若是有下一行,則返回true
      
                  } catch (SQLException e) {
                      e.printStackTrace();
                  }finally {
                      JDBCUtils.close(rs,pstmt,conn);
                  }
      
      
                  return false;
              }
          }

ResulSet -結果集對象


  • public interface ResultSet extends Wrapper
  • ResultSet:用來封裝查詢的結果集(表),內有如下方法獲取查詢結果的數據
    1. next(): 遊標向下移動一行
    2. getXXX(參數):獲取數據
      • XXX:爲數據類型,如int,String...
      • 參數:
        1. 接收是Int型:表明列編號,從1開始
        2. 接收是String型:表明列名稱
    3. 結果集是一個資源,須要關閉

PreparedStatemnet -動態傳參


  • PreparedStatement:執行sql的對象
    1. SQL注入問題:在拼接sql時,有一些sql的特殊關鍵字參與字符串的拼接。會形成安全性問題,以下:
      1. 輸入用戶隨便,輸入密碼:a' or 'a' = 'a
      2. sql:select * from user where username = 'fhdsjkf' and password = 'a' or 'a' = 'a'
    2. 解決sql注入問題:使用PreparedStatement對象來解決
    3. 預編譯的SQL:參數使用?做爲佔位符
    4. 步驟:
      1. 導入驅動jar包 mysql-connector-java-5.1.37-bin.jar
      2. 註冊驅動
      3. 獲取數據庫鏈接對象 Connection
      4. 定義sql
        • 注意:sql的參數使用?做爲佔位符。 如:select * from user where username = ? and password = ?;
      5. 獲取執行sql語句的對象 PreparedStatement Connection.prepareStatement(String sql)
      6. 給?賦值:
        • 方法: setXxx(參數1,參數2)
          • 參數1:?的位置,編號 從1 開始
          • 參數2:?的值
      7. 執行sql,接受返回結果,不須要傳遞sql語句
      8. 處理結果
      9. 釋放資源
    5. 後期都會使用PreparedStatement來完成增刪改查的全部操做
      1. 能夠防止SQL注入
      2. 效率更高

JDBC控制事務:


  1. 事務:一個包含多個步驟的業務操做。若是這個業務操做被事務管理則這多個步驟要麼同時成功,要麼同時失敗。
  2. 操做:
    1. 開啓事務
    2. 提交事務
    3. 回滾事務
  3. 使用Connection對象來管理事務
    • 開啓事務:setAutoCommit(boolean autoCommit) :調用該方法設置參數爲false,即開啓事務
      • 在執行sql以前開啓事務
    • 提交事務:commit()
      • 當全部sql都執行完提交事務
    • 回滾事務:rollback()
      • 在catch中回滾事務
  4. 代碼:
public class JDBCDemo10 {
        public static void main(String[] args) {
            Connection conn = null;
            PreparedStatement pstmt1 = null;
            PreparedStatement pstmt2 = null;
    
            try {
                //1.獲取鏈接
                conn = JDBCUtils.getConnection();
                //開啓事務(若代碼中有錯則會進行回滾)
                conn.setAutoCommit(false);
    
                //2.定義sql
                //2.1 張三 - 500
                String sql1 = "update account set balance = balance - ? where id = ?";
                //2.2 李四 + 500
                String sql2 = "update account set balance = balance + ? where id = ?";
                //3.獲取執行sql對象
                pstmt1 = conn.prepareStatement(sql1);
                pstmt2 = conn.prepareStatement(sql2);
                //4. 設置參數
                pstmt1.setDouble(1,500);
                pstmt1.setInt(2,1);
    
                pstmt2.setDouble(1,500);
                pstmt2.setInt(2,2);
                //5.執行sql
                pstmt1.executeUpdate();
                pstmt2.executeUpdate();
                //提交事務
                conn.commit();
            } catch (Exception e) {
                //事務回滾
                try {
                    if(conn != null) {
                        conn.rollback();
                    }
                } catch (SQLException e1) {
                    e1.printStackTrace();
                }
                e.printStackTrace();
            }finally {
                JDBCUtils.close(pstmt1,conn);
                JDBCUtils.close(pstmt2,null);
            }
    
    
        }
    
    }

JDBC實驗

  • Java實驗四 JDBC
    使用SQL Server數據庫或者MySQL數據庫各自的客戶端工具,完成以下任務:
    1. 建立數據庫students;
    2. 在數據students中建立表scores,包括以下字段:學號、姓名、性別、得分,字段類型自行定義。學號爲主鍵。
  • 接着使用JDBC編寫Java程序,完成以下任務:
    1. 在表格scores插入5條記錄,表明5個學生,三位男生二位女生,各字段內容自定(「得分」字段填入自定分數);
    2. 顯示5位學生的全部信息;
    3. 將三位男生的得分減去5分,將兩位女生的成績加上3分;
    4. 從鍵盤輸入不一樣學號,根據學號顯示相應學生的全部信息。

sql語句

CREATE DATABASE students;

CREATE TABLE scores(
id INT PRIMARY KEY,
NAME VARCHAR(32) NOT NULL,
sex VARCHAR(1),
score DOUBLE(5,2)

);

INSERT INTO scores VALUES(201826501,'老王','男',88.2),(201826502,'老胡','男',99.3),(201826503,'老薛','男',100),(201826504,'老巴','女',89.3),(201826505,'老謝','女',95.6);
UPDATE scores SET score = score-5 WHERE sex='男';
SELECT * FROM scores WHERE id = 201826501;

main方法


package cn.work.demo.Jdbc;

import java.sql.*;

public class JdbcDemo01 {
    public static void main(String[] args)  {
        //導入廠商jar包,複製包到新建文件夾lib,再add as Library
        /*
            mysql廠商的jar包在5版本后里的META-INF中已經註冊驅動,能夠不寫
            Class.forName("com.mysql.jdbc.Driver");
        */
        Connection conn = null;

        //獲取數據庫鏈接對象
        try {
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/students", "root", "123");
        } catch (SQLException e) {
            e.printStackTrace();
        }

        //查詢所有
        Query query = new Query(conn);

        //修改分數
        UpdateScores update = new UpdateScores(conn);

        //查詢單一人員信息
        QueryOne onePerson = new QueryOne(conn);

        //主菜單
        Menu menu = new Menu(query,update,onePerson);

        //關閉鏈接
        try {
            conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }

    }
}

主界面


package cn.work.demo.Jdbc;

import java.util.Scanner;

public class Menu {
   private boolean flag = true;
   private Scanner scanner =null;
    public Menu(Query query, UpdateScores update, QueryOne onePerson) {
        System.out.println("\n\n\t\t\tJDBC實驗\n\n");
        System.out.println("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *" );
        System.out.println("\t\t\t\t1.查詢所有人員信息\n");
        System.out.println("\t\t\t\t2.修改分數男生-5女生+3\n");
        System.out.println("\t\t\t\t3.查詢某人信息\n");
        System.out.println("\t\t\t\t4.退出\n");
        System.out.println("* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *" );
        scanner = new Scanner(System.in);
        //菜單
        do{
            System.out.println("請輸入要選擇的數字:");
           int command = scanner.nextInt();
           switch (command){
               case 1:
                   query.execute();
                   break;
               case 2:
                   update.execute();
                   break;
               case 3:
                   onePerson.execute();
                   break;
               case 4:
                   flag=false;
                   break;
               default:
                   System.out.println("輸入錯誤請從新輸入");
                   break;
           }

        }while (flag);
    }
}

查詢所有信息並打印在控制檯


package cn.work.demo.Jdbc;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class Query {

    private Statement statement=null;
    private Connection conn;
    private ResultSet count=null;

    public Query( Connection conn) {
        this.conn = conn;
    }

    public void execute() {
        try {
            //定義查詢SQL語句,語句不加分號
            String sql = " select * from scores ";
            //獲取執行sql的對象,Connection裏的方法返回Statement
            statement = conn.createStatement();
            //執行SQL,返回ResultSet
            count = statement.executeQuery(sql);
            //處理結果,打印在控制檯
            //先讓光標移動一行,進入數據區域進行打印輸出
            while (count.next()) {
                System.out.print(count.getInt(1) + "-----");
                System.out.print(count.getString(2) + "-----");
                System.out.print(count.getString(3) + "-----");
                System.out.println(count.getDouble(4));
            }


        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            //釋放資源
            if (statement != null) {
                try {
                    statement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (count != null) {
                try {
                    count.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }

            }
        }
    }
}

修改表中數據


package cn.work.demo.Jdbc;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

public class UpdateScores {
    private Statement statement=null;
    private Connection conn;

    public UpdateScores(Connection conn) {
        this.conn = conn;
    }
    public void execute() {
        try {
            //定義查詢SQL語句
            String sqlMen = "UPDATE scores SET score = score-5 WHERE sex='男'";
            String sqlWonmen = "UPDATE scores SET score = score+3 WHERE sex='女'";
            //建立一個 Statement 對象來將 SQL 語句發送到數據庫
            statement = conn.createStatement();
            //執行SQL
            statement.executeUpdate(sqlMen);
            statement.executeUpdate(sqlWonmen);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            //釋放資源
            if (statement != null) {
                try {
                    statement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

prepareStatement動態查詢


package cn.work.demo.Jdbc;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Scanner;

public class QueryOne {
    //PreparedStatement動態參數
    private PreparedStatement pstatement=null;
    private Connection conn;
    private ResultSet count=null;
    private Scanner scanner;

    public QueryOne(Connection conn) {
        scanner = new Scanner(System.in);
        this.conn = conn;
    }
    public void execute() {
        try {
            System.out.println("請輸入要查詢學號:");
            int id = Integer.parseInt(scanner.next());
            String sql = "SELECT * FROM scores WHERE id = ?";
            //獲取SQL執行的對象
            pstatement = conn.prepareStatement(sql);
            //傳遞動態參數
            pstatement.setInt(1,id);
            //執行SQL
            count = pstatement.executeQuery();
            if (count.next()){
                System.out.print(count.getInt(1) + "-----");
                System.out.print(count.getString(2) + "-----");
                System.out.print(count.getString(3) + "-----");
                System.out.println(count.getDouble(4));
            } else
                System.out.println("學號未找到!!!");
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            //釋放資源
            if (pstatement != null) {
                try {
                    pstatement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

數據庫鏈接池


  1. 概念:其實就是一個容器(集合),存放數據庫鏈接的容器。
    當系統初始化好後,容器被建立,容器中會申請一些鏈接對象,當用戶來訪問數據庫時,從容器中獲取鏈接對象,用戶訪問完以後,會將鏈接對象歸還給容器。
  2. 好處:
    1. 節約資源
    2. 用戶訪問高效
  3. 實現:
    1. 標準接口:DataSource javax.sql包下的
      1. 方法:
        • 獲取鏈接:getConnection()
        • 歸還鏈接:Connection.close()。若是鏈接對象Connection是從鏈接池中獲取的,那麼調用Connection.close()方法,則不會再關閉鏈接了。而是歸還鏈接
    2. 通常咱們不去實現它,有數據庫廠商來實現
      1. C3P0:數據庫鏈接池技術
      2. Druid:數據庫鏈接池實現技術,由阿里巴巴提供的
  4. C3P0:數據庫鏈接池技術
    • 步驟:
      1. 導入jar包 (兩個) c3p0-0.9.5.2.jar mchange-commons-java-0.2.12.jar ,
        • 不要忘記導入數據庫驅動jar包
      2. 定義配置文件:
        • 名稱: c3p0.properties 或者 c3p0-config.xml
        • 路徑:直接將文件放在src目錄下便可。
      3. 建立核心對象 數據庫鏈接池對象 ComboPooledDataSource
      4. 獲取鏈接: getConnection
    • 代碼:
    //1.建立數據庫鏈接池對象,不傳參數則使用默認配置
        DataSource ds  = new ComboPooledDataSource();
        //2. 獲取鏈接對象
        Connection conn = ds.getConnection();
  5. Druid:數據庫鏈接池實現技術,由阿里巴巴提供的
    1. 步驟:
      1. 導入jar包 druid-1.0.9.jar
      2. 定義配置文件:
        • 是properties形式的
        • 能夠叫任意名稱,能夠放在任意目錄下
      3. 加載配置文件。Properties
      4. 獲取數據庫鏈接池對象:經過工廠來來獲取 DruidDataSourceFactory
      5. 獲取鏈接:getConnection
    • 代碼:
    //3.加載配置文件
        Properties pro = new Properties();
        //當前類的資源路徑,找到配置文件,返回字節輸入流
        InputStream is = DruidDemo.class.getClassLoader().getResourceAsStream("druid.properties");
        //加載
        pro.load(is);
        //4.獲取鏈接池對象
        DataSource ds = DruidDataSourceFactory.createDataSource(pro);
        //5.獲取鏈接
        Connection conn = ds.getConnection();
    1. 定義工具類
      1. 定義一個類 JDBCUtils
      2. 提供靜態代碼塊加載配置文件,初始化鏈接池對象
      3. 提供方法
        1. 獲取鏈接方法:經過數據庫鏈接池獲取鏈接
        2. 釋放資源
        3. 獲取鏈接池的方法
    • 代碼:

    ```java

    public class JDBCUtils {
         //1.定義成員變量 DataSource
         private static DataSource ds ;
    
     //靜態代碼塊初始化
         static{
             try {
                 //1.加載配置文件
                 Properties pro = new Properties();
                 pro.load(JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties"));
                 //2.獲取DataSource
                 ds = DruidDataSourceFactory.createDataSource(pro);
             } catch (IOException e) {
                 e.printStackTrace();
             } catch (Exception e) {
                 e.printStackTrace();
             }
         }
    
         /**
          * 獲取鏈接
          */
         public static Connection getConnection() throws SQLException {
             return ds.getConnection();
         }
    
         /**
          * 釋放資源
          */
         public static void close(Statement stmt,Connection conn){
            /* if(stmt != null){
                 try {
                     stmt.close();
                 } catch (SQLException e) {
                     e.printStackTrace();
                 }
             }
    
             if(conn != null){
                 try {
                     conn.close();//歸還鏈接
                 } catch (SQLException e) {
                     e.printStackTrace();
                 }
             }*/
    
         //調用下面方法,簡化書寫
            close(null,stmt,conn);
         }
    
    
         public static void close(ResultSet rs , Statement stmt, Connection conn){
    
    
             if(rs != null){
                 try {
                     rs.close();
                 } catch (SQLException e) {
                     e.printStackTrace();
                 }
             }
    
    
             if(stmt != null){
                 try {
                     stmt.close();
                 } catch (SQLException e) {
                     e.printStackTrace();
                 }
             }
    
             if(conn != null){
                 try {
                     conn.close();//歸還鏈接
                 } catch (SQLException e) {
                     e.printStackTrace();
                 }
             }
         }
    
         /**
          * 獲取鏈接池方法
          */
    
         public static DataSource getDataSource(){
             return  ds;
         }
    
     }
    
     ```

Spring JDBC


  • Spring框架對JDBC的簡單封裝。提供了一個JDBCTemplate對象簡化JDBC的開發

  • 步驟:
    1. 導入jar包
    2. 建立JdbcTemplate對象。依賴於數據源DataSource
      • JdbcTemplate template = new JdbcTemplate(ds);
    3. 調用JdbcTemplate的方法來完成CRUD的操做
      • update():執行DML語句。增、刪、改語句
      • queryForMap():查詢結果將結果集封裝爲map集合,將列名做爲key,將值做爲value 將這條記錄封裝爲一個map集合
        • 注意:這個方法查詢的結果集長度只能是1
      • queryForList():查詢結果將結果集封裝爲list集合
        • 注意:將每一條記錄封裝爲一個Map集合,再將Map集合裝載到List集合中
      • query():查詢結果,將結果封裝爲JavaBean對象
        • query的參數:RowMapper
          • 通常咱們使用BeanPropertyRowMapper實現類。能夠完成數據到JavaBean的自動封裝
          • new BeanPropertyRowMapper <類型> (類型.class)
      • queryForObject:查詢結果,將結果封裝爲對象
        • 通常用於聚合函數的查詢
    4. 練習:
      • 需求:
        1. 修改1號數據的 salary 爲 10000
        2. 添加一條記錄
        3. 刪除剛纔添加的記錄
        4. 查詢id爲1的記錄,將其封裝爲Map集合
        5. 查詢全部記錄,將其封裝爲List
        6. 查詢全部記錄,將其封裝爲Emp對象的List集合
        7. 查詢總記錄數
      • 代碼:

        import cn.itcast.domain.Emp;
        import cn.itcast.utils.JDBCUtils;
        import org.junit.Test;
        import org.springframework.jdbc.core.BeanPropertyRowMapper;
        import org.springframework.jdbc.core.JdbcTemplate;
        import org.springframework.jdbc.core.RowMapper;
        
        import java.sql.Date;
        import java.sql.ResultSet;
        import java.sql.SQLException;
        import java.util.List;
        import java.util.Map;
        
        public class JdbcTemplateDemo2 {
        
            //Junit單元測試,可讓方法獨立執行
        
        
            //1. 獲取JDBCTemplate對象
            private JdbcTemplate template = new JdbcTemplate(JDBCUtils.getDataSource());
            /**
             * 1. 修改1號數據的 salary 爲 10000
             */
            @Test
            public void test1(){
        
                //2. 定義sql
                String sql = "update emp set salary = 10000 where id = 1001";
                //3. 執行sql
                int count = template.update(sql);
                System.out.println(count);
            }
        
            /**
             * 2. 添加一條記錄
             */
            @Test
            public void test2(){
                String sql = "insert into emp(id,ename,dept_id) values(?,?,?)";
                int count = template.update(sql, 1015, "郭靖", 10);
                System.out.println(count);
        
            }
        
            /**
             * 3.刪除剛纔添加的記錄
             */
            @Test
            public void test3(){
                String sql = "delete from emp where id = ?";
                int count = template.update(sql, 1015);
                System.out.println(count);
            }
        
            /**
             * 4.查詢id爲1001的記錄,將其封裝爲Map集合
             * 注意:這個方法查詢的結果集長度只能是1
             */
            @Test
            public void test4(){
                String sql = "select * from emp where id = ? or id = ?";
                Map<String, Object> map = template.queryForMap(sql, 1001,1002);
                System.out.println(map);
                //{id=1001, ename=孫悟空, job_id=4, mgr=1004, joindate=2000-12-17, salary=10000.00, bonus=null, dept_id=20}
        
            }
        
            /**
             * 5. 查詢全部記錄,將其封裝爲List
             */
            @Test
            public void test5(){
                String sql = "select * from emp";
                List<Map<String, Object>> list = template.queryForList(sql);
        
                for (Map<String, Object> stringObjectMap : list) {
                    System.out.println(stringObjectMap);
                }
            }
        
            /**
             * 6. 查詢全部記錄,將其封裝爲Emp對象的List集合
             */
        
            @Test
            public void test6(){
                String sql = "select * from emp";
                List<Emp> list = template.query(sql, new RowMapper<Emp>() {
        
                    @Override
                    public Emp mapRow(ResultSet rs, int i) throws SQLException {
                        Emp emp = new Emp();
                        int id = rs.getInt("id");
                        String ename = rs.getString("ename");
                        int job_id = rs.getInt("job_id");
                        int mgr = rs.getInt("mgr");
                        Date joindate = rs.getDate("joindate");
                        double salary = rs.getDouble("salary");
                        double bonus = rs.getDouble("bonus");
                        int dept_id = rs.getInt("dept_id");
        
                        emp.setId(id);
                        emp.setEname(ename);
                        emp.setJob_id(job_id);
                        emp.setMgr(mgr);
                        emp.setJoindate(joindate);
                        emp.setSalary(salary);
                        emp.setBonus(bonus);
                        emp.setDept_id(dept_id);
        
                        return emp;
                    }
                });
        
        
                for (Emp emp : list) {
                    System.out.println(emp);
                }
            }
        
            /**
             * 6. 查詢全部記錄,將其封裝爲Emp對象的List集合
             */
        
            @Test
            public void test6_2(){
                String sql = "select * from emp";
                List<Emp> list = template.query(sql, new BeanPropertyRowMapper<Emp>(Emp.class));
                for (Emp emp : list) {
                    System.out.println(emp);
                }
            }
        
            /**
             * 7. 查詢總記錄數
             */
        
            @Test
            public void test7(){
                String sql = "select count(id) from emp";
                Long total = template.queryForObject(sql, Long.class);
                System.out.println(total);
            }
        
        }
相關文章
相關標籤/搜索