Hibernate(四)

来源:http://www.cnblogs.com/xuweiweiailixing/archive/2017/04/28/6778209.html
-Advertisement-
Play Games

Hibernate的二級緩存 理解緩存定義: 緩存(Cache):電腦領域非常通用的概念。它介於應用程式和永久性數據存儲源(如硬碟上的文件或者資料庫)之間,其作用是降低應用程式直接讀寫永久性數據存儲源的頻率,從而提高應用的運行性能。緩存中的數據是數據存儲源中數據的拷貝。緩存的物理介質通常是記憶體。 ...


Hibernate的二級緩存

  • 理解緩存定義:
    • 緩存(Cache):電腦領域非常通用的概念。它介於應用程式和永久性數據存儲源(如硬碟上的文件或者資料庫)之間,其作用是降低應用程式直接讀寫永久性數據存儲源的頻率,從而提高應用的運行性能。緩存中的數據是數據存儲源中數據的拷貝。緩存的物理介質通常是記憶體。
  • 理解二級緩存的定義:
    • Hibernate中提供了兩個級別的緩存
      • 一級緩存是Session級別的緩存,它是屬於事務範圍的緩存。這一級別的緩存是由Hibernate管理的,一般情況下無需進行干預。
      • 二級緩存是SessionFactory級別的緩存,它是屬於進程範圍的緩存。
    • Hibernate的SessionFactory緩存可以分為兩類:
      • 內置緩存:Hibernate自帶的,不可拆卸。通常在Hibernate的初始化階段,Hibernate會把映射元數據和預定義的SQL語句放到SessionFactory的緩存中,映射元數據是映射文件中數據(*.hbm.xml文件中的數據)的複製,該內置緩存是只讀的。
      • 外置緩存(二級緩存):一個可排至的緩存插件,在預設情況下,SessionFactory不會啟用這個緩存插件。外置緩存中的數據是資料庫數據的複製,外置緩存的物理介質可以是記憶體或硬碟。
  • 使用Hibernate的二級緩存:
    • 適合放入二級緩存中的數據:
      • 很少被修改。
      • 不是很重要的數據,允許出現偶爾的併發問題。
    • 不適合放入二級緩存中的數據:
      • 經常被修改。
      • 財務數據,絕對不允許出現併發問題。
      • 與其他應用程式共用的數據。
  • Hibernate的二級緩存的架構

    

  • 二級緩存的併發訪問策略:
    • 兩個併發的事務同時訪問吃就吃的緩存的相同數據時,也有可能出現各類併發問題。
    • 二級緩存可以設定一下4中類型的併發訪問策略,每一種訪問策略對應一種事務的隔離級別。
      • 非嚴格讀寫(nonstrict-read-wirte):不保證緩存與資料庫中數據的一致性。提供Read Uncommited事務隔離級別。對於極少被修改,而且允許臟讀的數據,可以採用這種策略。
      • 讀寫型read-write):提供Read Committed數據隔離級別。對於經常讀但是很少被修改的數據,可以採用這種隔離烈性,因為它可以防止臟讀。
      • 事務型(transaction):僅僅在受管理環境下使用。它提供了Repeatable Read 事務隔離級別。對於經常讀但是很少被修改的數據,可以採用這種隔離級別,因為它可以防止臟讀和不可以重覆讀。
      • 只讀型(read-only):提供Serializable數據隔離級別。對於從來不會被修改的數據,可以採用這種訪問策略。
  • 管理Hibernate的二級緩存
    • Hibernate的二級緩存是進程或集群範圍內的緩存。
    • 二級緩存是可配置的插件,Hibernate允許選用以下類型的緩存插件:
      • EHCache:可作為進程分為內的緩存,存放數據的物理介質可以是記憶體或硬碟,對Hibernate的查詢緩存提供了支持。
      • OSCache:可作為進程範圍內的緩存,存放數據的物理介質可以是記憶體或硬碟,提供了豐富的緩存數據過期策略,對Hibernate的查詢緩存提供了支持。
      • SwarmCache:可作為集群範圍內的緩存,但是不支持Hibernate的查詢緩存。
      • JBossCache:可作為集群範圍內的緩存,支持Hibernate的查詢緩存。
    • 4種緩存插件的併發訪問策略
