程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> JDBC基本教程

JDBC基本教程

編輯:關於JAVA

JDBC基本教程。本站提示廣大學習愛好者:(JDBC基本教程)文章只能為提供參考,不一定能成為您想要的結果。以下是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法式設計有所贊助。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved