JDBC-01

来源:https://www.cnblogs.com/Charles-H/archive/2020/04/02/Learning_JDBC01.html
-Advertisement-
Play Games

JDBC 前言 在學習了SQL語句後,我們肯定會思考如何使用資料庫里的數據。這個時候,我們便要學習JDBC來將資料庫與JAVA結合在一塊。 正題 什麼是JDBC? Java資料庫連接,(Java Database Connectivity,簡稱JDBC)是Java語言中用來規範客戶端程式如何來訪問數 ...


JDBC

前言

  在學習了SQL語句後,我們肯定會思考如何使用資料庫里的數據。這個時候,我們便要學習JDBC來將資料庫與JAVA結合在一塊。

 

正題

什麼是JDBC?

Java資料庫連接,(Java Database Connectivity,簡稱JDBC)是Java語言中用來規範客戶端程式如何來訪問資料庫的應用程式介面。

 

JDBC的主要用途

  1. 與資料庫建立連接
  2. 發送 SQL 語句
  3. 處理結果

 

資料庫驅動

在學習JDBC之前,我們必須瞭解一個東西,驅動。

驅動:兩個設備(兩個應用)之間通信的橋梁。

 

JDBC的開發步驟

  1. 載入驅動
  2. 獲取連接
  3. 基本操作(CRUD)
  4. 釋放資源

 

使用JDBC的準備工作

  1.創建一個maven項目(當然你也可以不用這種方法,但maven在開發中最為方便)

  【創建方式請看我之前的博客:利用Maven進行導jar包】

  2.導入mysql的jar包

<dependencies>
       <dependency>
           <groupId>mysql</groupId>
           <artifactId>mysql-connector-java</artifactId>
           <version>5.1.6</version>
       </dependency>
 </dependencies>

  完成以上的操作,我們便可以開始進行JDBC的學習了。

 

JDBC的簡單例子(先瞭解一下整體的框架,後面會相應的解釋以及簡化)

package com.jdbc.demo01;

import org.junit.Test;
import java.sql.*;