緩存插件 read-only nonstrict-read-write read-write transaction
EHCache  
OSCache  
SwarmCache    
JBossCache    

 

 

 

 

 

 

 

 

 

  • 使用Hibernate的二級緩存的步驟:
    • 加入二級緩存插件的jar包及配置文件。
      • backport-util-concurrent.jar
      • commons-logging.jar
      • ehcache-1.5.0.jar
      • ehcache.xml
    • 配置hibernate.cfg.xml
      • 配置啟動Hibernate的二級緩存
        • <!-- 啟用二級緩存 -->
          <property name="hibernate.cache.use_second_level_cache">true</property>

      • 配置二級緩存的提供商
        • <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
      • 配置那些類使用二級緩存
        • <!-- 配置那個類使用二級緩存 -->
          <class-cache usage="read-only" class="cn.hibernate3.demo4.Customer"/>

  • 二級緩存的示例:證明二級緩存的存在
    • 配置演示環境:實體類,對應的映射文件及核心配置文件
    • 實體類:
      • Customer.java
package cn.hibernate3.demo4;

import java.io.Serializable;
import java.util.HashSet;
/**
 * 客戶實體
 */
import java.util.Set;
public class Customer implements Serializable{
    private Integer cid;
    private String cname;
    //一個客戶有多個訂單
    private Set<Order> orders = new HashSet<Order>();
    public Integer getCid() {
        return cid;
    }
    public void setCid(Integer cid) {
        this.cid = cid;
    }
    public String getCname() {
        return cname;
    }
    public void setCname(String cname) {
        this.cname = cname;
    }
    public Set<Order> getOrders() {
        return orders;
    }
    public void setOrders(Set<Order> orders) {
        this.orders = orders;
    }
    
    
}
      • Order.java
package cn.hibernate3.demo4;

import java.io.Serializable;
/**
 * 訂單實體
 */
public class Order implements Serializable{
    private Integer oid;
    private String addr;
    //訂單屬於某一個客戶
    private Customer customer ;
    
    public Integer getOid() {
        return oid;
    }
    public void setOid(Integer oid) {
        this.oid = oid;
    }
    public String getAddr() {
        return addr;
    }
    public void setAddr(String addr) {
        this.addr = addr;
    }
    public Customer getCustomer() {
        return customer;
    }
    public void setCustomer(Customer customer) {
        this.customer = customer;
    }
    
    
}
    • 映射文件:
      • Customer.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- 引入約束 -->
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="cn.hibernate3.demo4.Customer" table="customer" lazy="true">
        <!-- 配置唯一標識 -->
        <id name="cid" column="cid">
            <generator class="native"/>
        </id>
        <!-- 配置普通屬性 -->
        <property name="cname" column="cname" type="java.lang.String"/>
        <!-- 建立映射 -->
        <!-- 配置集合 -->
        <!-- 
            set標簽中的name表示關聯對象的屬性名稱
                
         -->
        <set name="orders" cascade="save-update">
            <!-- key標簽中的column用來一對多的多的一方的外鍵 -->
            <key column="cno"/>
            <!-- 配置一個one-to-many -->
            <one-to-many class="cn.hibernate3.demo4.Order" />
        </set>
    </class>
</hibernate-mapping>
      • Order.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!-- 引入約束 -->
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="cn.hibernate3.demo4.Order" table="orders">
        <!-- 配置唯一標識 -->
        <id name="oid" column="oid">
            <generator class="native"/>
        </id>
        <!-- 配置普通屬性 -->
        <property name="addr" column="addr" type="java.lang.String"/>
        <!-- 建立映射 -->
        <!-- 
            many-to-one標簽
                屬性:
                    name:關聯對象的屬性名稱。
                    column:表中外鍵的名稱。
                    class:關聯對象的全路徑。
         -->
        <many-to-one name="customer"  column="cno" class="cn.hibernate3.demo4.Customer"></many-to-one>
    </class>
