Oracle資料庫之第四篇

来源:https://www.cnblogs.com/haizai/archive/2019/09/30/11611751.html
-Advertisement-
Play Games

/* 授權命令 grant 許可權 to 用戶 授權可以授予多個許可權 grant connect,resource to baidu 收回許可權 revoke 許可權 from 用戶 revoke dba from baidu 創建用戶 分配表空間--指定用戶的預設表空間... ...


/*
      授權命令 grant 許可權 to 用戶
          授權可以授予多個許可權
          grant  connect,resource to baidu   
      收回許可權  revoke  許可權 from  用戶
          revoke dba from baidu
          
      創建用戶 分配表空間--指定用戶的預設表空間
         create  table p(..) 建表存在預設表空間
          --建表時候指定表空間 
         create table p(...) talebspace 表空間名
    */
    /*
     PlSql編程語言  procedure language 過程語言
          是在sql語句中加入一些處理過程的語句
          常見的條件表達式 if else  還有迴圈結構
     基本結構
        declare
           --聲明部分 理解為定義
              --聲明使用的變數
        begin
           --處理邏輯的代碼塊
        end;
    */
    --psSql簡單示例
    declare
       v_n number := 1; --聲明數值變數 賦值使用符號:=
       v_s varchar2(4) :='s'; --聲明字元類型變數
       emp_ename emp.ename%type ;-- 引用類型變數
       emp_row   emp%rowtype ;-- 記錄類型變數
    begin
       
       dbms_output.put_line('v_n====='||v_n); --輸出語句相當於sys out 
       dbms_output.put_line('v_s====='||v_s);
       
       select ename into emp_ename from emp where empno=7499; --使用into關鍵字賦值
       dbms_output.put_line('emp_ename====='||emp_ename);
       
       select  * into  emp_row    from emp where empno = 7499; --賦值記錄類型變數
       dbms_output.put_line('員工編號=='||emp_row.empno||'員工姓名'||emp_row.ename);
    end;
    /*
      plsql 的條件表達式判斷
      if .. 處理語句 else if ..處理語句
      -------------------------
      if .. then  
      elsif .. then  
      else  
      end if;   
    */
    ---使用條件表達式判斷員工的工資 使用漢字輸出
    declare
      
       emp_row   emp%rowtype ;-- 記錄類型變數
    begin
      
       select  * into  emp_row    from emp where empno = 7499; --賦值記錄類型變數
       --使用表達式判斷工資
       if emp_row.sal > 3000 then
          dbms_output.put_line('員工工資大於3000=='||emp_row.sal);
       elsif   emp_row.sal < 1000  then
          dbms_output.put_line('員工工資小於1000=='||emp_row.sal);
       else
           dbms_output.put_line('員工工資位於1000到3000之間=='||emp_row.sal);
       end if;
       
    end;

    /*
      迴圈結構
    第一種-----
      loop
        exit when 條件
      end loop;
    第二種 ---
      while 條件 loop
        
      end loop;
    第三種 ---
      for 變數  in  範圍 loop
        
      end loop;
    */
    -------使用迴圈輸出數字 1-----10
    /*
    第一種
      loop
        exit when 條件
      end loop;
    */
    declare
       v_n number :=1;
    begin
      
      loop 
        --只是用來判斷退出使用的,並不是相當於if()else{}
        exit when v_n>10 ;   --退出條件
        dbms_output.put_line(v_n);
        v_n:=v_n+1;   --自增
      end loop;
    end;
    /*
    第二種
      while 條件  loop
        
      end loop;
    */
    declare
       v_n number :=1;
    begin
      
      while v_n<11  loop
        dbms_output.put_line(v_n);
        v_n:=v_n+1;   --自增
      end loop;
    end;
    /*
      第三種
      for 變數 in 範圍 loop  變數的聲明和範圍的控制是由for迴圈自動執行
        
      end loop;
    */

    declare
    begin
      
      for i in 1..10  loop
        dbms_output.put_line(i);
      end loop;
    end;
    /*
      游標 游標  是用於接收查詢的記錄結果集 ResultSet 提示記錄使用.next()
      游標的使用步驟
         聲明游標 cursor 游標名 is select 語句 指定游標的記錄結果集
         打開游標  open  游標名
         提取游標  fetch 游標名 into 記錄類型變數 
         關閉游標  close cursor
      游標的兩個屬性  游標名%found     : 判斷它有找到
                      游標名%notfound  : 判斷它沒有找到
        if  emp_cursor%found then
           dbms_output.put_line('found');
         elsif  emp_cursor%notfound then
           dbms_output.put_line('notfound');
         elsif emp_cursor%notfound is null then
            dbms_output.put_line('null');
         end if;
    */
    --使用while迴圈結構演示游標
    declare
         --聲明游標
         cursor emp_cursor is select * from emp;
         --聲明記錄類型變數 用於接收游標提取的記錄
         emp_row  emp%rowtype; 
    begin
         --打開游標
         open emp_cursor; 
         --提取游標(判斷下一個是否有值)
         fetch emp_cursor into emp_row ;
         --有值就執行while迴圈
         while emp_cursor%found  loop
            dbms_output.put_line(emp_row.empno||'員工姓名'||emp_row.ename);
            --繼續提取游標(並判斷下一個是否有值)
            fetch emp_cursor into emp_row ;
         end loop;
         close emp_cursor;
    end;
    /*
     loop  
        exit when 游標提取不到
     end loop
    */
    declare
         --聲明游標
         cursor emp_cursor is select * from emp;
         --聲明記錄類型變數 用於接收游標提取的記錄
         emp_row  emp%rowtype; 
    begin
         --打開游標
         open emp_cursor; 
         loop
           fetch emp_cursor into emp_row;
           exit when emp_cursor%notfound;
             dbms_output.put_line(emp_row.empno||'員工姓名'||emp_row.ename);
         end loop;
         close emp_cursor;
    end;
    --使用游標提取某個部門的員工信息
    --聲明帶參數的游標信息
    declare
         --聲明游標
         cursor emp_cursor(dno number) is select * from emp where deptno = dno ;
         --聲明記錄類型變數 用於接收游標提取的記錄
         emp_row  emp%rowtype; 
    begin
         --打開游標 時候傳入參數
         open emp_cursor(10); 
         loop
           fetch emp_cursor into emp_row;
           exit when emp_cursor%notfound;
             dbms_output.put_line(emp_row.empno||'員工姓名'||emp_row.ename);
         end loop;
         close emp_cursor;
    end;
    /*
      錯誤信息開發中的異常
      資料庫中叫做 例外
            異常的分類 1.系統異常 系統定義好的異常
                           
                       2.自定義的異常
                         new 自定義類繼承Exception 自定義傳值(錯誤代碼,提示信息)
                         使用場景
                            不滿足某些特定業務場景,拋出自定義異常
            異常的處理
               java  try{}catche(IndexOutOfBoundException e){}catche(Exception e){}
               java  try{}catche(Exception e){} catche(IndexOutOfBoundException e){}--報錯
               資料庫可以捕捉處理異常
                     exception   關鍵字捕捉異常
                       when 異常類型 then 處理語句   判斷異常類型 處理異常
                            
    */
    --異常的簡單示例
    /*
      --除0的異常 除數為0
      --賦值錯誤
      
    */

    declare
      v_n number :=0;
      v_m number :=1;
      
    begin
      v_m:='s';  --將字元串賦值給數值變數
      v_m:= v_m/v_n;
    exception
      
      when zero_divide then 
        dbms_output.put_line('除數不能為0');
      when value_error then
        dbms_output.put_line('賦值有誤');

    end;
    ---處理太多記錄數異常
    declare
      
       emp_row   emp%rowtype ;-- 記錄類型變數
    begin
      
       select  * into  emp_row  from emp ; --賦值記錄類型
       
    exception
      
       when too_many_rows then
          dbms_output.put_line('太多記錄數'); 
        when others then    --others是最大範圍的異常 相當於java 的 Exception
         dbms_output.put_line('其他異常');
    end;
    /*
       需求 :使用游標查詢部門下的員工信息
              如果部門下沒有員工 報錯提示
       需要自定義異常 
       變數名  exception     --聲明自定義異常
              
    */
    declare
      
       cursor emp_cursor is select * from emp where deptno= 40;  --游標結果集不存在
        emp_row   emp%rowtype ;-- 記錄類型變數
       no_dept_emp  exception ;  --聲明自定義異常
    begin
       open emp_cursor;  --打開游標
        
           fetch emp_cursor into emp_row;
           if emp_cursor%notfound then
             --沒有員工  拋出錯誤異常
             raise no_dept_emp;
           end if;
       close emp_cursor;
    exception
       when no_dept_emp then 
         dbms_output.put_line('部門下麵沒人,快招人吧');
    end;

    /*
     
      存儲過程 是一段封裝好的代碼塊,過程是編譯好放在伺服器提供開發人員調用
      
              封裝的代碼塊意義:  提升開發效率  可以復用 誰用直接調用
                                  提升運行效率 一調用直接運行
       語法:create [or repalce]   procedure 過程名稱(參數名 out|in  參數類型) 
             as|is
                 --聲明變數的部分 
             begin
                 --處理過程語句代碼塊
             end;
       調用存儲過程
          在begin和end之間使用 過程名傳參調用
    */
    --存儲過程的簡單示例  使用存儲過程給某個員工增加工資100
    create or replace procedure add_sal(eno in number )
    as
      emp_sal number :=0;
    begin
      select sal into emp_sal from emp where empno = eno ;
      dbms_output.put_line('漲工資之前是===='||emp_sal);
      update emp set sal=sal+100 where empno = eno;
      select sal into emp_sal from emp where empno = eno ;
      dbms_output.put_line('漲工資之後是===='||emp_sal);
      commit;
    end;
    --------調用存儲過程
    declare
    begin
      add_sal(7499);
    end;
    /*
      使用存儲過程統計某個員工的年薪,年薪需要返回輸出列印
      in 類型輸入參數可以 省略 預設就是輸入參數
    */
    create or replace procedure count_sal(eno number,year_sal out number)
    as
    begin
      
        select sal*12+nvl(comm,0) into year_sal  from emp where empno=eno; --使用into賦值給輸出參數

    end;
    ----調用存儲過程計算年薪
    declare
      v_emp_sal number :=0;  
    begin
      count_sal(7499,v_emp_sal);
      dbms_output.put_line('年薪為=='||v_emp_sal);
    end;
    /*
      使用存儲過程 查詢出某個部門的員工信息
      某個部門應該接受一個in類型的輸入參數
      查詢到的部門員工多條記錄返回應該使用結果集 
      聲明游標 cursor 游標名 is select 語句指定結果集
      系統引用游標
       sys_refcursor 
       聲明系統引用游標  變數名 sys_refcursor;  --不需要指定結果集
       打開游標      open 系統引用游標 for select 語句  --使用for關鍵字裝入數據
    */
    create or replace procedure dept_emp(dno number,cusor_emp out sys_refcursor)
    as
    begin
      --根據傳進來的部門編號給游標裝入結果集數據
      open cusor_emp for select * from emp  where deptno = dno;   
    end;
    ----調用存儲過程查詢部門下的員工
    declare
       cursor_emp sys_refcursor;  --聲明系統引用游標傳參使用
       emp_row emp%rowtype ;--記錄類型變數
    begin
      dept_emp(10,cursor_emp);
      --提取游標中的數據
      loop
        fetch cursor_emp into emp_row;
        exit when cursor_emp%notfound;
        dbms_output.put_line('編號'||emp_row.empno||'姓名'||emp_row.ename);
      end loop;
      close cursor_emp; 
    end;
    /*
      存儲函數 是一段封裝好的代碼塊,是編譯好放在伺服器提供開發人員調用
      
              封裝的代碼塊意義:  提升開發效率  可以復用 誰用直接調用
                                  提升運行效率 一調用直接運行
                                  
       語法:create [or repalce]   function 函數名稱(參數名 out|in  參數類型) return 數據類型
                                                    in 代表傳入參數,out 代表傳出參數                        
             as|is
                 --聲明變數的部分 
             begin
                 --處理過程語句代碼塊
                 --return 變數
             end;
       調用存儲函數
          在begin和end之間使用 函數名傳參調用 函數必須使用變數接收 返回值
      
    */
    --使用存儲函數統計某個員工的年薪
    create or replace function count_emp_sal(eno number,year_sal out number) return number
    as
      v_sal number :=0;
    begin
      
        select sal*12+nvl(comm,0) into year_sal  from emp where empno=eno; --使用into賦值給輸出參數
        return v_sal;
    end;
    --不帶out類型輸出參數統計年薪
    create or replace function count_sal_noout(eno number) return number
    as
      v_sal number :=0;
    begin
      
        select sal*12+nvl(comm,0) into v_sal  from emp where empno=eno; --使用into賦值給輸出參數
        return v_sal;
    end;
    --調用函數統計年薪
    declare
      emp_sal number:=0;
      total_sal number :=0;
    begin
       --total_sal := count_emp_sal(7499,emp_sal);
       total_sal := count_sal_noout(7499);
       dbms_output.put_line(emp_sal);--0
       dbms_output.put_line(total_sal); --統計後年薪
    end;
    /*
       存儲函數和過程的區別
       
           1.創建的關鍵字  procedure   funciton
           2.創建函數 必須使用return 聲明函數的返回變數數據類型
           3.在函數的方法體內 必須使用return 返回一個變數
           4.函數的調用 必須有變數接收返回值
           5.函數可以用在select 查詢語句中  select emp.*,count_sal_noout(empno) from emp;
       
       存儲函數和過程使用場景
           開發規範 java代碼待用過程 過程是用來處理業務邏輯代碼
           如果邏輯中需要用到一些功能性的封裝,可以調用函數
           90%情況下 函數和過程通用 過程可以調用函數,函數同樣可以調用過程
       
    */

    /*
      觸發器 是一個監視器,監視對錶中數據的操作
           如果對數據的操作滿足觸發器的執行條件,
           觸發器會自動運行
      觸發器語法:
          create or repalce trigger 觸發器名稱
          after|before   --觸發器執行時機
          insert|update|delete  --監視的動作
          on 表名       --表級觸發器
          declare
          begin          
          end;
       行級觸發器                    insert        update        delete
           :new   動作之後的記錄   要插入的記錄   修改後的記錄     空
           :old   動作之前的記錄      空          原始的記錄     原始的記錄
           
    */
    --創建觸發器監視表,如果表中有數據插入,輸出一個歡迎語句
    create or replace trigger insert_trigger
    after
    insert
    on p
    declare
       
    begin
       dbms_output.put_line('歡迎加入!');
    end;
    ----插入數據測試效果
    insert into p values(1,'zs');
    commit;
    --插入數據不能在休息日插入數據
    --休息日 周六和周日
    /*
     raise_application_error(v1,v2) v1錯誤代碼  v2是提示語句
                                      -20000 -20999 
    */
    create or replace trigger insert_no_work
    before
    insert
    on p
    declare
       v_day varchar2(10) ;
    begin
      --獲取到當前星期
      select to_char(sysdate,'day') into v_day from dual;
      --判斷星期是否在休息日
      if trim(v_day)  in ('saturday','sunday') then
      --如果休息 錯誤提示
         raise_application_error(-20001,'不能休息日插入數據');
      end if;
    end;
    ----插入數據測試效果
    insert into p values(1,'zs');
    commit;

    --使用觸發器監視表中數據修改,不能做降低工資的操作
    create or replace trigger can_not_low
    before
    update
    on emp
    for each row --行級觸發器
    declare
      
    begin
      --獲取到原始記錄的工資  --獲取修改後的工資
      if :old.sal > :new.sal then
      --談錯誤框提示
      raise_application_error(-20002,'不能降低工資');
      end if;
    end;
    --修改員工的工資測試觸發器
    update emp set sal=sal-1 where empno=7499;

    /*
      觸發器實際應用 
          使用觸發器實現 插入數據的id 自增長 面試題
    **/

    create or replace trigger auto_increment_id
    before    
    insert
    on test_trigger
    for each row 
    declare 
    begin
      --補全將要插入記錄的id
      --補全的id 是自增長的數值 如果沒有提前創建序列,需要提前創建序列   --創建序列  create sequence order_sequence 
      select order_sequence.nextval into :new.pid from dual;
    end;

    insert into test_trigger(pname,phone) values('zs','1234566');
    commit;

    package baidu;

