Hibernate學習筆記

来源:https://www.cnblogs.com/Simon-Qi/archive/2018/11/17/9976506.html
-Advertisement-
Play Games

一、Hibernate簡介(網上搜的,理解性地看看) 1.概念:Hibernate是持久層(數據訪問層)的框架,對JDBC進行了封裝,是對資料庫訪問提出的面向對象的解決方案。 2.作用:使用Hibernate可以直接訪問對象,Hibernate自動將訪問轉換成SQL執行,從而實現簡介訪問資料庫的目的 ...


一、Hibernate簡介(網上搜的,理解性地看看)

  1.概念:Hibernate是持久層(數據訪問層)的框架,對JDBC進行了封裝,是對資料庫訪問提出的面向對象的解決方案。

  2.作用:使用Hibernate可以直接訪問對象,Hibernate自動將訪問轉換成SQL執行,從而實現簡介訪問資料庫的目的,簡化了數據訪問層的代碼開發。

  3.JDBC、MyBatis對比:

    a)JDBC需要編寫大量SQL語句,以及對大量參數賦值。需要手動將ResultSet結果集轉換成實體對象;SQL中包含特有函數,無法移植。而Hibernate可以自動生成SQL和參數賦值,自動將ResultSet結果集轉換成實體對象,採用一致的方法對資料庫操作,移植性好。

    b)MyBatis與Hibernate都對JDBC進行了封裝,採用ORM思想解決了Entity和資料庫的映射問題。MyBatis採用SQL與Entity映射,對JDBC封裝程度比較輕,需要自己寫SQL,更具有靈活性;而Hibernate採用資料庫與Entity映射,對JDBC封裝程度比較重,自動生成SQL,對於基本的操作,開發效率高。

  4.原理:Hibernate框架是ORM思想的一種實現,解決了對象和資料庫映射問題。我們可以通過Hibernate提供的一系列API,允許我們直接訪問實體對象,然後其根據ORM映射關係,轉換成SQL並且執行,從而達到訪問資料庫的目的。

    ORM:Object Relation Mapping,即對象關係映射,指Java對象和關係資料庫之間的映射。

    ORM思想:將對象與資料庫數據進行相互轉換的思想,不同的框架實現ORM的手段不同,但更多的是採用配置+反射的方式來實現ORM。

  5.框架體繫結構

    a)主配置文件,通常為“hibernate.cfg.xml”,用於配置資料庫連接參數,框架參數,已經映射關係文件。

    b)實體類,與資料庫對應的Java類型,用於封裝資料庫記錄的對象類型。

    c)映射關係文件,通常為“實體類.hbm.xml”,並放置在與實體類相同的路徑下。該文件是指定實體類和資料庫的對應關係,以及類中屬性和表中欄位之間的對應關係。

    d)底層API,對映射關係文件的解析,根據解析出來的內容,動態生成SQL語句,自動將屬性和欄位映射。

二、Hibernate使用

  1.常用API

    Configuration:負責載入主配置文件信息,同時載入映射關係文件信息

/**
到src下找到名稱為hibernate.cfg.xml的配置文件,創建對象,把配置文件放到對象中(載入核心配置文件)
*/
Configuration cfg = new Configuration().configure();

//載入指定的核心配置文件
Configuration cfg = new Configuration().configure("com/konrad/hibernate.cfg.xml");

//載入指定的映射配置文件
cfg.addResource("com/konrad/entity/User.hbm.xml");
複製代碼

    SessionFactory:負責創建Session對象,根據核心配置文件的配置,在資料庫創建對應的表,一個項目只應有一個此對象

private static final SessionFactory sessionFactory;
    
    static{
        try{
            //配置文件的方式
            sessionFactory = new Configuration().configure("hibernate.cfg.xml")  
                    .buildSessionFactory();  
            /* 註解的方式
            sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();   
            */
        }catch (Throwable ex){
            ex.printStackTrace();
            throw new ExceptionInInitializerError(ex);
        }
    }    