</hibernate-mapping>
    • 核心映射文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
    <!-- 配置資料庫的基本信息 -->
    <!-- 驅動的名稱 -->
    <property name="hibernate.connection.driver_class">
        com.mysql.jdbc.Driver
    </property>
    <!-- 訪問資料庫的url -->
    <property name="hibernate.connection.url">
        jdbc:mysql:///hibernate_day03
    </property>
    <!-- 用戶名 -->
    <property name="hibernate.connection.username">root</property>
    <!-- 密碼 -->
    <property name="hibernate.connection.password">root</property>
    <!-- 方言 -->
    <property name="hibernate.dialect">
        org.hibernate.dialect.MySQLDialect
    </property>
    <!-- C3P0連接池設定-->
    <!-- 使用c3po連接池  配置連接池提供的供應商-->
    <property name="connection.provider_class">
        org.hibernate.connection.C3P0ConnectionProvider
    </property>
    <!--在連接池中可用的資料庫連接的最少數目 -->
    <property name="c3p0.min_size">5</property>
    <!--在連接池中所有資料庫連接的最大數目  -->
    <property name="c3p0.max_size">20</property>
    <!--設定資料庫連接的過期時間,以秒為單位,
        如果連接池中的某個資料庫連接處於空閑狀態的時間超過了timeout時間,就會從連接池中清除 -->
    <property name="c3p0.timeout">120</property>
    <!--每3000秒檢查所有連接池中的空閑連接 以秒為單位-->
    <property name="c3p0.idle_test_period">3000</property>
    <!-- 可選配置 -->
    <!-- 顯示SQL -->
    <property name="hibernate.show_sql">true</property>
    <!-- 格式化SQL -->
    <property name="hibernate.format_sql">true</property>
    <!-- hbm:映射 2:to ddl:create drop alter -->
    <property name="hibernate.hbm2ddl.auto">update</property>
    <!-- 
        1—Read uncommitted isolation
        2—Read committed isolation
        4—Repeatable read isolation
        8—Serializable isolation
     -->
    <property name="hibernate.connection.isolation">4</property>
    
    <property name="hibernate.current_session_context_class">thread</property>
    
    <!-- 啟用二級緩存 -->
    <property name="hibernate.cache.use_second_level_cache">true</property>
    
    <!-- 配置使用的二級緩存提供商 -->
    <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
    
    
    
    <mapping resource="cn/hibernate3/demo4/Customer.hbm.xml" />
    <mapping resource="cn/hibernate3/demo4/Order.hbm.xml" />
    <!--
  


<class-cache usage="read-write" class="cn.hibernate3.demo4.Customer"/>
<class-cache usage="read-write" class="cn.hibernate3.demo4.Order"/>

<collection-cache usage="read-write" collection="cn.hibernate3.demo4.Customer.orders"/>




