JAVA操作數據庫接口jdbc入門

1 JDBC入門
1.1 回顧
之前操作mysql數據庫:
1)使用mysql客戶端工具
2)使用客戶端連接mysql服務器
3)發送sql語句到mysql服務器,執行
1.2 什麼是JDBC?
使用java程序發送sql語句到數據庫服務器端執行,這叫用到了JDBC技術!!!!
jdbc是Oracle-Sun公司設計的一套專門用於java程序操作數據庫的接口。
1.3 使用jdbc發送sql條件
連接mysql數據庫:
數據庫主機
端口
數據庫用戶名
數據庫密碼
連接的數據庫
1.4 JDBC的核心API
|-Driver接口: 數據庫驅動程序的接口,所有具體數據庫廠商需要的驅動程序需要實現此接口。
Connection connect(String url, Properties info) 用於獲取數據庫連接
案例:演示三種連接數據庫的方式
java連接數據庫詳解

|-Connection接口:與具體的數據庫的連接對象。
Statement createStatement() 創建一個靜態sql語句對象
PreparedStatement prepareStatement(String sql) 創建預編譯的sql語句對象
CallableStatement prepareCall(String sql) 創建存儲過程的sql語句對象

|-Statement接口:用於執行靜態 SQL 語句
    int executeUpdate(String sql)  執行更新操作的sql語句                                                                   (create/alter/drop) DDL語句

(insert/update/delete)DML語句
ResultSet executeQuery(String sql) 執行查詢操作的sql語句
(select)(DQL查詢語句)
|- PreparedStatement接口:用於執行預編譯的 SQL 語句(是Statement的子接口)
int executeUpdate() 執行更新操作的sql語句
ResultSet executeQuery() 執行查詢操作的sql語句
|- CallableStatement接口:用於執行 SQL 存儲過程的接口(是PreparedStatement的子接口)
ResultSet executeQuery() 執行存儲過程的sql語句

|- ResultSet接口:結果集對象。 存儲所有數據庫查詢的結果,用該對象進行數據遍歷。
boolean next() : 把光標移動到下一行。如果下一行有數據,返回true,如果沒有下一行數據,返回false。
getXXX(列索引|列字段名稱): 獲取字段的數據

2 Statement對象執行SQL操作
2.1 執行DDL操作
/**
* 通過jdbc執行DDL語句
* @author APPle
*/

public class Demo1 {
    //數據庫的連接的URL
    private static String url = "jdbc:mysql://localhost:3306/day17";
    //數據庫用戶名
    private static String user = "root";
    //數據庫密碼
    private static String password = "root";

    public static void main(String[] args){
        Connection conn = null;
        Statement stmt = null;
        try {
            //1.驅動驅動程序
            Class.forName("com.mysql.jdbc.Driver");
            //2.從驅動程序管理類獲取連接
            conn = DriverManager.getConnection(url, user, password);
            //3.通過Connection對象獲取Statement對象
            stmt = conn.createStatement();
            //4.準備sql語句
            String sql = "CREATE TABLE student(id INT PRIMARY KEY AUTO_INCREMENT,NAME VARCHAR(20),gender VARCHAR(2))";
            //5.執行sql語句,返回結果
            int count = stmt.executeUpdate(sql);

            System.out.println("影響了"+count+"行");
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        } finally{
            //6.關閉資源(先關閉statement,再關閉connection)
            if(stmt!=null)
                try {
                    stmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                    throw new RuntimeException(e);
                }
            if(conn!=null)
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                    throw new RuntimeException(e);
                }
        }
    }
}

2.2 執行DML操作

/**
 * 通過jdbc執行DML語句(insert/update/delete)
 * @author APPle
 *
 */
