20.java-JDBC鏈接mysql數據庫詳解

1.JDBC介紹

jdbc(java database connectivity)爲java開發者使用數據庫提供了統一的編程接口,它由一組java類和接口組成。java

JDBC須要用到的類和接口有:mysql

DriverManager、Connection、Statement、ResultSet         sql

 

2. mysql-connector-java下載

本機的mysql版本是5.7.26 win32的,因此本章訪問mysql都以該版本爲例:數據庫

 

而後進入https://dev.mysql.com/downloads/connector/j/下載mysql-connector-java.jar包,用於鏈接mysql編程

以下圖所示,只有8.0.19版本,那咱們下載它就行了,反正無論64位仍是32位都能訪問:工具

 

下載解壓後,就有個mysql-connector-java-8.0.19.jar:測試

 

接下來就來測試,能不能訪問url

 

3.JDBC使用過程spa

3.1 經過DriverManager. registerDriver(Driver driver)來註冊驅動程序code

須要注意,new Driver的時候,須要選擇com.mysql.cj.jdbc.Driver:

 

由於com.mysql.jdbc.Driver已經被棄用了.

PS:也能夠直接將DriverManager. registerDriver(Driver driver)改成:

Class.forName("com.mysql.cj.jdbc.Driver");
//加載一下這個類就能夠註冊驅動,由於mysql Driver類的靜態代碼塊中已經調用了registerDriver()來註冊驅動程序.

 

3.2 而後經過 Connection DriverManager.getConnection(String url, String user, String password)來鏈接數據庫,並獲取Connection對象

url: 填入「jdbc:子協議://ip地址:端口號/數據庫名」 ,若是是mysql則填入「jdbc:mysql://localhost:3306/數據庫名」

針對mysql-connector-java-8.0以上的版本,則還要追加"?characterEcoding=utf-8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true"

username:mysql用戶名

password:mysql密碼

 

3.3 經過Connection對象獲取statement對象

Statement statement = connection.createStatement();

 

3.4 經過statement對象的executeQuery(String)來執行查詢sql語句,並返回ResultSet數據庫結果集

好比:

ResultSet  resultSet = statement. executeQuery("select * from student");       //獲取student表裏的數據

除此以外還有int executeUpdate(String sql)方法.用來實現INSERT、UPDATE 或 DELETE 語句,返回值表示執行sql語句以後影響到的數據行數 (後面示例有講)

 

3.5 而後經過ResultSet來讀出query內容

ResultSet經常使用方法以下:

boolean first();             //移到內容第一行數據處

boolean  last();             //移到內容最後一行數據處

int getRow() ;             //獲取當前光標處於的行號

boolean isLast()           //獲取光標是否位於此 ResultSet 對象的最後一行。

boolean   next();          //移到下一行數據處,而後就能夠經過getXXX()獲取完當前一行數據後,則經過next()來移動到下行繼續getXXX(),直到next()返回爲false爲止

boolean   previous();     //移到上一行數據處

String getString(String columnLabel);  //獲取當前一行的columnLabel列名的內容                             

String  getString(int columnIndex);   //獲取當前一行的第columnIndex列的內容,第一列是從1開始的.

         String getInt (String columnLabel);  //獲取當前一行的columnLabel列名的內容                     

String  getInt(int columnIndex);  //獲取當前一行的第columnIndex列的內容,第一列是從1開始的.

 
//...除此以外,還有getFloat(),getLong(),getShort(),getURL(),getBoolean(),getRowId()

 PS:獲取到ResultSet後,必須先next()一次才能getXXX(),來獲取內容

 

3.6 訪問結束後,釋放Mysql資源(畢竟mysql連入個數是有限的) 

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

 

4.本章要訪問的數據庫以students爲例:

 

 

5.首先來寫JdbcUtils工具類

JdbcUtils工具類裏主要寫getConnection(),releaseResc()這兩個類,這樣避免後續的重複代碼產生.

JdbcUtils.java代碼以下所示:

public class JdbcUtils {

    private static String driver;
    private static String url;
    private static String user;
    private static String pwd;