--> </session-factory> </hibernate-configuration>
    • 測試類
  @Test
    public void demo13(){
        Session session = HibernateUtils.openSession();
        Transaction tx = session.beginTransaction();

        Customer customer1 = (Customer) session.get(Customer.class, 1);
        System.out.println(customer1.getCname()); 
        tx.commit();
       
        
        session = HibernateUtils.openSession();
        tx = session.beginTransaction();
        Customer customer2 = (Customer) session.get(Customer.class, 1);
        System.out.println(customer2.getCname()); 
        
        tx.commit();
        session.close();
        
    }

    • 設置Customer類使用二級緩存。其核心配置文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
    <!-- 配置資料庫的基本信息 -->
    <!-- 驅動的名稱 -->
    <property name="hibernate.connection.driver_class">
        com.mysql.jdbc.Driver
    </property>
    <!-- 訪問資料庫的url -->
    <property name="hibernate.connection.url">
        jdbc:mysql:///hibernate_day03
    </property>
    <!-- 用戶名 -->
    <property name="hibernate.connection.username">root</property>
    <!-- 密碼 -->
    <property name="hibernate.connection.password">root</property>
    <!-- 方言 -->
    <property name="hibernate.dialect">
        org.hibernate.dialect.MySQLDialect
    </property>
    <!-- C3P0連接池設定-->
    <!-- 使用c3po連接池  配置連接池提供的供應商-->
    <property name="connection.provider_class">
        org.hibernate.connection.C3P0ConnectionProvider
    </property>
    <!--在連接池中可用的資料庫連接的最少數目 -->
    <property name="c3p0.min_size">5</property>
    <!--在連接池中所有資料庫連接的最大數目  -->
    <property name="c3p0.max_size">20</property>
    <!--設定資料庫連接的過期時間,以秒為單位,
        如果連接池中的某個資料庫連接處於空閑狀態的時間超過了timeout時間,就會從連接池中清除 -->
    <property name="c3p0.timeout">120</property>
    <!--每3000秒檢查所有連接池中的空閑連接 以秒為單位-->
    <property name="c3p0.idle_test_period">3000</property>
    <!-- 可選配置 -->
    <!-- 顯示SQL -->
    <property name="hibernate.show_sql">true</property>
    <!-- 格式化SQL -->
    <property name="hibernate.format_sql">true</property>
    <!-- hbm:映射 2:to ddl:create drop alter -->
    <property name="hibernate.hbm2ddl.auto">update</property>
    <!-- 
        1—Read uncommitted isolation
        2—Read committed isolation
        4—Repeatable read isolation
        8—Serializable isolation
     -->
    <property name="hibernate.connection.isolation">4</property>
    
    <property name="hibernate.current_session_context_class">thread</property>
    
    <!-- 啟用二級緩存 -->
    <property name="hibernate.cache.use_second_level_cache">true</property>
    
    <!-- 配置使用的二級緩存提供商 -->
    <property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
    
    
    
    <mapping resource="cn/hibernate3/demo4/Customer.hbm.xml" />
    <mapping resource="cn/hibernate3/demo4/Order.hbm.xml" />

  <!-- 配置那個類使用二級緩存-->
  <class-cache usage="read-write" class="cn.hibernate3.demo4.Customer"/>
  <class-cache usage="read-write" class="cn.hibernate3.demo4.Order"/>
  <!-- 集合緩存區 -->
  <collection-cache usage="read-write" collection="cn.hibernate3.demo4.Customer.orders"/>

</session-factory>
</hibernate-configuration>

 

  • 類緩存區的特點:緩存的是對象的散裝的數據。
@Test
    public void demo13(){
        Session session = HibernateUtils.openSession();
        Transaction tx = session.beginTransaction();

        Customer customer1 = (Customer) session.get(Customer.class, 1);
        Customer customer2 = (Customer) session.get(Customer.class, 1);
        System.out.println(customer1==customer2); 
        tx.commit();
        
        session = HibernateUtils.openSession();
        tx = session.beginTransaction();
        Customer customer3 = (Customer) session.get(Customer.class, 1);
        Customer customer4 = (Customer) session.get(Customer.class, 1);
        System.out.println(customer3 == customer4);
        
        System.out.println(customer1 == customer3);
        
        tx.commit();
        session.close();
        
    }

  • 集合緩存區的特點:緩存的是對象的id,需要依賴類緩存區的配置。      