/**
 *

 * JDBC的入門程式

 * @author  Charles
   *
    */
   public class JDBCdemo1 {
    @Test
public void demo01() throws ClassNotFoundException, SQLException { // 1.載入驅動 Class.forName("com.jdbc.Driver"); // 2.獲得連接 Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/web_test3", "root" , "1234"); // 3.基本操作:執行SQL // 3.1獲得執行SQL語句的對象 Statement statement = conn.createStatement(); // 3.2編寫SQL語句: String sql = "select * from user"; // 3.3執行SQL: ResultSet rs = statement.executeQuery(sql); // 3.4遍歷結果集 while (rs.next()){ System.out.println(rs.getInt(("id")+ " ")); System.out.println(rs.getInt(("username")+ " ")); System.out.println(rs.getInt(("password")+ " ")); System.out.println(rs.getInt(("nickname")+ " ")); System.out.println(rs.getInt(("age"))); System.out.println(); } // 4.釋放資源 rs.close(); statement.close(); conn.close(); } }

 

接下來我來介紹一下上面代碼的含義:

DriverManager:驅動管理類

  作用:①註冊驅動 ②獲得連接

①:

// 1.載入驅動,雙引號裡面的內容一般是標準
Class.forName("com.jdbc.Driver");

 

此時,你或許會好奇,不是註冊驅動嗎,為什麼代碼是載入驅動。

首先,我們來看看JAVA的API中Driver註冊驅動的介紹

 

 

這種方式的確可以完成驅動的註冊,但是實際開發中並不會這麼做。

原因:

  如果需要註冊驅動,就會使用DirverManager.registerDriver(new Driver()); ,但是在查詢源代碼的時候,我們發現源代碼中有一段靜態代碼塊已經調用了註冊驅動的方法。因此,如果我們再手動調用註冊,就會導致驅動被註冊兩次。

 

所以調用 Class.forName 將自動將載入驅動程式類。(具體的原理可以查看一些API文檔)

 

②:Connection conn = DriverManager.getConnection(url, user, password);

// 2.獲得連接
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/web_test3", "root", "1234");

 參數介紹:

  • url:與資料庫連接的路徑
  • user:與資料庫連接的用戶名
  • password:與資料庫連接的密碼

 

url:

"jdbc:mysql://localhost:3306/web_test3"
  • jdbc:連接資料庫的協議
  • mysql:是jdbc的子協議
  • localhost:連接的Mysql資料庫伺服器的主機地址【本機:localhost,非本機:連接主機的IP地址】
  • 3306:Mysql資料庫伺服器的埠號
  • web_test3:資料庫名稱

 

Connection:與資料庫的連接對象

  作用:①創建執行SQL語句的對象  ②管理事務

①:常用的三個對象:Statement、CallableStatement、PreparedStatement

Statement:執行SQL語句

 

 

CallableStatement:執行資料庫的存儲過程

 

PrepardedStatement:執行SQL語句,對SQL進行預處理。(用於解決SQL註入漏洞問題)

 

②:三個常用對象:setAutoCommit、commit、rollback

setAutoCommit

 

 

commit

 

rollback

 

 

接下來我們來看看Statement的詳細操作:

作用:①執行SQL  ②執行批處理

①:常用的執行SQL方法: 主要使用的是後兩個

  • boolean execute(String sql)

  執行查詢,修改,添加,刪除的SQL語句

 

  • ResultSet executeQuery(String sql) 

  執行查詢(Select 語句)

 

  • int executeUpdate(String sql)

  執行修改,添加,刪除的SQL語句

 

 

②:常用的執行批處理的方法

 addBatch

 

clearBatch

 

executeBatch

 

ResultSet:結果集

通過select語句的查詢結果

 

結果集的遍歷:

 

 

 

結果集的獲取:

 

結果集的獲取可以使用: getxxx(); 通常都會有重載的方法。

getxxx(int columnIndex);

getxxx(String columnName);

 

JDBC的資源釋放:

  JDBC程式執行結束後,將與資料庫進行交互的對象釋放掉,通常是ResultSet,Statement(PreparedStatement),Connection。

  這幾個對象尤其是Connection對象是非常稀有的,這個對象一定要做到儘量晚創建,儘早釋放掉。

  註:釋放代碼應寫入finally的代碼塊中。

 

具體實現:

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

 

CRUD的操作:

保存操作:

package com.charles.sql;

import org.junit.*;

import java.sql.*;

public class Demo01 {
    @Test
    public void demo01(){
        Connection conn = null;
        Statement statement = null;
        try{
            // 註冊驅動
            Class.forName("com.mysql.jdbc.Driver");
            // 獲得連接
            conn = DriverManager.getConnection("jdbc:mysql:///web_test3", "root",
                    "1234);
            // 執行操作
            // 創建執行SQL語句對象
            statement = conn.createStatement();
            // 編寫SQL語句
            String sql = "insert into user values (null, 'eee', '123', 'Jack', 21)";
            // 執行SQL語句
            int num = statement.executeUpdate(sql);
            if (num > 0){
                System.out.println("保存用戶成功!");
            }

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            // 釋放資源
            if (statement != null){
               try{
                   statement.close();
               } catch (SQLException e){
                   e.printStackTrace();
               }
               statement = null;
            }

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

        }
    }

}

 

修改操作:

package com.charles.sql;

import org.junit.*;

import java.sql.*;

public class Demo01 {
    @Test
    public void demo01(){
        Connection conn = null;
        Statement statement = null;
        try{
            // 註冊驅動
            Class.forName("com.mysql.jdbc.Driver");
            // 獲得連接
            conn = DriverManager.getConnection("jdbc:mysql:///web_test3", "root",
                    "1234");
            // 執行操作
            // 創建執行SQL語句對象
            statement = conn.createStatement();
            // 編寫SQL語句
            String sql = "update user set password='2222',nickname='biubiu' where id=6";
            // 執行SQL語句
            int num = statement.executeUpdate(sql);
            if (num > 0){
                System.out.println("修改用戶成功!");
            }

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            // 釋放資源
            if (statement != null){
               try{
                   statement.close();
               } catch (SQLException e){
                   e.printStackTrace();
               }
               statement = null;
            }

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

        }
    }

}

 

刪除操作:

package com.charles.sql;

import org.junit.*;

import java.sql.*;

public class Demo01 {
    @Test
    public void demo01(){
        Connection conn = null;
        Statement statement = null;
        try{
            // 註冊驅動
            Class.forName("com.mysql.jdbc.Driver");
            // 獲得連接
            conn = DriverManager.getConnection("jdbc:mysql:///web_test3", "root",
                    "1234");
            // 執行操作
            // 創建執行SQL語句對象
            statement = conn.createStatement();
            // 編寫SQL語句
            String sql = "delete from user where id=6";
            // 執行SQL語句
            int num = statement.executeUpdate(sql);
            if (num > 0){
                System.out.println("刪除用戶成功!");
            }

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            // 釋放資源
            if (statement != null){
               try{
                   statement.close();
               } catch (SQLException e){
                   e.printStackTrace();
               }
               statement = null;
            }

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

        }
    }

}

 

查詢操作:

①多條信息查詢:

package com.charles.sql;

import org.junit.*;

import java.sql.*;

public class Demo01 {
    @Test
    public void demo01(){
        Connection conn = null;
        Statement statement = null;
        ResultSet rs = null;
        try{
            // 註冊驅動
            Class.forName("com.mysql.jdbc.Driver");
            // 獲得連接
            conn = DriverManager.getConnection("jdbc:mysql:///web_test3", "root",
                    "1234");
            // 執行操作
            // 創建執行SQL語句對象
            statement = conn.createStatement();
            // 編寫SQL語句
            String sql = "select * from user";
            // 執行SQL語句
            rs = statement.executeQuery(sql);
            while(rs.next()){
                 System.out.println(rs.getInt(("id")+ " "));
                System.out.println(rs.getInt(("username")+ " "));
                System.out.println(rs.getInt(("password")+ " "));
                System.out.println(rs.getInt(("nickname")+ " "));
                System.out.println(rs.getInt(("age")));
                System.out.println();
            }

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            // 釋放資源
            if (statement != null){
               try{
                   statement.close();
               } catch (SQLException e){
                   e.printStackTrace();
               }
               statement = null;
            }

            if (conn != null){
                try {
                    conn.close();
                }catch (SQLException e){
                    e.printStackTrace();
                }
                conn = null;
            }
            
            if (rs != null){
                try {
                    rs.close();
                }catch (SQLException e){
                    e.printStackTrace();
                }
                conn = null;
            }

        }
    }

}

 

②一條信息查詢:

package com.charles.sql;

import org.junit.*;

import java.sql.*;

public class Demo01 {
    @Test
    public void demo01(){
        Connection conn = null;
        Statement statement = null;
        ResultSet rs = null;
        try{
            // 註冊驅動
            Class.forName("com.mysql.jdbc.Driver");
            // 獲得連接
            conn = DriverManager.getConnection("jdbc:mysql:///web_test3", "root",
                    "1234");
            // 執行操作
            // 創建執行SQL語句對象
            statement = conn.createStatement();
            // 編寫SQL語句
            String sql = "select * from user where id=1";
            // 執行SQL語句
            rs = statement.executeQuery(sql);
            if(rs.next()){
                System.out.println(rs.getInt("id")+" "+rs.getString("username")+" 
                                   "+re.getString("password"));
            }

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            // 釋放資源
            if (statement != null){
               try{
                   statement.close();
               } catch (SQLException e){
                   e.printStackTrace();
               }
               statement = null;
            }

            if (conn != null){
                try {
                    conn.close();
                }catch (SQLException e){
                    e.printStackTrace();
                }
                conn = null;
            }
            
            if (rs != null){
                try {
                    rs.close();
                }catch (SQLException e){
                    e.printStackTrace();
                }
                conn = null;
            }

        }
    }

}

 

JDBC工具類的抽取:

目的:包裝成工具類後,能夠更方便地使用JDBC,減少不必要的工作量

package org.charl;

import java.sql.*;

/**
 * JDBC工具類
 * @author Charles
 */

public class Demo {

    // 預設設置
    public static final String driverClassName;
    public static final String url;
    public static final String username;
    public static final String password;
    static {
        driverClassName = "com.mysql.jdbc.Driver";
        url = "jdbc:mysql:///web_test3";
        username = "root";
        password = "1234";
    }
    // 註冊驅動類
    public static void loadDriver(){
        try {
            Class.forName(driverClassName);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    // 獲得連接
    public static Connection getConnection(){
        Connection conn = null;
        try {
            loadDriver();
            conn = DriverManager.getConnection(url,username,password);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return conn;
    }

    // 資源釋放
    public static void release(Statement st,Connection conn){
        if (st != null){
            try{
                st.close();
            } catch (SQLException e){
                e.printStackTrace();
            }
            st = null;
        }

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

    public static void release(Statement st,Connection conn, ResultSet rs){
        if (st != null){
            try{
                st.close();
            } catch (SQLException e){
                e.printStackTrace();
            }
            st = null;
        }

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

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

 

配置文件:

  創建一個:db.properties配置文件

  作用:用來存儲資料庫用戶等信息

  目的:簡化工具類的代碼

演示:

 

 

在工具類中解析屬性文件

 

JDBC的SQL註入漏洞:

  什麼是SQL註入漏洞?

    假設有一個網站,用戶需要進行註入。用戶註冊後根據用戶名和密碼進行登錄。假設該用戶的用戶名被其他人知道了,但他並不     知道密碼,也可以登錄到網站上進行相應的用戶操作。

 

  漏洞分析:

 

 

  SQL註入漏洞的解決方法

  採用PreparedStatement對象解決SQL註入漏洞問題。該對象將SQL預先進行編譯,使用'?'作為占用符。'?'所代表的內容是SQL所固定。如果再次傳入變數(包括SQL的關鍵字),這個時候也不會識別這些關鍵字。

 

PreparedStatement預編譯:

具體操作:

package com.charles.sql;

import java.sql.*;

/***
 * @return
 * @author Charles
 */

public class Demo02 {
    public boolean login(String username, String password){

        Connection conn = null;
        PreparedStatement preparedStatement = null;
        ResultSet rs = null;
        boolean flag = false;
        try{
            conn = org.charl.Demo.getConnection();
            String sql = "select * from user where username = ? and password = ?";
            preparedStatement = conn.prepareStatement(sql);
            // 設置參數
            preparedStatement.setString(1,username);
            preparedStatement.setString(2,password);
            rs = preparedStatement.executeQuery();
            if (rs.next()){
                flag = true;
            }
        } catch (SQLException e){
            e.printStackTrace();
        } finally {
            org.charl.Demo.release(preparedStatement,conn,rs);
        }
        return flag;
    }
}

 

JDBC批處理操作:

  什麼是批處理?

    批處理就是將所有SQL語句一起執行。

常用的方法已在前面介紹過。

註意:通常情況下MySQL批處理是沒有開啟的,要想執行批處理,就要在url的內容中進行相應的添加。

?rewriteBatchedStatements=true

 

 

接下來展示一下比較完整的實例:

【裡面包含了PreparedStatement等內容,之前的案例看不懂沒關係,這個案例供大家參考】

 

資料庫web_test4中user表原先的信息

 

 

工具類代碼

package org.charl;

import java.sql.*;
import java.util.Properties;

/**
 * JDBC工具類
 * @author Charles
 */

public class Demo {

    // 預設設置
    public static final String driverClassName;
    public static final String url;
    public static final String username;
    public static final String password;
    static {
        driverClassName = "com.mysql.jdbc.Driver";
        url = "jdbc:mysql:///web_test4?rewriteBatchedStatements=true?characterEncoding=utf-8";
        username = "root";
        password = "1234";
    }
    // 註冊驅動類
    public static void loadDriver(){
        try {
            Class.forName(driverClassName);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    // 獲得連接
    public static Connection getConnection(){
        Connection conn = null;
        try {
            loadDriver();
            conn = DriverManager.getConnection(url,username,password);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return conn;
    }

    // 資源釋放
    public static void release(Statement st,Connection conn){
        if (st != null){
            try{
                st.close();
            } catch (SQLException e){
                e.printStackTrace();
            }
            st = null;
        }

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

    public static void release(Statement st,Connection conn, ResultSet rs){
        if (st != null){
            try{
                st.close();
            } catch (SQLException e){
                e.printStackTrace();
            }
            st = null;
        }

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

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

 

執行主代碼

package com.charles.sql;

import org.junit.Test;

import java.sql.*;

public class Demo03 {
    @Test
    public void Test(){
        long begin = System.currentTimeMillis();
        Connection conn = null;
        PreparedStatement preparedStatement = null;
        ResultSet rs = null;
        try{
            // 註冊驅動 + 獲得連接
            conn = org.charl.Demo.getConnection();
            // 編寫SQL語句
            String sql = "insert into user values(null,?)";
            // 預編譯
            preparedStatement = conn.prepareStatement(sql);
            for (int i =1;i<10000;i++){
                preparedStatement.setString(1,"name"+i);
                // 添加到批處理
                preparedStatement.addBatch();
                // 執行批處理
              

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、創建項目(本文以Idea基於Maven構建的項目為例) New——>Project 筆者這裡是選擇自己本地的Maven及配置 最後點擊Finish即可 二、在配置文件中添加依賴包 pom.xml配置文件中添加Mybatis、JDBC驅動、log4j日誌管理的包依賴 完整代碼如下: <?xml v ...
  • 項目簡介 項目來源於: "https://gitee.com/glotion/servlet jsp_news" 本系統基於 JSP+Servlet+C3P0+Mysql 。涉及技術少,易於理解,適合 JavaWeb初學者 學習使用。 難度等級:簡單 技術棧 編輯器 IntelliJ IDEA 20 ...
  • 給出兩個 非空 的鏈表用來表示兩個非負的整數。其中,它們各自的位數是按照 逆序 的方式存儲的,並且它們的每個節點只能存儲 一位 數字。 如果,我們將這兩個數相加起來,則會返回一個新的鏈表來表示它們的和。 您可以假設除了數字 0 之外,這兩個數都不會以 0 開頭。 示例: 輸入:(2 -> 4 -> ...
  • 一. 反射 反射的概念是由Smith在1982年首次提出的,主要是指程式可以訪問、檢測和修改它本身狀態或行為的一種能力(自省)。這一概念的提出很快引發了電腦科學領域關於應用反射性的研究。它首先被程式語言的設計領域所採用,併在Lisp和麵向對象方面取得了成績。 python面向對象中的反射:通過字元 ...
  • [TOC] 本文內所有實現的代碼均附在文末,有需要可以參考。~~(好奇寶寶們可以粘貼下來跑一下~~ 多線程程式評價標準 安全性: ​ 安全性就是不損壞對象。也就是保證對象內部的欄位的值與預期相同。 生存性: ​ 生存性是指無論什麼時候,必要的處理都一定能夠執行。失去生存性最典型的例子就是“死鎖”。 ...
  • 用vector實現鄰接表 vector <int> G[100]; //表示有100個頂點的圖的鄰接表 G[u].push_back(v); //從頂點u 向頂點v 畫邊,即在相當於創建一個二維數組G[100][i] //搜索與頂點u 相鄰的頂點v for( int i = 0; i < G[u]. ...
  • 作者:劉超 轉自【劉超的通俗雲計算】 什麼是雲計算 早在十年前,市場上就出現了很多和雲計算相關的崗位,當時正是雲計算技術最火熱的時代,不管是BAT還是華為等企業都開始佈局雲計算,於是OpenStack研發、容器研發、底層開發等相關崗位相應地也越來越多,雖然這幾年大數據和AI的風頭已經完全壓過了雲計算 ...
  • 前言 文的文字及圖片來源於網路,僅供學習、交流使用,不具有任何商業用途,版權歸原作者所有,如有問題請及時聯繫我們以作處理。 作者:李嘉圖 PS:如有需要Python學習資料的小伙伴可以加點擊下方鏈接自行獲取http://t.cn/A6Zvjdun 起因 今天有個朋友家裡wifi密碼忘了,沒有能連上的 ...
一周排行
    -Advertisement-
    Play Games
  • .Net8.0 Blazor Hybird 桌面端 (WPF/Winform) 實測可以完整運行在 win7sp1/win10/win11. 如果用其他工具打包,還可以運行在mac/linux下, 傳送門BlazorHybrid 發佈為無依賴包方式 安裝 WebView2Runtime 1.57 M ...
  • 目錄前言PostgreSql安裝測試額外Nuget安裝Person.cs模擬運行Navicate連postgresql解決方案Garnet為什麼要選擇Garnet而不是RedisRedis不再開源Windows版的Redis是由微軟維護的Windows Redis版本老舊,後續可能不再更新Garne ...
  • C#TMS系統代碼-聯表報表學習 領導被裁了之後很快就有人上任了,幾乎是無縫銜接,很難讓我不想到這早就決定好了。我的職責沒有任何變化。感受下來這個系統封裝程度很高,我只要會調用方法就行。這個系統交付之後不會有太多問題,更多應該是做小需求,有大的開發任務應該也是第二期的事,嗯?怎麼感覺我變成運維了?而 ...
  • 我在隨筆《EAV模型(實體-屬性-值)的設計和低代碼的處理方案(1)》中介紹了一些基本的EAV模型設計知識和基於Winform場景下低代碼(或者說無代碼)的一些實現思路,在本篇隨筆中,我們來分析一下這種針對通用業務,且只需定義就能構建業務模塊存儲和界面的解決方案,其中的數據查詢處理的操作。 ...
  • 對某個遠程伺服器啟用和設置NTP服務(Windows系統) 打開註冊表 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\NtpServer 將 Enabled 的值設置為 1,這將啟用NTP伺服器功 ...
  • title: Django信號與擴展:深入理解與實踐 date: 2024/5/15 22:40:52 updated: 2024/5/15 22:40:52 categories: 後端開發 tags: Django 信號 松耦合 觀察者 擴展 安全 性能 第一部分:Django信號基礎 Djan ...
  • 使用xadmin2遇到的問題&解決 環境配置: 使用的模塊版本: 關聯的包 Django 3.2.15 mysqlclient 2.2.4 xadmin 2.0.1 django-crispy-forms >= 1.6.0 django-import-export >= 0.5.1 django-r ...
  • 今天我打算整點兒不一樣的內容,通過之前學習的TransformerMap和LazyMap鏈,想搞點不一樣的,所以我關註了另外一條鏈DefaultedMap鏈,主要調用鏈為: 調用鏈詳細描述: ObjectInputStream.readObject() DefaultedMap.readObject ...
  • 後端應用級開發者該如何擁抱 AI GC?就是在這樣的一個大的浪潮下,我們的傳統的應用級開發者。我們該如何選擇職業或者是如何去快速轉型,跟上這樣的一個行業的一個浪潮? 0 AI金字塔模型 越往上它的整個難度就是職業機會也好,或者說是整個的這個運作也好,它的難度會越大,然後越往下機會就會越多,所以這是一 ...
  • @Autowired是Spring框架提供的註解,@Resource是Java EE 5規範提供的註解。 @Autowired預設按照類型自動裝配,而@Resource預設按照名稱自動裝配。 @Autowired支持@Qualifier註解來指定裝配哪一個具有相同類型的bean,而@Resourc... ...