激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務器之家 - 編程語言 - JAVA教程 - JDBC基礎教程

JDBC基礎教程

2019-12-07 15:40shichen2014 JAVA教程

這篇文章主要介紹了JDBC基礎知識與操作技巧,講述原理與基本技巧的基礎上分析了安全問題與操作注意事項,非常具有實用價值,需要的朋友可以參考下

本文實例講述了JDBC基礎知識與技巧。分享給大家供大家參考。具體分析如下:

1.什么是JDBC?

通俗來講JDBC技術就是通過java程序來發送SQL語句到數據庫,數據庫收到SQL語句后執行,把結果返回給java程序管理。

2.使用JDBC要有什么條件呢?

A)目標數據庫主機的地址

B)數據庫軟件在該主機上所占用的端口號

C)登陸數據庫用的用戶名

D)該用戶名的密碼

E)連接數據庫

3.JDBC技術的原理

我們知道,數據庫是有各種類型的,不同的廠商生產的數據庫標格和規范是不同的,這時候,如果我們用JAVA代碼來發送SQL語句,就要根據不同的數據庫來寫一套又一套的操作代碼,這對程序開發者的開發成本是十分巨大的,所以,SUN公司在開發JDBC技術的時候,規定了一套標準接口,數據庫產商都必須提供一個驅動來實現這套接口,那么,只要程序開發者在開發時使用了該數據庫的驅動,就用一致的方法來開發了,而不需自己寫一套有一套的代碼去適應不同的數據庫。

4.JDBC中的核心API

|- Driver : 驅動程序類實現的接口。

  |-Connection connect(String url, Properties info)  --用于連接數據庫,得到連接對象

Properties 里需要設置的參數:

    url: 數據庫連接的URL字符串。協議+數據庫子協議+主機+端口+數據庫

    user: 數據庫用戶名

    password: 用戶的密碼

  |-Connection :    與數據庫連接的接口

      |- Statement createStatement()   --創建Statement對象,用于發送sql語句

      |- PreparedStatement prepareStatement(String sql)  -創建PreparedStatement對象,用于發送預編譯的sql語句

      |-CallableStatement prepareCall(String sql)  --創建CallableStatement對象,用于調用存儲過程。

      |-Statement: 用于執行靜態sql語句

          |-int executeUpdate(String sql)  --執行更新操作(DDL+DML)

          |-ResultSet executeQuery(String sql)  --執行查詢操作(DQL)

      |- PreparedStatement: 用于執行預編譯的sql語句

          |- int executeUpdate() -- 執行更新操作

          |- ResultSet executeQuery()    -- 執行查詢操作

      |- CallableStatement: 用于執行存儲過程的sql

          |- ResultSet executeQuery()  --調用存儲過程

          |- ResultSet: 結果集。用于封裝數據庫的查詢后的數據

              |- boolean next() --將記錄光標移動到下一行

              |- Object getObject(int columnIndex) -- 得到字段上的值

了解完又哪些API,下面我們就來使用JDBC發送SQL語句吧~

5.使用Statement對象操作數據庫

DDL與DML操作

步驟1

導包,因為我使用的是MySQL數據庫,所以要使用JDBC技術,必須使用由MySQL數據庫產商提供的數據庫驅動,所以,第一步我們要把數據庫驅動包導入工程里。

使用的包名:mysql-connector-java-5.1.7-bin.jar

步驟2

創建一個普通的類,在里面添加一個方法,在該方法中按照以下步驟

復制代碼代碼如下:

//URL
    private String url = "jdbc:mysql://localhost:3306/vmaxtam";
    //user
    private String user = "root";
    //password
    private String password = "root";

 