import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import org.junit.Test;

import oracle.jdbc.OracleCallableStatement;
import oracle.jdbc.OracleTypes;

public class TestJdbc {

     String driverClass = "oracle.jdbc.driver.OracleDriver";
     String url ="jdbc:oracle:thin:@192.168.17.128:1521:orcl";
     String user= "baidu_03";
     String password = "baidu_03";
     /*
      *測試jdbc連接資料庫
      *
      * */
     @Test
     public void querEmp(){
         try{
         //載入驅動
         Class.forName(driverClass);
         //獲取鏈接
         Connection con = DriverManager.getConnection(url, user,password);
         //獲取預編譯的statement
         PreparedStatement pst= con.prepareStatement("select * from emp");
         //執行查詢
         ResultSet rs =  pst.executeQuery();
         //處理結果
         while(rs.next()){
             System.out.println(rs.getInt(1)+"員工姓名"+rs.getString("ename"));
         }
         rs.close();
         con.close();
         //關閉連接
         }catch(Exception e){
             e.printStackTrace();
         }
         
     }
     /*存儲過程的調用
      * {call <procedure-name>[(<arg1>,<arg2>, ...)]}
        add_sal(eno number,addsal number)
      * */
     @Test
     public void callAddSal(){
         try{
         //載入驅動
         Class.forName(driverClass);
         //獲取鏈接
         Connection con = DriverManager.getConnection(url, user,password);
         //獲取預編譯的statement
         CallableStatement pst= con.prepareCall("{call add_sal(?,?)}");
         pst.setInt(1, 7499);
         pst.setInt(2, 1000);
         //執行查詢
         pst.execute();
         con.close();
         //關閉連接
         }catch(Exception e){
             e.printStackTrace();
         }
         
     }
     