public class Demo2 {
    //數據庫的連接的URL
    private static String url = "jdbc:mysql://localhost:3306/day17";
    //數據庫用戶名
    private static String user = "root";
    //數據庫密碼
    private static String password = "root";
    /**
     * 執行插入操作
     */
    @Test
    public void test1(){
        Connection conn = null;
        Statement stmt = null;
        try {
            //註冊驅動
            Class.forName("com.mysql.jdbc.Driver");
            //獲取連接
            conn = DriverManager.getConnection(url, user, password);
            //創建Statment對象
            stmt = conn.createStatement();
            //準備sql
            String sql = "INSERT INTO student(NAME,gender) VALUES('張三','男')";
            //執行sql,返回結果
            int count = stmt.executeUpdate(sql);
            System.out.println("影響了"+count+"行");
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        } finally{
            //關閉資源
            if(stmt!=null)
                try {
                    stmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                    throw new RuntimeException(e);
                }
            if(conn!=null)
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                    throw new RuntimeException(e);
                }
        }
    }

    /**
     * 執行更新操作
     */
    @Test
    public void test2(){
        Connection conn = null;
        Statement stmt = null;
        //聲明外部變量
        String name = "陳六";
        int id=2;
        try {
            //註冊驅動
            Class.forName("com.mysql.jdbc.Driver");
            //獲取連接
            conn = DriverManager.getConnection(url, user, password);
            //創建Statment對象
            stmt = conn.createStatement();
            //準備sql
            String sql = "UPDATE student SET NAME='"+name+"' WHERE id="+id+""; //變量和String拼接sql
            //執行sql,返回結果
            int count = stmt.executeUpdate(sql);
            System.out.println("影響了"+count+"行");
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        } finally{
            //關閉資源
            if(stmt!=null)
                try {
                    stmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                    throw new RuntimeException(e);
                }
            if(conn!=null)
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                    throw new RuntimeException(e);
                }
        }
    }

    /**
     * 執行刪除操作
     */
    @Test
    public void test3(){
        Connection conn = null;
        Statement stmt = null;
        //聲明外部變量
        int id=2;
        try {
            //註冊驅動
            Class.forName("com.mysql.jdbc.Driver");
            //獲取連接
            conn = DriverManager.getConnection(url, user, password);
            //創建Statment對象
            stmt = conn.createStatement();
            //準備sql
            String sql = "DELETE FROM student WHERE id="+id+""; //變量和String拼接sql
            //執行sql,返回結果
            int count = stmt.executeUpdate(sql);
            System.out.println("影響了"+count+"行");
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        } finally{
            //關閉資源
            if(stmt!=null)
                try {
                    stmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                    throw new RuntimeException(e);
                }
            if(conn!=null)
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                    throw new RuntimeException(e);
                }
        }
    }
}
    2.3 執行DQL查詢操作
/**
 * 使用jdbc執行DQL語句(select)
 * @author APPle
 *
 */
public class Demo3 {
    //數據庫的連接的URL
    private static String url = "jdbc:mysql://localhost:3306/day17";
    //數據庫用戶名
    private static String user = "root";
    //數據庫密碼
    private static String password = "root";

    public static void main(String[] args) {
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        try {
            //註冊驅動
            Class.forName("com.mysql.jdbc.Driver");
            //獲取連接
            conn = DriverManager.getConnection(url, user, password);
            //創建Statement對象
            stmt = conn.createStatement();
            //準備sql
            String sql = "SELECT * FROM student";

            rs = stmt.executeQuery(sql);

            //移動光標到下一行
            //rs.next();
            /**
             * 注意:
             *   1)如果光標在第一行之前,使用rs.getXX()獲取列值,報錯:Before start of result set
             *   2)如果光標在最後一行之後,使用rs.getXX()獲取列值,報錯:After end of result set
             */

            //獲取列值
            /*if(rs.next()){
                //使用列索引

                int id = rs.getInt(1);
                String name = rs.getString(2);
                String gender = rs.getString(3);

                //使用列名稱
                int id = rs.getInt("id");
                String name = rs.getString("name");
                String gender = rs.getString("gender");
                System.out.println(id+"\t"+name+"\t"+gender+"\t");
            }*/

            //迭代結果集
            while(rs.next()){
                //使用列索引
                /*
                int id = rs.getInt(1);
                String name = rs.getString(2);
                String gender = rs.getString(3);
                */
                //使用列名稱
                int id = rs.getInt("id");
                String name = rs.getString("name");
                String gender = rs.getString("gender");
                System.out.println(id+"\t"+name+"\t"+gender+"\t");
            }


        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        } finally{
            if(rs!=null)
                try {
                    rs.close();
                } catch (SQLException e1) {
                    e1.printStackTrace();
                    throw new RuntimeException(e1);
                }
            //關閉資源
            if(stmt!=null)
                try {
                    stmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                    throw new RuntimeException(e);
                }
            if(conn!=null)
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                    throw new RuntimeException(e);
                }
        }

    }
}

2.4jdbc工具類的抽取

    private static String url = "jdbc:mysql://localhost:3306/day18";
    private static String user = "root";
    private static String password = "root";
    private static String className = "com.mysql.jdbc.Driver";

    static{
        //註冊驅動,註冊一次就可以了
        //註冊驅動
        try {
            Class.forName(className);
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    //獲取連接
    public static Connection getConnection(){
        try {
            //獲取連接
            Connection conn = DriverManager.getConnection(url, user, password);
            //返回conn
            return conn;
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException();
        }
    }

    //釋放資源
    public static void close(ResultSet rs,Statement stmt,Connection conn){
        //先判空後釋放
        if (rs!=null) {
            try {
                rs.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                throw new RuntimeException();
            }
        }

        if (stmt!=null) {
            try {
                stmt.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                throw new RuntimeException();
            }
        }

        if (conn!=null) {
            try {
                conn.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                throw new RuntimeException();
            }
        }

    }

2.5 課堂練習
1.使用jdbc創建一張員工表
員工表字段:編號,姓名,性別,年齡,職位,郵箱,電話

2.使用jdbc對員工表執行以下操作:
1)插入一條數據
2)修改一條數據
3)刪除一條數據
4)查詢並打印所有員工數據