複製代碼

    Session:資料庫連接會話,負責執行增刪改操作

    Transaction:負責事務控制

    Query:負責執行特殊查詢

  2.使用步驟

    a)導入Hibernate包,以及資料庫驅動包。(開發需要的包不知道的自行百度,也可以通過Maven構建)

    b)引入Hibernate主配置文件hibernate.cfg.xml

       - <session-factory>標簽要寫在<hibernate-configuration>標簽內部

    c)創建實體類

    d)創建映射關係文件(也可以通過註解的方式進行映射,這樣就不需要xml映射文件)

      - <class>標簽中的name屬性寫的是類的全路徑

       - <id>和<property>標簽中的name屬性寫的是實體類中的屬性名稱

       - <id>和<property>標簽中,column可以省略,若省略就是以name屬性值生成表的欄位名

         - <property>標簽中還有一個type屬性,用於生成表的欄位的類型,但是使用比較少

    e)使用Hibernate API執行增刪改查等操作

      f)額外說明:註解方式的應用

     - 如果實體類屬性名與表欄位名稱不同時,要麼都註解在屬性前,要麼都註解在get方法前。

      - 如果實體類屬性名和表欄位名稱統一,可以部分註解在屬性前,部分註解在get方法前。

      - 若都不註解,則預設表欄位名和屬性名一致

      - 若實體類中某個屬性不需要存進資料庫表,使用@Transient進行註解即可

      - 表名稱可以在實體類前進行註解

      - 所有註解都在javax.persistence包下

  3.映射類型

    a)Java類型:映射關係文件中,配置屬性和欄位關係時,可以在type屬性上指定Java類型,用於做Java屬性和資料庫欄位的轉換。指定時需要完整的類型名,如java.lang.String。

    b)自定義類型:當某些特殊類型,Java預置類型無法支持,需要自定義一個類來實現,這個類要求實現介面UserType。比如boolean類型,資料庫中一般存char(1),存y/n或者t/f,Java預置類型無法支持boolean類型的配置,需要自定義。

    c)Hibernate也提供了一些類型來支持這些映射,提供了7中映射類型,書寫時全是小寫。

      

三、Hibernate的主鍵生成方式

   1.sequence:採用序列生成主鍵,適用於Oracle資料庫。

<generator class="sequence">
    <param name="sequence">序列名</param>
</generator>

  2.identity:採用資料庫自增長機制生成主鍵,適用於Oracle之外的其他資料庫。

<generator class="identity">
</generator>

  3.native:根據當前配置的資料庫方言,自動選擇sequence或者identity。

<generator class="native">
    <param name="sequence">序列名</param>
</generator>

  4.increment:不是採用資料庫自身的機制來生成主鍵,而是Hibernate提供的一種生成主鍵的方式,它會獲取當前表中主鍵的最大值,然後加1作為新的主鍵。PS:這種方式在併發量高時存在問題,可能會產生重覆的主鍵,因此不推薦。

<generator class="increment">
</generator>

  5.assigned:Hibernate不負責生成主鍵,需要程式員自己處理主鍵的生成。

<generator class="assigned">
</generator>

  6.uuid/hilo:採用uuid或hilo演算法生成一個主鍵值,這個主鍵值是一個不規則的長數字。PS:這個方式生成的主鍵可以保證不重覆,但是沒有規律,因此不能按主鍵排序。

<generator class="uuid">
</generator>

四、一些使用的代碼實例

  1.核心配置文件