@Test
    public void demo13(){
        Session session = HibernateUtils.openSession();
        Transaction tx = session.beginTransaction();

        Customer customer1 = (Customer) session.get(Customer.class, 1);
        System.out.println(customer1.getOrders().size());
        tx.commit();
        
        session = HibernateUtils.openSession();
        tx = session.beginTransaction();
        Customer custome2 = (Customer) session.get(Customer.class, 1);
        System.out.println(custome2.getOrders().size());
        
        tx.commit();
        session.close();
        
    }

  • list()方法和iterate()方法的區別
    • list()方法:會向二級緩存中存放數據,但是不會使用二級緩存中的數據。
      • 證明:list()方法會向二級緩存中存放數據。
  @Test
    //list()方法會向二級緩存中存放數據,但是不會使用二級緩存中的數據
    //證明list()方法會向二級緩存中存放數據
    public void demo13(){
        Session session = HibernateUtils.openSession();
        Transaction tx = session.beginTransaction();

        List<Customer> list = session.createQuery("from Customer").list();//發送SQL語句
        for (Customer customer : list) {
            System.out.println(customer.getCname());
        }
        
        tx.commit();
        
        session = HibernateUtils.openSession();
        tx = session.beginTransaction();
        
        Customer customer = (Customer) session.get(Customer.class, 1);//不發送SQL語句,從二級緩存中獲取
        System.out.println(customer.getCname());
        
        tx.commit();
        session.close();
        
    }

      • 證明:list()不會使用二級緩存中的數據。
  @Test
    //list()方法會向二級緩存中存放數據,但是不會使用二級緩存中的數據
    //證明list()方法不會使用二級緩存中的數據
    public void demo13(){
        Session session = HibernateUtils.openSession();
        Transaction tx = session.beginTransaction();

        List<Customer> list = session.createQuery("from Customer").list();//發送SQL語句
        for (Customer customer : list) {
            System.out.println(customer.getCname());
        }
        
        tx.commit();
        
        session = HibernateUtils.openSession();
        tx = session.beginTransaction();
        
        list = session.createQuery("from Customer").list();//發送SQL語句
         for (Customer customer : list) {
                System.out.println(customer.getCname());
        }
         
        tx.commit();
        session.close();
        
    }

    • iterate()方法:
      • 和list()方法一樣也能執行查詢操作。
      • list()方法執行的SQL語句包含實體類對象的數據表中的所有欄位。
      • iterate()方法執行SQL語句中僅包含實體類對應的數據表的id欄位。
      • 當遍歷結果集的時候,該方法先到session緩存及二級緩存中查看是否存在特定oid的對象,如果存在,就直接返回該對象,如果不存在,就通過相應的SQL select語句到資料庫中載入特定的實體對象。
      • 大多數情況下,應考慮使用list()方法執行查詢操作,iterate()方法僅在滿足以下條件對的場合,可以稍微提高查詢性能:
        • 要查詢的數據表中包含大量的欄位。
        • 啟用了二級緩存,且二級緩存中可能已經包含了待查詢的對象。
  @Test
    public void demo13(){
        Session session = HibernateUtils.openSession();
        Transaction tx = session.beginTransaction();
        
        //發送N+1條SQL去查詢
        Iterator<Customer> iterator = session.createQuery("from Customer").iterate();
        while(iterator.hasNext()){
            Customer customer = iterator.next();
            System.out.println(customer.getCname());
        }
        
        tx.commit();
        
        session = HibernateUtils.openSession();
        tx = session.beginTransaction();
        
        iterator = session.createQuery("from Customer").iterate();
        while(iterator.hasNext()){
            Customer customer = iterator.next();
            System.out.println(customer.getCname());
        }
         
        tx.commit();
        session.close();
        
    }

 

  •  一級緩存更新同步到二級緩存及二級緩存配置文件
    • 證明一級緩存更新同步到二級緩存
  @Test
    public void demo13(){
        Session session = HibernateUtils.openSession();
        Transaction tx = session.beginTransaction();
        
        Customer customer = (Customer) session.get(Customer.class, 1);
        customer.setCname("哈哈");
        
        tx.commit();
        
        session = HibernateUtils.openSession();
        tx = session.beginTransaction();
        
        Customer customer2 = (Customer) session.get(Customer.class, 1);
        System.out.println(customer2.getCname());
        
        
        tx.commit();
        session.close();
        
    }

    • 二級緩存的配置文件

  • 更新時間戳區
  @Test
    public void demo13(){
        Session session = HibernateUtils.openSession();
        Transaction tx = session.beginTransaction();
        
        Customer customer = (Customer) session.get(Customer.class, 1);
        session.createQuery("update Customer set cname='呵呵' where cid= 1").executeUpdate();
        
        tx.commit();
        
        session = HibernateUtils.openSession();
        tx = session.beginTransaction();
        
        Customer customer2 = (Customer) session.get(Customer.class, 1);
        System.out.println(customer2.getCname());
        
        
        tx.commit();
        session.close();
        
    }

  • 查詢緩存區
    • 比二級緩存功能更加強大,而且查詢緩存必須依賴二級緩存。
    • 二級緩存:對類或對象的緩存。
    • 查詢緩存:針對類中的屬性的緩存。
      • select c.cname from Customer c;
    • 查詢緩存的配置
      • 前提是二級緩存已經配置完畢。
      • 在核心配置文件中配置
        • <property name="hibernate.cache.use_query_cache">true</property>
      • 編寫代碼的時候,添加如下代碼(詳解示例):
        •                  
  @Test
    public void demo13(){
        Session session = HibernateUtils.openSession();
        Transaction tx = session.beginTransaction();
        
        Query query = session.createQuery("select c.cname from Customer c");
        query.setCacheable(true);
        List<Object> list = query.list();
        for (Object object : list) {
            System.out.println(object);
        }
        
        tx.commit();
        
        session = HibernateUtils.openSession();
        tx = session.beginTransaction();
        
        query = session.createQuery("select c.cname from Customer c");
        query.setCacheable(true);
        list = query.list();
        for (Object object : list) {
            System.out.println(object);
        }
        
        tx.commit();
        session.close();
        
    }
    

                 


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