3 PreparedStatement對象執行SQL操作

/**
 * 使用PreparedStatement執行sql語句
 * @author APPle
 *
 */
public class Demo1 {

    /**
     * 插入操作
     */
    @Test
    public void test1(){
        Connection conn = null;
        PreparedStatement stmt = null;
        try{
            //獲取連接
            conn = JdbcUtil.getConnection();
            String sql = "INSERT INTO student(NAME,gender) VALUES(?,?)"; //預編譯sql:使用?號代替參數值。一個?號代表一個參數值
            //創建PreparedStatement對象,執行預編譯的sql語句
            stmt = conn.prepareStatement(sql);
            //設置參數
            /**
             * 參數一: 參數位置。從1開始
             * 參數二: 參數實際值
             * 注意: 所有參數必須要賦值
             */
            stmt.setString(1, "rose");
            stmt.setString(2, "女");
            //發送參數,執行sql語句
            int count = stmt.executeUpdate();
            System.out.println(count);
        }catch(Exception e){
            e.printStackTrace();
            throw new RuntimeException(e);
        }finally{
            //關閉資源
            JdbcUtil.close(conn, stmt, null);
        }
    }

    /**
     * 修改操作
     */
    @Test
    public void test2(){
        Connection conn = null;
        PreparedStatement stmt = null;
        //聲明變量
        String name = "jacky";
        int id = 8;
        try{
            //獲取連接
            conn = JdbcUtil.getConnection();
            String sql = "UPDATE student SET NAME=? WHERE id=?"; //預編譯sql:使用?號代替參數值。一個?號代表一個參數值
            //創建PreparedStatement對象,執行預編譯的sql語句
            stmt = conn.prepareStatement(sql);
            //設置參數
            stmt.setString(1,name);
            stmt.setInt(2, id);
            //發送參數,執行sql語句
            int count = stmt.executeUpdate();
            System.out.println(count);
        }catch(Exception e){
            e.printStackTrace();
            throw new RuntimeException(e);
        }finally{
            //關閉資源
            JdbcUtil.close(conn, stmt, null);
        }
    }

    /**
     * 刪除操作
     */
    @Test
    public void test3(){
        Connection conn = null;
        PreparedStatement stmt = null;
        //聲明變量
        int id = 8;
        try{
            //獲取連接
            conn = JdbcUtil.getConnection();
            String sql = "DELETE FROM student WHERE id=?"; //預編譯sql:使用?號代替參數值。一個?號代表一個參數值
            //創建PreparedStatement對象,執行預編譯的sql語句
            stmt = conn.prepareStatement(sql);
            //設置參數
            //任何類型都可以使用setObject進行賦值
            stmt.setObject(1, id);
            //發送參數,執行sql語句
            int count = stmt.executeUpdate();
            System.out.println(count);
        }catch(Exception e){
            e.printStackTrace();
            throw new RuntimeException(e);
        }finally{
            //關閉資源
            JdbcUtil.close(conn, stmt, null);
        }
    }

    /**
     * 查詢操作
     */
    @Test
    public void test4(){
        Connection conn = null;
        PreparedStatement stmt = null;
        //聲明變量
        String name = "張%";
        try{
            //獲取連接
            conn = JdbcUtil.getConnection();
            String sql = "SELECT * FROM student WHERE NAME LIKE ?";
            //創建PreparedStatement,預編譯sql語句
            stmt = conn.prepareStatement(sql);
            //設置參數
            stmt.setObject(1, name);
            //發送參數,執行sql,返回結果集
            ResultSet rs = stmt.executeQuery();
            //遍歷結果集
            while(rs.next()){
                int id = rs.getInt("id");
                String nameStr = rs.getString("name");
                String gender = rs.getString("gender");
                System.out.println(id+"\t"+nameStr+"\t"+gender+"\t");
            }
        }catch(Exception e){
            e.printStackTrace();
            throw new RuntimeException(e);
        }finally{
            //關閉資源
            JdbcUtil.close(conn, stmt, null);
        }
    }

}

Statement和PreparedStatement的區別==========================================
一、語法結構不同
1)Statment執行靜態sql語句,且sql可以拼接。
2)PreparedStatement可以先執行預編譯的sql語句,在預編譯sql語句中使用?進行參數佔位,後面在進行參數賦值
二、原理不同
1)Statement不能進行sql緩存
2)而PreparedStatement可以進行sql緩存,執行效率會比Statement快!!!

三、安全性不同
1)Statement存在sql注入的風險(使用登錄註冊講解sql注入)
2)而PreparedStatement可以有效防止用戶注入。

– 創建一張user表(sql注入)

CREATE TABLE USER(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(20),
PASSWORD VARCHAR(20)
);

– 給用戶表中插入數據
INSERT INTO USER(NAME,PASSWORD) VALUES(‘james’,’123456’);
INSERT INTO USER(NAME,PASSWORD) VALUES(‘mayun’,’123456’);

– 查詢表
SELECT * FROM USER WHERE NAME=’james’ AND PASSWORD=’123456’;

– 查詢全部表,基於肯定條件
SELECT * FROM USER WHERE 1=1;

– 查詢全張表給予否定條件
SELECT * FROM USER WHERE 1<>1;

– 查詢表(sql注入)

SELECT * FROM USER WHERE NAME='james' OR 1=1 ;-- ' AND PASSWORD='123456';

4 CallableStatement對象執行存儲過程
4.1 執行帶輸入參數的存儲過程

/**
     * 執行帶有輸入參數存儲過程
     */
    @Test
    public void test1(){
        Connection conn = null;
        CallableStatement stmt = null;
        ResultSet rs = null;
        try{
            //獲取連接
            conn = JdbcUtil.getConnection();
            //創建CallableStatement對象
            String sql = "CALL pro_findById(?)";//預編譯sql、可以帶?號
            //執行預編譯的sql
            stmt = conn.prepareCall(sql);
            //設置參數
            stmt.setInt(1, 4);
            //發送參數,執行sql,返回結果
            rs = stmt.executeQuery();// 注意: 執行存儲過程必須使用exeuteQuery!!!!
            //遍歷結果
            while(rs.next()){
                int id = rs.getInt("id");
                String name = rs.getString("name");
                String gender = rs.getString("gender");
                System.out.println(id+"\t"+name+"\t"+gender+"\t");
            }
        }catch(Exception e){
            e.printStackTrace();
            throw new RuntimeException(e);
        }finally{
            //關閉資源
            JdbcUtil.close(conn, stmt, rs);
        }
    }
    4.2 執行帶有輸出參數的存儲過程
/**
     * 執行帶有輸出參數存儲過程
     */
    @Test
    public void test2(){
        Connection conn = null;
        CallableStatement stmt = null;
        try{
            //獲取連接
            conn = JdbcUtil.getConnection();
            String sql = "CALL pro_findById2(?,?)"; // 第一個參數時輸入參數,第二個參數是輸出參數
            //創建CallableStatement對象
            stmt = conn.prepareCall(sql);
            //設置輸入參數
            stmt.setObject(1, 4);
            //註冊一個輸出參數
            /**
             * 參數一: 參數位置
             * 參數二: 表示存儲過程中的OUT參數的數據庫類型
             */
            stmt.registerOutParameter(2, java.sql.Types.VARCHAR);

            //發送參數,執行存儲過程
            stmt.executeQuery();

            /**
             * 如何獲取存儲過程的返回值:OUT參數值。使用getXXX方法
             */
            String name = stmt.getString(2);//和預編譯語句中的參數位置保持一致!!!!
            System.out.println("結果:"+name);
        }catch(Exception e){
            e.printStackTrace();
            throw new RuntimeException(e);
        }finally{
            //關閉資源
            JdbcUtil.close(conn, stmt, null);
        }
    }

5 優化jdbc工具類

private static String url = null;
    private static String user = null;
    private static String password = null;
    private static String className = null;

    static{
        //註冊驅動,註冊一次就可以了
        //註冊驅動
        try {
            //給成員變量賦值,將文件中的鍵值對加載到properties集合中
            Properties prop = new Properties();
            InputStream in = new FileInputStream("db.properties");
            prop.load(in);
            url = prop.getProperty("url");
            user = prop.getProperty("user");
            password = prop.getProperty("password");
            className = prop.getProperty("className");
            System.out.println(url);
            System.out.println(user);
            System.out.println(password);
            System.out.println(className);
            Class.forName(className);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    //獲取連接
    public static Connection getConnection(){
        try {
            //獲取連接
            Connection conn = DriverManager.getConnection(url, user, password);
            //返回conn
            return conn;
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException();
        }
    }

    //釋放資源
    public static void close(ResultSet rs,Statement stmt,Connection conn){
        //先判空後釋放
        if (rs!=null) {
            try {
                rs.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                throw new RuntimeException();
            }
        }

        if (stmt!=null) {
            try {
                stmt.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                throw new RuntimeException();
            }
        }

        if (conn!=null) {
            try {
                conn.close();
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
                throw new RuntimeException();
            }
        }

    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章