Java后台Servlet學習(二)


 

  首先糾正前一篇博客中的一個小問題,關於Get和Post兩種請求,昨天翻了下室友的Android開發教程,看了下發送請求那一塊,里面說到Get請求是想從服務端獲取信息,Post只是想上傳信息到服務端,但是有一點不明白,明明Post也有response對象,應該也能返回信息到客戶端才對,區別還是不太懂。

  下面進入正題,這一篇博客主要是記錄回顧JDBC的一些操作,以及遇到的一些問題

1.准備工作

  首先MySQL安裝好不用多說,然后編譯器我的是eclipse oxygen,相對上一次需要多准備的也就只有一個jar包,下載鏈接:https://dev.mysql.com/downloads/connector/j/ 

  

2.JDBC連接MySQL數據庫

  我們首先來看一下官方給出的樣例代碼

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

// Notice, do not import com.mysql.cj.jdbc.*
// or you will have problems!

public class LoadDriver {
    public static void main(String[] args) {
        try {
            // The newInstance() call is a work around for some
            // broken Java implementations

            Class.forName("com.mysql.cj.jdbc.Driver").newInstance();
        } catch (Exception ex) {
            // handle the error
        }
    }
}
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

Connection conn = null;
...
try {
    conn =
       DriverManager.getConnection("jdbc:mysql://localhost/test?" +
                                   "user=minty&password=greatsqldb");

    // Do something with the Connection

   ...
} catch (SQLException ex) {
    // handle any errors
    System.out.println("SQLException: " + ex.getMessage());
    System.out.println("SQLState: " + ex.getSQLState());
    System.out.println("VendorError: " + ex.getErrorCode());
}

  以上兩段是官方給出的連接數據庫的代碼,第一部分是利用forName函數獲取MySQL驅動,后面的newInstance可以不用寫,forName中的參數是根據你MySQL的版本來的,這也就是我學習中遇到的第一個坑,最開始跟着網上的教程做一直連接不上數據庫,因為之前的MySQL版本forName中的參數都是com.mysql.jdbc.Driver,而我下的最新版本是com.mysql.cj.jdbc.Driver,獲取驅動之后就可以准備連接了Connection con = DriverManager.getConnection(String url),這一步只需要知道url的值就可以了,下面就講一講url的格式

  url:  "jdbc:mysql://" + 數據庫所在的ip(本機就可以用localhost)+ "/" + 想要訪問的數據庫名 + "?" + "user=" + 數據庫賬號 + "&password=" + 賬號對應的密碼

  其實一般的訪問的url鏈接也是跟這個差不太多的,這部分放到后面再繼續說,不管怎么說連接數據庫的部分算是結束了吧,畢竟根據官方的文檔來寫應該是沒什么問題的,然而讓我萬萬沒想到的,就是有問題!

  這個的原因是時差,報錯的信息中也有寫到time zone對吧,所以網上查一查也就知道了,在url后面接上&serverTimezone=GMT就真正的連接成功啦,特別提醒url中不能有空格,所以像我這種寫代碼習慣數字和操作符用空格隔開的朋友需要注意。

3.利用JDBC對數據庫進行操作

  首先來介紹一下JDBC對數據庫進行操作的方式,目前就我了解到的就兩種類,一個是Statement類,一個是PreparedStatement類

  先來介紹第一個Statement

  1)Statement對象的創建方式

    我們之前通過DriverManager.getConnection()函數已經獲得了Connection對象con,而Statement對象則是通過con.createStatement()函數獲得的,下面是官方的解釋

  返回類型為Statement,作用生成一個Statement對象來發送SQL聲明給數據庫

  2)利用Statement對象進行數據庫查詢

    數據庫查詢用到的函數是executeQuery(String SQL),其實也很好理解,execute是執行的意思,query是查詢的意思,這里函數返回的是一個ResultSet對象

    ResultSet的常用的操作就是next()函數和各種get函數,前一個是移動到下一行,如果后面沒有了就返回false,有就返回true,get函數就比如getString、getInt等,傳參的方式有int string兩種,比如我user表中的是id(int)、username(String)、password(String),在執行ResultSet rs = execute("SELECT * FROM user")之后,我想獲得第一行中的username就先rs.next();然后可以用String str = rs.getString(2);或者rs.getString("username");同樣的想獲得id可以使用int id = rs.getInt(1)或者rs.getInt("id");下面給出官方的說明

  

  

  3)利用Statement對象對數據庫進行增、刪、改操作

    在JDBC中update、delete、insert都被歸納成update,所以都通過executeUpdate(String sql)函數進行操作,返回值是操作的行數,這個就沒什么好說的了,下面是官方的說明文檔

  4)在不知道是查詢還是更改的情況下

    在不知道是要查詢還是更改的情況下,我們可以用execute(String sql)直接執行,但是這個函數的返回值是bool型,也就是在sql為查詢語句的時候就返回true,在為更改語句的時候返回false,如果是查詢語句,想要獲得結果可以在Statement對象調用execute()函數之后再調用getResultSet()函數;如果是update語句,想要得到update的列數,可以可以在Statement對象調用execute()函數之后再調用getUpdateCountt()函數,下面是例子

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

// assume that conn is an already created JDBC connection (see previous examples)

Statement stmt = null;
ResultSet rs = null;

try {
    stmt = conn.createStatement();
    rs = stmt.executeQuery("SELECT foo FROM bar");

    // or alternatively, if you don't know ahead of time that
    // the query will be a SELECT...

    if (stmt.execute("SELECT foo FROM bar")) {
        rs = stmt.getResultSet();
    }

    // Now do something with the ResultSet ....
}
catch (SQLException ex){
    // handle any errors
    System.out.println("SQLException: " + ex.getMessage());
    System.out.println("SQLState: " + ex.getSQLState());
    System.out.println("VendorError: " + ex.getErrorCode());
}
finally {
    // it is a good idea to release
    // resources in a finally{} block
    // in reverse-order of their creation
    // if they are no-longer needed

    if (rs != null) {
        try {
            rs.close();
        } catch (SQLException sqlEx) { } // ignore

        rs = null;
    }

    if (stmt != null) {
        try {
            stmt.close();
        } catch (SQLException sqlEx) { } // ignore

        stmt = null;
    }
}

    到這里有關Statement的操作就講解完畢,Statement的操作一般針對用不變的操作,輸入的語句是固定的,不要說用String拼接,那樣不安全比如固定好的語句為

        String sql = "SELECT password FROM user WHERE username=" +user_name;

    針對這種情況輸入的是'OR'1'='1'時,執行的語句就發生了變化,所以針對Statement對象不要使用字符串拼接!

    那么要實現可以復用、更改的執行語句要用什么呢,下面就介紹第二種PreparedStatement

   1)創建PreparedStatement

     創建PreparedStatement對象的方式為con.prepareStatement(String sql)

String sql = "SELECT password FROM user WHERE username=?";
PreparedStatement  ps = con.prepareStatement(sql);

      ?就是未定的部分(注意=的左右不要有空格,不要有空格,不要有空格),可以利用ps.setString(int num,String str)函數拼接上去,但是利用這個函數拼接就不會出現問題,因為這個函數會把敏感符號全部轉譯,單引號這種符號也就只是一個單引號了,不會改變原來SQL語句的意思,還有一些setInt等操作、作用也是一樣的 

      這里的第一個參數就表示是第幾個?,第二個參數是要修改的值

   2)利用PreparedStatement對象對數據庫進行查詢操作

      由於在創建PreparedStatement對象的時候傳入的sql語句,所以查詢的時候就不需要額外傳入參數了,直接調用executeQuery()函數即可,返回值仍然是ResultSet型

   3)利用PreparedStatement對象對數據庫進行增、刪、改

       同查詢值要直接調用executeUpdate()函數即可,返回值還是更改的行數

 

    以上就是我掌握的JDBC的知識,這段時間在學習過濾器和監聽器的操作,大概十天之后寫關於這兩個的操作吧

 

 

  

 

    

 

     

  


免責聲明!

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



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