     /*存儲過程的調用
      * {call <procedure-name>[(<arg1>,<arg2>, ...)]}
        count_yearsal(eno number,total_year_sal out number)
      * */
     @Test
     public void callCountSal(){
         try{
         //載入驅動
         Class.forName(driverClass);
         //獲取鏈接
         Connection con = DriverManager.getConnection(url, user,password);
         //獲取預編譯的statement
         CallableStatement pst= con.prepareCall("{call count_yearsal(?,?)}");
         pst.setInt(1, 7499);
         //註冊輸出參數
         pst.registerOutParameter(2, OracleTypes.NUMBER);
         //執行查詢
         pst.execute();
         int total =  pst.getInt(2);
         System.out.println(total);
         con.close();
         //關閉連接
         }catch(Exception e){
             e.printStackTrace();
         }
         
     }
     /*
      * pro_dept_emp(dno number,dept_emp out sys_refcursor)
      * */
     @Test
     public void callProEmp(){
         try{
         //載入驅動
         Class.forName(driverClass);
         //獲取鏈接
         Connection con = DriverManager.getConnection(url, user,password);
         //獲取預編譯的statement
         CallableStatement pst= con.prepareCall("{call pro_dept_emp(?,?)}");
         pst.setInt(1, 10);
         //註冊輸出參數
         pst.registerOutParameter(2, OracleTypes.CURSOR);
         //執行查詢
         pst.execute();
         OracleCallableStatement ocs = (OracleCallableStatement)pst;
         ResultSet rs =  ocs.getCursor(2);
         while(rs.next()){
             System.out.println(rs.getInt(1)+"員工姓名"+rs.getString("ename"));
         }
         rs.close();
         ocs.close();
         pst.close();
         con.close();
         //關閉連接
         }catch(Exception e){
             e.printStackTrace();
         }
         
     }
}