<?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="connection.driver_class">com.mysql.jdbc.Driver</property>  
        <property name="connection.url">jdbc:mysql://localhost:3306/test</property>  
        <property name="connection.username">root</property>  
        <property name="connection.password"></property>  
        <property name="javax.persistence.validation.mode">none</property>   
        <!-- 支持mysql方言 -->
        <property name="dialect">org.hibernate.dialect.SQLServerDialect</property>  
          
        <property name="current_session_context_class">thread</property>  
  
        <!-- 配置是否在控制台顯示sql語句 -->
        <property name="show_sql">true</property>  
        <!-- 配置是否按照格式顯示sql語句 -->
        <property name="format_sql">true</property>  
        <!-- 配置生成策略
        update:如果沒有表創建之,有表就更新表
     -->
        <property name="hbm2ddl.auto">update</property>  
        
        <!-- 引入映射配置文件 必須的 -->
    <mapping resource="com/maven/test/hibernate/entity/PersonEntity.hbm.xml"/>
    <!-- 若使用註解的方式,需要如下配置 --> <!-- <mapping class="com.maven.test.hibernate.entity.PersonEntity">-->

</session-factory> </hibernate-configuration>
複製代碼

  2.關係映射XML文件dtd約束:

<!DOCTYPE hibernate-configuration PUBLIC  
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"  
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

  3.HibernateUtil類:提供獲取Session和關閉Session的方法。Hibernate中我們使用ThreadLocal管理Session。 

package com.maven.test.hibernate.util;

import org.apache.log4j.Logger;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateUtil {
    public static final ThreadLocal<Session> SESSIONMAP = new ThreadLocal<Session>(); 
    private static final SessionFactory sessionFactory;
    private static final Logger LOGGER = Logger.getLogger(HibernateUtil.class);
    
    static{
        try{
            LOGGER.debug("HibernateUtil.static - loading config");
            sessionFactory = new Configuration().configure("hibernate.cfg.xml")  
                    .buildSessionFactory();  
            LOGGER.debug("HibernateUtil.static - end");
        }catch (Throwable ex){
            ex.printStackTrace();
            LOGGER.error("HibernateUtil error: ExceptionInInitializerError");
            throw new ExceptionInInitializerError(ex);
        }
    }
    
    private HibernateUtil(){}
    
    public static Session getSession() throws HibernateException{
        Session session  = SESSIONMAP.get();
        if(session == null){
            session = sessionFactory.openSession();
            SESSIONMAP.set(session);
        }
        return session;
    }
    
    
    public static void closeSession() throws HibernateException{
        Session session = SESSIONMAP.get();
        SESSIONMAP.set(null);
        
        if(session != null)
            session.close();
    }
    
}
複製代碼

  4.添加操作

PersonEntity person = new PersonEntity();
person.setId(100);
person.setName("Konrad");        
        
Session session = HibernateUtil.getSession();
Transaction tx = session.beginTransaction();
        
session.save(person);
        
tx.commit();
HibernateUtil.closeSession();
複製代碼

  5.刪除操作

Session session = HibernateUtil.getSession();
session.beginTransaction();

PersonEntity person = session.get(PersonEntity,class, 1);
session.delete(person);

session.getTransaction().commit();
HibernateUtil.closeSession();
複製代碼

  6.查詢操作

Session session = HibernateUtil.getSession();
session.beginTransaction();

//單行查詢,根據主鍵查詢
PersonEntity p = session.get(PersonEntity.class, 1)

//多行查詢    
@SuppressWarnings("unchecked")
List<PersonEntity> personList = session.createQuery("select p from PersonEntity p").list();
        
for(PersonEntity person : personList){
     System.out.println(person);
}

session.getTransaction().commit();
HibernateUtil.closeSession();
複製代碼

  7.修改操作

Session session = HibernateUtil.getSession();
session.beginTransaction();
        
PersonEntity person = session.get(PersonEntity.class, 1);
person.setName("haha");
session.update(person);

session.getTransaction().commit();
HibernateUtil.closeSession();
複製代碼