-Advertisement-
Play Games
更多相關文章
  • NetMQ是ZeroMQ的C#移植版本,它是對標準socket介面的擴展。它提供了一種非同步消息隊列,多消息模式,消息過濾(訂閱),對多種傳輸協議的無縫訪問。本文記錄了NetMQ的源碼進行學習並分析理解。 ...
  • 1.1Spring框架的概述 1.1.1什麼是Spring Spring是分層的JavaSE和JavaEES一站式輕量級開源框架。 分層: SUN提供的EE的三層結構:web層、業務層、數據訪問層(持久層、集成層)。 Struts2是web層基於MVC設計模式框架。 Hibernate是持久層的一個 ...
  • 正則表達式是一個特殊的字元序列,它能幫助你方便的檢查一個字元串是否與某種模式匹配。 re 模塊使 Python 語言擁有全部的正則表達式功能。 compile 函數根據一個模式字元串和可選的標誌參數生成一個正則表達式對象。該對象擁有一系列方法用於正則表達式匹配和替換。 re 模塊也提供了與這些方法功 ...
  • 當我們的一個對象可能代表一個單一的實體,或者一個組合的實體,但是仍然需要通過同樣的方式被使用時,這種情形則適合使用組合模式的設計。 ...
  • 預計分數:100+50+50 實際分數:5+50+100 =.= 多重背包 (backpack.cpp/c/pas) (1s/256M) 題目描述 提供一個背包,它最多能負載重量為W的物品。 現在給出N種物品:對於第i類物品,一共有Ci件物品;對於每一件物品,重量為Wi,價值為Vi。 找出一種裝載方 ...
  • 知乎指南 知乎讓我增長了見識, 看到了很多真實故事, 喝了百樣的雞湯, 所以我決定以後不看知乎了 知乎給我的錯覺:階段性 第一周 我打開了新的大門, 很多有意思的段子, 看上去很有內涵, 不過都很老套 有很多故事, 大家似乎都願意講他們的故事, 看客很多, 會屏蔽666, 老鐵, 233之類的評論 ...
  • 裝飾器模式詳解地址 原文總結 定義: 在不必改變原類文件和使用繼承的情況下, 動態的擴展一個對象的功能. 通過創建一個包裝對象, 也就是裝飾來包裹真實的對象 部分詳解提示 看了一些文檔, 裝飾器模式非常依賴構造器 與 重寫方法 裝飾器模式的特點: 不改變原來的類 , 不使用繼承 , 動態擴展 流這塊 ...
  • 本篇博客我們繼續的來聊SpringMVC的東西,下方我們將會聊到js、css這些靜態文件的載入配置,以及伺服器推送的兩種實現方式。當然我們在伺服器推送時,會用到jQuery的東西,所以我們先聊一下如何載入靜態資源文件,然後我們再聊如何實現伺服器推送。 下方給出了兩種實現伺服器推送的方式,一種是SSE ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...