public void show4(){
         try {
             
             Class.forName(driverClass);
             Connection con = DriverManager.getConnection(url, user,password);
             CallableStatement pst= con.prepareCall("{?= call count_sal_noout(?)}");

             //給第二個參數賦值
             pst.setLong(2, 7499);
            // stat2.setLong(2, empno);

             //聲明第一個參數的類型
             pst.registerOutParameter(1, OracleTypes.NUMBER);
             pst.execute();
             OracleCallableStatement ocs = (OracleCallableStatement)pst;
             NUMBER num = ocs.getNUMBER(1);
             System.out.println(num);
//             long i = pst.getLong(1);
//             System.out.println(i);
         
             con.close();
             
         } catch (Exception e) {
             e.printStackTrace();
         }
     }
/*

 


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

-Advertisement-
Play Games
更多相關文章
  • IE瀏覽器遠程代碼執行高危漏洞(CVE-2019-1367)加固遇到的問題 一、背景介紹 Internet Explorer,是微軟公司推出的一款網頁瀏覽器。用戶量極大。9月23日微軟緊急發佈安全更新,修複了一個影響IE瀏覽器的遠程代碼執行漏洞。由谷歌威脅分析小組發現此漏洞,據稱該漏洞已遭在野利用。 ...
  • 博主做過比較多項目的archive腳本編寫,對於這種刪除數據的腳本開發,肯定是一開始的話用最簡單的一個delete語句,然後由於部分表數據量比較大啊,索引比較多啊,會發現刪除數據很慢而且影響系統的正常使用。然後就對delete語句進行按均勻數據量分批delete的改寫,這樣的話,原來的刪除一個表用一 ...
  • 所謂事務是用戶定義的一個數據操作序列,這些操作可作為一個完整的工 作單元,要麼全部執行,要麼全部不執行,是一個不可分割的工作單位。 事務中的操作一般是對數據的更新操作,包括增、刪、改。 ...
  • [TOC] # 1. 前言 在資料庫安全的生命周期中, 包括: 保護、檢測、響應和補救。檢測的核心就是審計(Audit)。有些情況下,審計不僅僅用於檢測不好的行為,也作為對整個資料庫的行為進行監控而存在。審計能夠告訴我們誰訪問了什麼、在什麼地方、什麼時間、採用了何種方式。 有效的審計不僅僅意味著安全 ...
  • 背景 昨天,關於價格詳情介面又來了一個小需求,而且有點特別。價格顯示:改為保留兩位小數,沒錯,就是保留兩位小數。大家是不是想說這沒啥特別的。。。資料庫都有函數搞定了。例如四捨五入的ROUND(x,d),直接截取的TRUNCATE(x,d),還可以利用類型轉換CONVERT(value,type)等等 ...
  • -- mysql安裝 -- https://www.mysql.com/downloads/ 終端執行命令 (可參考本筆記MySQL環境搭建-mysql 8.0.13 解壓版安裝配置方法圖文教程) mysql 教學demo --命令行輸指令創建表 http://www.forta.com/books ...
  • Aborted_clients和 Aborted_connects狀態變數詳解 By:授客 QQ:1033553122 狀態變數定義 Aborted_clients 因客戶端消亡時未恰當的關閉連接而引起的被中斷連接數 The number of connections that were abort ...
  • 今天我們來看一下淘寶、美團和滴滴的大數據平臺,一方面進一步學習大廠大數據平臺的架構,另一方面也學習大廠的工程師如何畫架構圖。通過大廠的這些架構圖,你就會發現,不但這些知名大廠的大數據平臺設計方案大同小異,架構圖的畫法也有套路可以尋覓。 淘寶大數據平臺 淘寶可能是中國互聯網業界較早搭建了自己大數據平臺 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...