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
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...