五、Hibernate進階

  1.一級緩存

    a)Hibernate創建每個Session對象時,都會給該Session對象分配一塊獨立的緩存區,用於存放該Session查詢出來的對象,這個分配給Session的緩存區稱之為一級緩存,也叫Session級緩存。Session的save、update、delete操作會觸發緩存更新。

    b)使用一級緩存的原因是,Session取數據時,會優先向緩存區取數據,如果存在數據則直接返回,不存在才會去資料庫查詢,從而降低了資料庫訪問次數,提升代碼性能。

    c)一級緩存是預設開啟的,使用Hibernate API查詢時會自動使用。

    d)session.evict(obj) - 將obj從一級緩存中移除

       session.clear() - 清除一級緩存中所有的obj

       session.close() - 關閉session,釋放緩存空間  

  2.Hibernate中,實體對象的3中狀態:臨時態、持久態、游離態

    a)臨時態:臨時態的對象可以被垃圾回收,未進行持久化,未與session關聯

     - 通過new創建的對象為臨時態

      - 通過delete方法操作的對象將轉變為臨時態

    b)持久態:持久態對象垃圾回收器不能回收,進行了持久化,與session關聯。實際上持久態對象存在於session緩存中,由session負責管理;持久態對象的數據可以自動更新到資料庫中,在調用session.flush()時執行,而提交事務時會使用session.flush(),因此提交事務也會觸發同步

     - 通過get、load、list、iterate方法查詢到的對象為持久態

      - 通過save、update方法操作的對象轉變為持久態

    c)游離態:游離態的對象可以被垃圾回收,進行過持久化,但已與session解除了關聯

      - 通過session的evict、clear、close方法操作的對象會轉變為游離態

 

      

  3.延遲載入

    a)使用某些Hibernate方法查詢數據時,Hibernate返回的只是一個空對象(除id外屬性都為null),並沒有真正查詢資料庫。而在使用這個對象時才會觸發查詢資料庫,並將查詢到的數據註入到這個空對象中,這種將查詢時機制推遲到對象訪問時的機制稱之為延遲載入。  

    b)延遲載入可以提升記憶體資源的使用率,降低對資料庫的訪問次數。

    c)session.load()、query.iterate()、關聯映射中對關聯屬性的載入,以上屬於採用延遲載入的方法。

    d)採用具有延遲載入機制的操作,需要避免session提前關閉。

  4.關聯映射

    a)關聯映射即使用Hibernate操作一張表時,它可以通過配置關係自動地幫助我們操作另一張表

    b)關聯查詢出關係表的數據、關聯新增/修改關係表的數據、關聯刪除關係表的數據

    c)類型:一對多關聯、多對一關聯、多對多關聯、一對一關聯、繼承關聯

     一對多關聯實現步驟:

      - 在“一”方實體類添加集合屬性,以及get、set方法

      - 在“一”方hbm文件中配置關聯關係

<!-- 
set指定屬性類型為Set集合
name指定屬性名
-->
<set name="courses">
    <!-- column指定了關聯欄位名-->
    <key column="stu_id"/>
    <!-- one-to-many指定了關聯關係,class指定了另一方類型-->
    <one-to-many class="com.konrad.entity.Course" />
</set>
複製代碼

     關聯實現步驟:

      - 在“多”方實體類添加屬性,以及get、set方法

      - 在“多”方hbm文件中配置關聯關係

 <!-- many-to-one指定了關聯關係,
name指定了屬性名,
column指定了關係欄位,
class指定了另一方類型-->
<many-to-one name="student" column="stu_id" class="com.konrad.entity.Student" />

     多關聯實現步驟:

      - 在雙方方實體類添加集合屬性,以及get、set方法

      - 在雙方hbm文件中配置關聯關係

Student映射配置文件
<!-- 配置學生對應的教師集合 name屬性:配置教師實體類中的Set集合屬性的名稱 table屬性:表示中間表的名稱 --> <set name="teachers" table="t_stu_tea"> <!-- column屬性:配置當前映射文件在中間表中外鍵名稱 --> <key column="sid"></key> <!-- class屬性:配置另一個張表的實體類全路徑名稱 colunm屬性:配置一張表在中間表中的外鍵名稱 --> <many-to-many class="cn.konrad.entity.Teacher" column="tid"></many-to-many> </set>
複製代碼
Teacher映射配置文件
<!-- 
            配置教師對應的學生集合
            name屬性:配置學生實體類中的Set集合屬性的名稱
            table屬性:中間表的名稱
         -->
        <set name="students" table="t_stu_tea">
            <!-- column屬性:配置當前映射文件在中間表中外鍵名稱    -->
            <key column="tid"></key>
            <!-- 
                class屬性:配置另一個張表的實體類全路徑名稱
                colunm屬性:配置一張表在中間表中的外鍵名稱
             -->
            <many-to-many class="cn.konrad.entity.Student" column="sid"></many-to-many>
        </set>
複製代碼

  對一關聯實現步驟:

      - 在雙方方實體類添加屬性,以及get、set方法

 

      - 在雙方hbm文件中配置關聯關係

Wife映射關係文件
<!-- property-ref屬性:指定使用被關聯實體主鍵以外的欄位作為關聯欄位 --> <one-to-one name="husband" class="cn.konrad.entity.Husband" property-ref="wife"></one-to-one>
Husband映射配置文件
<id name="hid" column="hid">
            <!-- 2.1配置主鍵的策略 
                foreign屬性:表示主鍵參照外鍵生成
            -->
            <generator class="foreign">
                <!-- param標簽配置當前實體類中引用的對方實體對象的引用名 -->
                <param name="property">wife</param>
            </generator>
        </id>
        <!-- 3.配置實體類與表的其他屬性 
            name屬性:實體類的屬性名稱
            column屬性:表中的列名
           Contrained=true表示生產外鍵
        -->
        <property name="hname" column="hname"></property>
        <one-to-one name="wife" class="cn.konrad.entity.Wife" constrained="true"></one-to-one>
複製代碼

  5.關聯操作

    a)預設情況下,關聯屬性時採用延遲載入機制載入的,可以通過映射關係文件中關聯屬性配置標簽中的lazy屬性進行修改,true/false。

    b)通過一個連接查詢一次性取出2張表的數據,避免2次查詢。在關聯屬性標簽上通過fetch屬性進行設置,稱之為抓取策略。“join”表示查詢時使用連接查詢,一起把對方數據抓取過來;“select”表示查詢時不使用連接查詢,是預設情況。當fetch為“join”時,關聯屬性的延遲載入失效。

 

  6.級聯操作:通過關聯映射,在對一方進行增刪改時,連帶增刪改關聯的另一方數據

    a)實現級聯添加/修改,需要在映射關係文件中的關聯屬性標簽中,通過cascade屬性進行設置,cascade="save-update"

    b)實現級聯刪除,cascade="delete"

    c)若想級聯添加、修改、刪除一起支持,cascade="all"

    d)控制反轉,在一對多關聯中,使用級聯新增、刪除時,當前操作的“一”方會試圖維護關聯欄位,然而關聯欄位是在“多”方對象中,它會自動維護這個欄位,因此“一”方沒必要做這樣的處理。在關聯屬性標簽上通過inverse屬性(true/false)交出控制權,預設是false,不控制反轉。

  7.Hibernate查詢

    a)HQL按條件查詢:條件中寫的是屬性名,在執行查詢前調用query對象為條件參數賦值

String hql = "from Course where name=?";
Session session = HibernateUtil.getSession();
Query query = session.createQuery(hql);
query.setString("math");
List<Course> courses = query.list();

    b)HQL查詢部分欄位:可以只查詢表中的一部分欄位,需要在from之前追加select語句,指定要查詢列對應的屬性名

String hql = "select id,name" + " from Course";

    註意:查詢部分欄位時,query.list()方法返回的集合中封裝的不是實體對象,而是一個Object[],數組中的值與select語句後面的屬性按順序對應。

    c)分頁查詢:通過API統一實現

int from = (page - 1) * pageSize;
query.setFirstResult(from);
query.setMaxResults(pageSize);

    註意:查詢的起點是本頁第一行,按照JDBC計算,公式為(page -1) * pageSize +1;Hibernate中行數的起點是0,不同於JDBC是從1開始,所以要在上面公式的基礎上-1,即(page -1) * pageSize

    d)查詢總頁數:根據以下hql查詢總行數,再計算總頁數

String hql = "select count(*) from Student";

    e)多表聯合查詢:可以使用HQL進行多表聯合查詢,不過HQL中寫的是關聯的對象的屬性名;有3中關聯查詢的方式:

    對象方式關聯

String hql = "select s.id, s.name, c.name from Student s, Course c " +
    "where s.course.id = c.id";

    join方式關聯(不能直接join對象,需要join關聯屬性)

String hql = "select s.id, s.name, c.name from Student s inner join s.courses c";

    select子句關聯

    f)直接使用SQL查詢

String sql = "select * from t_course where c_name=?";
Session session = HibernateUtil.getSession();
SQLQuery query = session.createSQLQuery(sql);
query.setString(0,"math");
List<Object[]> list = query.list(); //返回集合封裝的是Object[]

//若想返回集合中封裝實體對象
query.addEntity(Course.class);
List<Course> list = query.list();
複製代碼

 

    g)使用Criteria查詢

Criteria c = session.createCriteria(Course.class);
c.add(Restriction.eq("name", "math")).add(Restrictions.or(Restrictions.eq(), Restrications.eq()));
List<Course> list = c.list();

  

 

  8.二級緩存

    a)二級緩存類似於一級緩存,可以緩存對象,但它是SessionFactory級別的緩存,有SessionFactory負責管理。因此二級緩存的數據是Session間共用的,不同的Session對象都可以共用二級緩存中的數據。

    b)二級緩存適用於:對象數據頻繁共用,數據變化頻率低

    c)二級緩存使用步驟:

      導入ehcache.jar

      在src下添加緩存配置文件ehcache.xml

<ehcache>
<!--緩存到硬碟時的緩存路徑,java.io.tmpdir表示系統預設緩存路徑-->
<diskStore path="java.io.tmpdir"/>
<!--預設緩存配置
maxElementsInMemory:二級緩存可容納最大對象數
eternal:是否保持二級緩存中對象不變
timeToIdleSeconds:允許對象空閑的時間,即對象最後一次訪問起,超過該時間即失效
timeToLiveSeconds:允許對象存活的時間,即對象創建起,超過該時間即失效
overflowToDisk:記憶體不足,是否允許使用硬碟緩存,寫入路徑參考diskStore
-->

<defaultCache>
    maxElementsInMemory = "300"
    eternal = "false"
    timeToIdleSeconds = "120"
    timeToLiveSeconds = "300"
    overflowToDisk = "true" />
  

<!--自定義配置-->
<cache name="myCache">
    maxElementsInMemory = "2000"
    eternal = "false"
    timeToIdleSeconds = "200"
  timeToLiveSeconds = "300"
    overflowToDisk = "true" />
</ehcache>
複製代碼

      在hibernate.cfg.xml中開啟二級緩存,指定採用的二級緩存驅動類

<property name="hibernate.cache.use_second_level_cache">true</property>

<property name="hibernate.cache.provider_class">
org.hibernate.cache.EhCacheProvider
</property>

     在要緩存的對象對應的映射關係文件中,開啟當前對象的二級緩存支持,並指定緩存策略

<!--開啟二級緩存,並指定緩存策略
可以用region屬性指定自定義的緩存設置-->
<cache usage="read-only" />

   d)緩存策略:

      -只讀型(read-only):緩存不會更新,適用於不會發生改變的數據,效率最高,事務隔離級別最低

      -讀寫型(read-write):緩存會在數據變化時更新,適用於變化的數據

      -不嚴格讀寫型(nonstrict-read-write):緩存不定期更新,適用於變化頻率低的數據

      -事務型(transactional):緩存會在數據變化時更新,並且支持事務。效率最低,事務隔離界別最高。

<!-- 配置事務的隔離級別
        1 -- Read uncommitted isolation
        2 -- Read committed isolation
        3 -- Repeatable read isolation
        4 -- Serializable isolation
     -->
<property name="hibernate.connection.isolation">2</property>
複製代碼  

  9.查詢緩存

    a)查詢緩存依賴於二級緩存,可以理解為特殊的二級緩存,也是SessionFactory級別的,也是由SessionFactory負責維護

    b)查詢緩存可以緩存任何查詢到的結果

    c)查詢緩存是以hql為key,緩存該hql查詢到的整個結果。如果執行2次同樣的hql,第二次執行可以從查詢緩存中取到第一次查詢緩存的內容

    d)使用查詢緩存步驟:

      開啟二級緩存

      在hibernate.cfg.xml中,開啟查詢緩存

<!--開啟查詢緩存-->
<property name="hibernate.cache.use_query_cache">true</property>

      在查詢代碼執行前,指定開啟查詢緩存

query.setCacheable(true); //開啟查詢緩存 

整理到此為止,有不足的歡迎指正討論。。。☺


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

-Advertisement-
Play Games
更多相關文章
  • 隨著HTML5的廣泛應用,在一些網站中,經常看到有些預覽的短視頻預覽,滑鼠經過就會播放,移除就會停止播放,再次移進去就會繼續播放。 自己也研究著做一個比較簡單的類似的練習。 視頻可以自己到包圖網下載,包圖網的媒體首頁視頻預覽就是滑鼠移進去就播放,離開就停止,再移進去就播放。 不過,他們在視頻上,還增 ...
  • 這是一個簡約、大氣、實用的Hexo新主題:BMW
  • Object對象 說這個對象之前,如果您對編程語言開發稍微有點瞭解的話,應該知道面向對象是什麼意思,而js也有面向對象一說,就因為如此,js才會這麼強大。 什麼是面向對象 其實所有支持面向對象的編程語言,對於這個面向對象的概念都一樣的,所以你學會了此概念,理解其他任何語言的面向對象都很簡單,所... ...
  • 1.1 JavaScript 的簡史 JavaScript 誕生於1995年 ,後由 歐洲電腦製造商協會( ECMA,European Computer Manufacturers Association進行標準化 。ISO/IEC 也採用了ECMAscript 做為標準 自此以後 瀏覽器開發商就 ...
  • 所謂高度塌陷就是在文檔流中,父元素的高度預設是被子元素撐開的,也就是子元素多高,父元素就多高。但是當為子元素設置浮動以後,子元素會完全脫離文檔流,此時將會導致子元素無法撐起父元素的高度,導致父元素的高度塌陷。 由於父元素的高度塌陷了,則父元素下的所有元素都會向上移動,這樣將會導致頁面佈局混亂。 例如 ...
  • 編輯器選擇 對js的編輯器選用,有很多,能對html編輯的,也能對js編輯,比如notepad++,visual studio code,webstom,atom,pycharm,sublime text,Hbuilder等等的,根據你的喜好來就行 調試 在我們編寫js時,也可以像調整css樣式一樣... ...
  • Koa2學習(一)環境搭建 koa2腳手架 koa2服務安裝 koa2 generator目錄結構 什麼是 Koa2 koa 是由 Express 原班人馬打造的,致力於成為一個更小、更富有表現力、更健壯的 Web 框架。 使用 koa 編寫 web 應用,通過組合不同的 generator,可以免 ...
  • 【原因】 因為這個表和另一個表是有一對多關係的,當序列化表1的時候,會找到和另一個表2關聯的欄位,就會到另一個表2中序列化,然後另一個表2中也有一個欄位和表1相關聯.這樣.序列化就會發生這種錯誤! 【解決方案】 /註:這裡值得註意的是,當有外鍵向關聯時,必須要指定序列化元素,如果沒有外鍵相關聯,直接 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...