    static{
        
        driver = "com.mysql.cj.jdbc.Driver";
        url = "jdbc:mysql://localhost:3306/students?characterEcoding=utf-8&"    
                + "useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true";
    
        user = "root";
        pwd = "sql";
        
    }
    
    
    //獲取一個連接mysql的Connection對象
    static public Connection getConnection(){
        
        try {
            Class.forName(driver);
             Connection connection = DriverManager.getConnection(url,user,pwd);
             return connection;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        
    }
    
    /**
     * 釋放Mysql資源(畢竟mysql連入個數是有限的)    
     * @param resultSet 結果集
     * @param statement 
     * @param connection 連接
     */
    public static void releaseResc(ResultSet resultSet, Statement statement, Connection connection) {
    
        try {
            if(resultSet!=null){
            resultSet.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } 
        try {
            if(statement!=null){
            statement.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            if(connection!=null){
            connection.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

 

6.數據庫查詢示例

查詢全部學生的信息:

@Test
    public void jdbcQuery(){
        
        ResultSet resultSet = null;
        Statement statement = null;
        Connection connection = null;
        try {
            connection = JdbcUtils.getConnection();        //經過JdbcUtils獲取connection
            statement = connection.createStatement();
            
            String sql = "select * from student";
            
            resultSet = statement.executeQuery(sql);
        
            while(resultSet.next()){
                
                String name = resultSet.getString("name");
                String score = resultSet.getString("score");
                String classs = resultSet.getString("class");
                
                System.out.println("姓名:"+name+"  成績:"+score+"  班級:"+classs);
            }
            
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            
            JdbcUtils.releaseResc(resultSet, statement, connection);        //釋放資源
        }
    }

打印以下所示:

 

 

7.數據庫插入示例

@Test
    public void jdbcInser(){
        
        ResultSet resultSet = null;
        Statement statement = null;
        Connection connection = null;
         
        try {
            connection = JdbcUtils.getConnection();
            statement = connection.createStatement();
            
            String name = "小f";
            int score = 99;
            String classs = "初2-4班";
            
            String sql = "INSERT INTO  student(name,score,class) "        
                       +" values('"+name+"','"+String.valueOf(score)+"','"+classs+"')";
            
            int result = statement.executeUpdate(sql); 
            //executeUpdate:用來實現INSERT、UPDATE 或 DELETE 語句,返回值表示執行sql語句以後影響到的數據行數 
            
            System.out.println("插入了"+result+"條數據");
            
            
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            
            JdbcUtils.releaseResc(resultSet, statement, connection);        //釋放資源
        }
    }

運行打印:

 

查看數據庫:

 

8.數據庫更新示例

將全部低於60分的同窗的成績改成0:

@Test
    public void jdbcUpdate(){
        
        ResultSet resultSet = null;
        Statement statement = null;
        Connection connection = null;
        
        try {
            connection = JdbcUtils.getConnection();
             statement = connection.createStatement();
            
        
            String sql = "update student  SET score='0'  WHERE  score<60";
            
            
            int result = statement.executeUpdate(sql); 
            //executeUpdate:用來實現INSERT、UPDATE 或 DELETE 語句,返回值表示執行sql語句以後影響到的數據行數 
            
            System.out.println("更新了"+result+"條數據");
            
            
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally {
            
            JdbcUtils.releaseResc(resultSet, statement, connection);        //釋放資源
        }
        
    }

查看數據庫:

 

 

9.SQL 注入攻擊

Statement採起直接編譯 SQL 語句的方式,扔給數據庫去執行,因此很容易進行被SQL注入攻擊.

好比:

咱們登錄執行時須要執行:

statement.executeQuery("select id from users where name ='"+username+"' and password = '"+password+"'");

而黑客則將字符串直接改成:

statement.executeQuery("select id from users where name ='"+username+"' or '1==1' and password = '"+password+"'");

就能夠直接亂輸入密碼也能實現登陸了,因此java中提供了另外一個類PreparedStatement, 採用"?"佔位符預編譯,再填充參數,用來避免SQL注入攻擊.

 

PreparedStatement類介紹

採用"?"佔位符預編譯,再填充參數,而後經過setXXX()來填充參數.好比setString():

setString(int parameterIndex, String x);       //向第parameterIndex個佔位符填入x內容
// parameterIndex:第一個?佔位符是1,第二個是2....

//...除了該方法以外,還有setFloat(),setLong(),setBoolean()....等等

 

修改登陸界面之PreparedStatement使用以下所示:

public static boolean login(String username,String password){
          Connection connection = JdbcUtils.getConnection();                  //獲取
                  try {

                          String sql = "select id from users where username =? and password = ?"; //要運行的sql語句,經過?來替換登陸帳號和密碼

                          PreparedStatement preparedStatement = connection.prepareStatement(sql);

                          //第一個? 用username字符串去替換
                          preparedStatement.setString(1, username);

                          //第二個? 用password字符串去替換
                          preparedStatement.setString(2, password);

                          ResultSet resultSet = preparedStatement.executeQuery();

                          return resultSet.next();            //有值則返回true,不然返回false;

                  } catch (SQLException e) {
                          e.printStackTrace();
                          return false;
                  }
 }
相關文章
相關標籤/搜索