public void testDDL()throws Exception{
        //1.注冊驅動
        Class.forName("com.mysql.jdbc.Driver");
        
        //2.獲取連接
        Connection conn = DriverManager.getConnection(url, user, password);
        
        //3.創建Statement對象
        Statement stmt = conn.createStatement();
        
        //4.準備sql語句
        String sql  ="CREATE TABLE student(sid INT PRIMARY KEY,sname VARCHAR(20),age INT)";
        
        //5.通過statement對象發送sql語句,返回執行結果
        int count = stmt.executeUpdate(sql);
        
        //6.打印執行結果
        System.out.println("影響了"+count+"條記錄");
}
//7.關閉資源
if(statement!=null)
{
    statement.close();
}

if(conn!=null)
{
    conn.close();
}


如果要進行DQL與DDL操作,都可以把SQL語句寫好,然后調用statement的executlUpdate方法來給數據庫執行SQL語句,這個方法返回一個整數值,表示數據庫中有多少行受到了影響。

 

如果我們不改變上述的程序,想要再向數據庫發出SQL語句,那么又要寫一個程序來再次連接,操作完后又要關閉statement對象 和connection對象,這是十分繁瑣的。所以,我們一般把連接過程和釋放對象的過程抽取到一個工具類中。工具類中的代碼如下:

復制代碼代碼如下:

public class sqlUtil {
    private static String url = "jdbc:mysql://localhost:3306/vmaxtam";
    private static String user = "root";
    private static String password = "root";

 

    // 獲取連接
    public static Connection getconnection() {
        Connection conn = null;
        try {
            // 1.注冊驅動
            Class.forName("com.mysql.jdbc.Driver");
            // 2.獲取連接
            conn = DriverManager.getConnection(url, user, password);
            // 3.獲得statement對象
            Statement statement = conn.createStatement();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return conn;
    }

    // 7.關閉資源
    public static void close(Statement statement, Connection connection) {
        {
            try {
                if (statement != null)
                    statement.close();
                if (connection != null) {
                    connection.close();
                }
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

 

還要考慮的情況就是:

一)一個用戶只需要注冊一次驅動就行,不用每次連接數據庫都注冊驅動,所以我們把注冊驅動的過程寫在靜態代碼塊中。

二)url 和用戶名,密碼還有驅動類名,在程序里是寫死的,為了能夠在不改代碼的前提下更換數據庫 或者更換用戶,我們通常把這些信息寫到一份配置文件中。

配置文件寫在工程的src目錄下,名為db.properties

復制代碼代碼如下:
url=jdbc:mysql://localhost:3306/vmaxtam
user=root
password=root
driverClass=com.mysql.jdbc.Drive


然后再sqlUtil中讀取該配置文件,最后優化成下面代碼

復制代碼代碼如下:

public class sqlUtil {
    private static String url = null;
    private static String user = null;
    private static String password = null;
    private static String driverClass= null;

 

    static{
        try {
            //1.獲得字節碼對象
            Class clazz = sqlUtil.class;
            
            //2.調用getResourceAsStream獲取路徑
            InputStream inputStream = clazz.getResourceAsStream("/db.properties");
            Properties pro = new Properties();
            pro.load(inputStream);
            
            //3.讀取參數
            url=pro.getProperty("url");
            password=pro.getProperty("password");
            user=pro.getProperty("user");
            driverClass=pro.getProperty("driverClass");
            
            Class.forName(driverClass);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("注冊失敗!" + e.getMessage());
            throw new RuntimeException(e);
        }
    }
    
    // 獲取連接
    public static Connection getconnection() {
        Connection conn = null;
        try {        
            // 獲取連接
            conn = DriverManager.getConnection(url, user, password);
            // 獲得statement對象
            Statement statement = conn.createStatement();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return conn;
    }

    // 關閉資源
    public static void close(Statement statement, Connection connection) {
        {
            try {
                if (statement != null)
                    statement.close();
                if (connection != null) {
                    connection.close();
                }
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

 

DQL操作

那么如何用JDBC來查詢數據庫中的數據呢?

復制代碼代碼如下:
@Test
    public void testdsl() throws Exception {
        //獲取連接
        cnn2=sqlUtil.getconnection();
        Statement statement = cnn2.createStatement();
    
        
        //準備SQL語句
        String sql = "select * from subject";
        
        //調用executeQuery執行查詢語句
        ResultSet res = statement.executeQuery(sql);
        
        //查詢結束后res會指向表頭,想要獲取數據必須不斷地指向查詢結果的下一行,當沒有下一行數據時,返回0.
        while(res.next())
        {
            //獲取查詢結果中字段為“sjid”的值,并且要明確類型
            int id = res.getInt("sjid");
            
            //獲取查詢結果中字段為“sjname”的值,并且要明確類型
            String name = res.getString("sjname");
            System.out.println("ID:" + id + "  NAME:" + name);
        }
        sqlUtil.close(statement, cnn2);
}

 

以上就是使用Statement對象來操作數據庫了~

6.使用PreparedStatement操作數據庫

PreparedStatement對象其實就是一個特殊的Statement對象,它能夠預編譯SQL語句,當你把參數設置好,然后就可以去執行SQL語句了~

DDL與DML操作

復制代碼代碼如下:

package com.vmaxtam.sqltest;

 

import java.sql.Connection;
import java.sql.PreparedStatement;

import org.junit.Test;

public class PreparedStatementTest {
    Connection connection = null;
    @Test
    public void ddldmlTest() throws Exception {
        // 1.獲取連接
        connection = sqlUtil.getconnection();

        // 2.準備SQL語句,預編譯語句,參數用?號占位
        String sql = "INSERT INTO SUBJECT VALUES(?,?)";

        // 3.獲得對象
        PreparedStatement preparedStatement = connection.prepareStatement(sql);

        /*
         * 4.設置SQL參數 需要參數是第幾個,并且知道它的類型 下面第一句表示:SQL語句第一個參數是int類型,參數值設置為3,如此類推
         */
        preparedStatement.setInt(1, 3);
        preparedStatement.setString(2, "英語");

        // 5.交給數據庫執行SQL
        int num = preparedStatement.executeUpdate();

        System.out.println("有" + num + "條記錄受到了影響");

              sqlUtil.close(preparedStatement , connection );
    }
}

 

以上就是使用PreparedStatement對象來進行插入語句的發送,同理,DDL與DML類的語句都可以根據這樣來發送.

PreparedStatement預編譯的好處:

PreparedStatement的預編譯可以使你可以通過設置不同的參數來查詢不同的目標,在數據庫端,只會保存一段預編譯語句,但是如果你使用Statement來發送語句,每發送一條,數據庫中就會存一條,這可能會造成占用大量內存。

DQL操作

復制代碼代碼如下:

@Test
    public void dqlTest() throws Exception {
        // 1.獲取連接
        connection = sqlUtil.getconnection();

 

        // 2.準備SQL語句,預編譯語句,參數用?號占位
        String sql = "select * from subject where sjid=? or sjname=?";

        // 3.獲得對象
        PreparedStatement preparedStatement = connection.prepareStatement(sql);

        /*
         * 4.設置SQL參數 需要參數是第幾個,并且知道它的類型 下面第一句表示:SQL語句第一個參數是int類型,參數值設置為3,如此類推
         */
        preparedStatement.setInt(1, 2);
        preparedStatement.setString(2, "語文");

        // 5.交給數據庫執行SQL
        ResultSet rst = preparedStatement.executeQuery();
        
        //6.迭代結果集
        while(rst.next())
        {
            int id = rst.getInt("sjid");
            String name = rst.getString("sjname");
            System.out.println("ID:" + id + "  NAME:" + name);
        }
        
        //7.關閉連接
        sqlUtil.close(preparedStatement, connection);
}

 

也是調用executeQuery();方法即可,得到結果集后迭代輸出~

既然Statement 與 PreparedStatement那么相似,比較它們的優缺點吧~

Statement 與 PreparedStatement的區別:

1.語法不同

Statement只支持靜態編譯,SQL語句是寫死的。

PreparedStatement支持預編譯,用?號來占位。

2.效率不同

Statement每次都要發送一條SQL語句,不支持緩存,執行效率低。

PreparedStatement支持預編譯,緩存在數據庫,只需發送參數,執行效率快。

3.安全性不同

Statement容易被注入。

注入:狡猾的分子可以編寫特殊的SQL語句來入侵數據庫。

例如:要查詢某個用戶的信息

一般情況:SELECT * FROM user_list where username=xxx and password=xxx;(這里的xxx本應為用戶填寫自己的用戶名和密碼)

注入情況:SELECT * FROM user_list where username='abc' or 1=1 -- password=xxx;

這樣1=1恒等,而且在password前加上了“--”號,后面的內容成為了注釋不被執行。也就是說,這樣就能不用密碼地查詢所有的用戶信息。

PreparedStatement,因為規定了SQL語句中的參數,所以可以防止注入。

結論:建議使用PreparedStatement,因為它更快更安全

7.使用CallableStatement執行存儲過程

使用CallableStatement只是執行存儲過程,創建存儲過程我們還是要在數據庫內創建的。

步驟1

現在數據庫建好一個存儲過程:

復制代碼代碼如下:
DELIMITER $
CREATE PROCEDURE pro_add(IN a INT , IN b VARCHAR(20),OUT c INT)
BEGIN    
    SELECT * FROM SUBJECT WHERE sjid=a OR sjname=b;
    SET c=a+a+a+a;
END $

 

步驟2

利用java代碼執行,并得到輸出參數

復制代碼代碼如下:
@Test
public void calaST() throws Exception {
        //獲取連接
        connection= sqlUtil.getconnection();
        //準備SQL語句
        String sql = "CALL pro_add(?,?,?)";
        
        //得到callableStatement對象
        CallableStatement cbs = connection.prepareCall(sql);
        
        //設置輸入參數,和preparedStatement一樣
        cbs.setInt(1, 3);
        cbs.setString(2, "數學");
        
        /*那么如何設置輸出參數呢?
         * 需要注冊輸出參數!
         */
        cbs.registerOutParameter(3, java.sql.Types.INTEGER);//需要使用內置對象來設置參數類型
        
        //執行SQL語句
        cbs.executeQuery();
        
        //利用getXXX方法得到相應位置的輸出參數
        Integer num= cbs.getInt(3);
        
        System.out.println("a*4 is " + num);
        
             //關閉資源
        sqlUtil.close(cbs, connection);
}

 

希望本文所述對大家的Java程序設計有所幫助。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: gogo全球大胆高清人露出91 | 免费一级肉体全黄毛片 | av国产在线被下药迷网站 | 欧美一级毛片美99毛片 | 一本色道久久综合狠狠躁篇适合什么人看 | 中国av中文字幕 | 久久精品免费网站 | 亚洲一区二区三区在线免费观看 | 国产成人综合在线视频 | 国产精品久久久久久久亚洲按摩 | 青青国产在线视频 | 久久中文一区 | 91网站免费在线观看 | 综合成人在线 | 免费在线观看成人网 | 亚洲最新无码中文字幕久久 | 色欧美视频 | 亚洲一级片免费观看 | 久久这里只有精品1 | 国产一级毛片高清视频 | 日日草夜夜 | 激情综合在线 | 亚洲欧美日韩久久精品第一区 | 色综合欧美 | 国产一区视频在线免费观看 | 亚洲一级片免费观看 | v11av在线视频成人 | 在线成人免费视频 | 欧美日韩国产中文字幕 | 99精品视频免费看 | 国产精品啪一品二区三区粉嫩 | 精品久久久久久久久久久久久久久久久久久 | 可以看逼的视频 | 手机免费看一级片 | 国产精品刺激对白麻豆99 | 伦理三区 | 在线播放免费人成毛片乱码 | 婷婷久久青草热一区二区 | a视频在线播放 | 欧美黑人一级 | 成人免费毛片网站 |