Hibernate框架之關聯映射入門

来源:http://www.cnblogs.com/zhangzongle/archive/2016/08/12/5766912.html
-Advertisement-
Play Games

關聯映射就是將關聯關係映射到資料庫里,在對象模型中就是一個或多個引用。 一:配置單向多對一關聯 在Emp類中定義一個Dept屬性,而在Dept類中無須定義用於存放Emp對象的集合屬性 01.Dept.java 02.Emp.java 03.Dept.hbm.xml 04.Emp.hbm.xml 05 ...


關聯映射就是將關聯關係映射到資料庫里,在對象模型中就是一個或多個引用。

一:配置單向多對一關聯

 在Emp類中定義一個Dept屬性,而在Dept類中無須定義用於存放Emp對象的集合屬性

 01.Dept.java

package cn.zhang.entity;

//部門實體類
public class Dept {
    
    private Integer deptid;//編號
    
    private String deptname;//名稱


    public Integer getDeptid() {
        return deptid;
    }

    public void setDeptid(Integer deptid) {
        this.deptid = deptid;
    }

    public String getDeptname() {
        return deptname;
    }

    public void setDeptname(String deptname) {
        this.deptname = deptname;
    }

}

02.Emp.java

package cn.zhang.entity;
//員工實體類
public class Emp {
    
    private Integer empno;//編號
    
    private String empname;//姓名
    
    private Dept dept;//所屬部門
    

    public Dept getDept() {
        return dept;
    }

    public void setDept(Dept dept) {
        this.dept = dept;
    }

    public Integer getEmpno() {
        return empno;
    }

    public void setEmpno(Integer empno) {
        this.empno = empno;
    }

    public String getEmpname() {
        return empname;
    }

    public void setEmpname(String empname) {
        this.empname = empname;
    }
    
}

03.Dept.hbm.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.zhang.entity">
<class name="Dept" table="DEPT">
<!--主鍵生成策略-->
<id name="deptid" column="DEPTID">
   <generator class="sequence">
   <param name="sequence">SQ_Num</param>
   </generator>
</id>
<property name="deptname" type="string" column="deptname"/>
</class>
</hibernate-mapping>

04.Emp.hbm.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.zhang.entity">
<class name="Emp" table="EMP">
<!-- 主鍵生成策略 -->
<id name="empno" column="empno">
    <generator class="sequence">
   <param name="sequence">SQ_Num</param>
   </generator>
</id>
<property name="empname" type="string" column="empname"/>
<!-- 多對一(員工對部門) -->
 <many-to-one name="dept" column="deptid" class="Dept"></many-to-one> 
</class>
</hibernate-mapping>

05.hibernate.cfg.xml  配置文件

<?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>

        <!-- Database connection settings -->
        <property name="connection.driver_class">oracle.jdbc.OracleDriver</property>
        <property name="connection.url">jdbc:oracle:thin:@localhost:1521:orcl</property>
        <property name="connection.username">zhangzong</property>
        <property name="connection.password">123</property>

        <!-- SQL dialect (SQL 方言)-->
        <property name="dialect">org.hibernate.dialect.Oracle10gDialect</property>
    
        <!-- Drop and re-create the database schema on startup -->
         <property name="hbm2ddl.auto">create</property> 

        <!-- Echo all executed SQL to stdout  在控制台列印後臺的SQL語句-->
        <property name="show_sql">true</property>
        
        <!-- 格式化顯示SQL -->
        <property name="format_sql">true</property>    
        
        <!-- JDBC connection pool (use the built-in) -->
        <!-- <property name="connection.pool_size">1</property> -->
        
        <!-- Enable Hibernate's automatic session context management 指定當前session範圍和上下文-->
        <!--  <property name="current_session_context_class">thread</property> -->
        
        <!-- Disable the second-level cache -->
        <!-- <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>-->

        <mapping resource="cn/zhang/entity/Dept.hbm.xml" />
        <mapping resource="cn/zhang/entity/Emp.hbm.xml" />
        

    </session-factory>

</hibernate-configuration>

06.用於獲得session對象和關閉session對象的工具類HibernateUtil 

package cn.zhang.util;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateUtil {
    //初始化一個ThreadLocal對象,有get和set方法
    private static final ThreadLocal<Session> sessionTL=new ThreadLocal<Session>();
    
    private static Configuration configuration;
    
    private final static SessionFactory sessionFactory;
    static{
        
        configuration=new Configuration().configure();
        sessionFactory=configuration.buildSessionFactory();
    }
    //獲得session對象
    public static Session currentSession() {
        //sessionTL的get方法根據當前線程返回其對應的線程內部變數,即Session對象,多線程情況下共用資料庫連接是不安全的。
        //ThreadLocal保證了每個線程都有自己的session對象
        Session session=(Session)sessionTL.get();
        if (session==null) {
            session=sessionFactory.openSession();
            sessionTL.set(session);
        }
        
        return session;
    }
    //關閉session對象
    public static void closeSession() {
        Session session=(Session)sessionTL.get();
        sessionTL.set(null);
        session.close();
    }

}

07.測試類

@Test //多對一的單向關聯關係
    public void TestOne(){
        
        Session session = HibernateUtil.currentSession();
        
        Transaction tx = session.beginTransaction();
        Dept dept=new Dept();
        dept.setDeptname("開發部");
        
        Emp emp=new Emp();
        emp.setDept(dept);
        emp.setEmpname("張總");
        
        session.save(dept);
        session.save(emp);
        
        tx.commit();
        
        HibernateUtil.closeSession();        
    }

二:配置雙向的一對多關聯

在上一個例子中,已經建立Emp類到Dept類的多對一關聯,下麵再增加Dept到Emp類的一對多關聯,

在Dept類中增加一個集合類型的emps屬性:

    private Set<Emp> emps=new HashSet<Emp>();//員工集合
    
    public Set<Emp> getEmps() {
        return emps;
    }

    public void setEmps(Set<Emp> emps) {
        this.emps = emps;
    }

在Dept.hbm.xml中也會改變為:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.zhang.entity">
<class name="Dept" table="DEPT">
<id name="deptid" column="DEPTID">
   <generator class="sequence">
   <param name="sequence">SQ_Num</param>
   </generator>
</id>
<property name="deptname" type="string" column="deptname"/>
<!-- 映射集合類型的emps屬性 -->
<!-- name屬性:設定持久化類的屬性名。此處為Dept類的emps -->
<set name="emps" cascade="save-update" inverse="true">
<!-- column屬性設定與所關聯的持久化類對應的表的外鍵,此處為EMP表的deptid欄位 -->
<key column="deptid"></key>
<!-- class屬性設定與所關聯的持久化類,此處為Emp類 -->
<one-to-many class="Emp"></one-to-many>
</set>
</class>
</hibernate-mapping>

補充:cascade屬性和inverse屬性(會新寫一篇博客)

 01."cascade"屬性

   "cascade"-直譯過來就是"級聯、串聯"的意思,書面化的解釋為"該屬性會使我們在操作主對象時,同時Hibernate幫助我們完成從屬對象 相應的操作(比如,有Customer和Order這兩張表,關係為一對多,只使用JDBC刪除Customer表中的一行記錄時,我們還需要手動的將 Order表中與之關聯的記錄全都刪除,使用Hibernate的'cascade'屬性後,當我們刪除一條Customer記錄時,Hibernate 會幫助我們完成相應Order表記錄的刪除工作,方便了我們的工作)"。

 02."inverse"屬性

       "inverse" -直譯過來就是"反轉,使顛倒"的意思,書面化的解釋為"是否將關係維護的權力交給對方"(這個解釋真夠蛋疼的-_-!!,就是理解不了)。 Hibernate中的"inverse"屬性只有兩個值"true"和"false"。"true"表示將關係維護的權力交給對方,"false"表示不交出維護權力(預設值)。

推薦博客:http://www.cnblogs.com/o-andy-o/archive/2012/03/26/2418235.html

測試:

    @Test  
    public void TestThree(){
        //獲得session對象
        Session session = HibernateUtil.currentSession();
        //開啟事務
        Transaction tx = session.beginTransaction();
        //建立一個Dept對象和Emp對象

        Dept dept=new Dept();
        dept.setDeptname("就業部");
        
        Emp emp=new Emp();
        emp.setEmpname("坤坤");
        //建立Dept和Emp對象的一對多雙向關聯關係
        emp.setDept(dept);    
        dept.getEmps().add(emp);
        //保存Dept對象
        session.save(dept);
        
        //提交事務
        tx.commit();
        //關閉session連接
        HibernateUtil.closeSession();

    }

 

三:配置單向多對多關聯  --利用第三張表建立兩張表之間的聯繫

建立從Project(項目)類到Emp(員工)類的單向多對多關聯。

需在Project定義集合類型emps屬性,Emp類中不需要定義集合類型的projects屬性。

Project.java

package cn.zhang.entity;

import java.util.HashSet;
import java.util.Set;
public class Project {
    private Integer proid;
    private String proname;
    private Set<Emp> emps = new HashSet<Emp>();
    public Integer getProid() {
        return proid;
    }
    public void setProid(Integer proid) {
        this.proid = proid;
    }
    public String getProname() {
        return proname;
    }
    public void setProname(String proname) {
        this.proname = proname;
    }
    public Set<Emp> getEmps() {
        return emps;
    }
    public void setEmps(Set<Emp> emps) {
        this.emps = emps;
    }        

}

Project.hbm.xml     --利用第三張表建立兩張表之間的聯繫

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.zhang.entity">
    <class name="Project" table="PROJECT">
        <id name="proid" type="java.lang.Integer">
            <generator class="sequence">
          <param name="sequence">SQ_Num</param>
           </generator>
        </id>
        <property name="proname" type="java.lang.String" column="PRONAME"/>
        <!-- 多對多關聯 -->
        <set name="emps" table="PROEMP" cascade="save-update"  >
            <key column="proid" />
            <many-to-many class="Emp" column="empno" />             
        </set>      
    </class>
</hibernate-mapping>

測試:

    @Test
    public void TestOne(){
        Session session = HibernateUtil.currentSession();
        Transaction tx = session.beginTransaction();
        //創建EMP對象
        Emp emp=new Emp();
        emp.setEmpname("李小龍");
        
        //創建Pro對象
        Project pro=new Project();
        pro.setProname("海澱花園");
    
        //指定工程需要的員工
        pro.getEmps().add(emp);
                    
        session.save(pro);
        
        // 事務提交
        tx.commit();
            
        HibernateUtil.closeSession();
    }
     

三:配置雙向多對多關聯    --利用第三張表建立兩張表之間的聯繫

對於雙向多對多關聯,需要把一端的inverse屬性設為true,關聯的兩端都可以使用<set>元素。

Project類--定義集合類型的emps屬性

Emp類--定義集合類型的projects屬性

Project.java:

package cn.zhang.entity;

import java.util.HashSet;
import java.util.Set;

public class Project {
    private Integer proid;
    private String proname;
    private Set<Emp> emps = new HashSet<Emp>();
    public Integer getProid() {
        return proid;
    }
    public void setProid(Integer proid) {
        this.proid = proid;
    }
    public String getProname() {
        return proname;
    }
    public void setProname(String proname) {
        this.proname = proname;
    }
    public Set<Emp> getEmps() {
        return emps;
    }
    public void setEmps(Set<Emp> emps) {
        this.emps = emps;
    }
    
    

}

 

Emp.java:

package cn.zhang.entity;

import java.util.HashSet;
import java.util.Set;

//員工實體類
public class Emp {
    
    private Integer empno;
    
    private String empname;
    
    private Set<Project> projects = new HashSet<Project>();
    
    public Set<Project> getProjects() {
        return projects;
    }

    public void setProjects(Set<Project> projects) {
        this.projects = projects;
    }

    public Integer getEmpno() {
        return empno;
    }

    public void setEmpno(Integer empno) {
        this.empno = empno;
    }

    public String getEmpname() {
        return empname;
    }

    public void setEmpname(String empname) {
        this.empname = empname;
    }
        
}

Project.hbm.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.zhang.entity">
    <class name="Project" table="PROJECT">
        <id name="proid" type="java.lang.Integer">
            <generator class="sequence">
          <param name="sequence">SQ_Num</param>
           </generator>
        </id>
        <property name="proname" type="java.lang.String" column="PRONAME"/>
        <!-- 多對多關聯 -->
        <set name="emps" table="PROEMP" cascade="save-update"  >
            <key column="proid" />
            <many-to-many class="Emp" column="empno" />             
        </set>      
    </class>
</hibernate-mapping>

Emp.hbm.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.zhang.entity">
    <class name="Emp" table="EMP">
        <id name="empno" column="empno">
            <generator class="sequence">
                <param name="sequence">SQ_Num</param>
            </generator>
        </id>
        <property name="empname" type="string" column="empname" />

        <!--多對多關聯 -->
        <set name="projects" table="PROEMP" cascade="save-update" inverse="true">
            <key column="empno" />
            <many-to-many class="Project" column="proid" />
        </set>
    </class>
</hibernate-mapping>

測試:

@Test
    public void TestOne(){
        Session session = HibernateUtil.currentSession();
        Transaction tx = session.beginTransaction();
        //創建EMP對象
        Emp emp=new Emp();
        emp.setEmpname("李小龍");
        Emp emp2=new Emp();
        emp2.setEmpname("小龍");
        Emp emp3=new Emp();
        emp3.setEmpname("李龍");
        //創建Pro對象
        Project pro=new Project();
        pro.setProname("海澱花園");
        Project pro2=new Project();
        pro2.setProname("海澱花園fd");
        //指定工程需要的員工
        pro.getEmps().add(emp);
        pro.getEmps().add(emp2);
        pro.getEmps().add(emp3);
        
        pro2.getEmps().add(emp3);
        pro2.getEmps().add(emp2);
        //指定員工所屬的工程
        //emp.getProjects().add(pro);
        
        session.save(pro);
        session.save(pro2);
        
        // 事務提交
        tx.commit();
            
        HibernateUtil.closeSession();
    }

註意:雙向多對多,還可以拆成兩個多對一

四:建立多對多雙向關聯 拆成兩個一對多  --利用第三張表建立兩張表之間的聯繫

主要思想:新建立一個關係實體類和兩張表關聯的映射文件,主要在此映射文件中配置關聯關係,其他兩個映射文件只要配置基礎映射

ProEmp.java

package cn.zhang.entity;
//關聯實體類
public class ProEmp {
    private Integer id;
    private Project pro; //項目集合
    private Emp emp; //部門集合
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public Project getPro() {
        return pro;
    }
    public void setPro(Project pro) {
        this.pro = pro;
    }
    public Emp getEmp() {
        return emp;
    }
    public void setEmp(Emp emp) {
        this.emp = emp;
    }

}

Emp.java

package cn.zhang.entity;

import java.util.HashSet;
import java.util.Set;

//員工實體類
public class Emp {
    
    private Integer empno;
    
    private String empname;
    
    private Set<ProEmp> projects = new HashSet<ProEmp>();//與ProEmp關聯
    
    public Set<ProEmp> getProjects() {
        return projects;
    }

    public void setProjects(Set<ProEmp> projects) {
        this.projects = projects;
    }

    public Integer getEmpno() {
        return empno;
    }

    public void setEmpno(Integer empno) {
        this.empno = empno;
    }

    public String getEmpname() {
        return empname;
    }

    public void setEmpname(String empname) {
        this.empname = empname;
    }
    
    

}

Project.java

package cn.zhang.entity;

import java.util.HashSet;
import java.util.Set;

//員工實體類
public class Emp {
    
    private Integer empno;
    
    private String empname;
    
    private Set<ProEmp> projects = new HashSet<ProEmp>();//與ProEmp關聯
    
    public Set<ProEmp> getProjects() {
        return projects;
    }

    public void setProjects(Set<ProEmp> projects) {
        this.projects = projects;
    }

    public Integer getEmpno() {
        return empno;
    }

    public void setEmpno(Integer empno) {
        this.empno = empno;
    }

    public String getEmpname() {
        return empname;
    }

    public void setEmpname(String empname) {
        this.empname = empname;
    }
    
}

Emp.hbm.xml  

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="cn.zhang.entity">
    <class name="Emp" table="EMP">
        <id name="empno" column="empno">
            <generator class="sequence">
                <param name="sequence">SQ_Num</param>
            </generator>
        
              
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 前一篇分析了前十個基礎實驗的代碼,從這裡開始分析後十個~ 一、PPI原理: PPI(Programmable Peripheral Interconnect),中文翻譯為可編程外設互連。 在nRF51822 內部設置了PPI 方式,可以通過任務和事件讓不同外設之間進行互連,而不需要CPU 進行參與。 ...
  • nginx代理啟動 /usr/local/nginx/sbin/nginx apache2.2 service httpd restart【重啟apache服務】vi /etc/sysconfig/iptables【防火牆配置】service iptables restart【重啟防火牆服務】 vi ...
  • 實驗01 - GPIO輸出控制LED 引腳輸出配置:nrf_gpio_cfg_output(LED_1); 引腳輸出置高:nrf_gpio_pin_set(LED_1); 引腳電平轉換:nrf_gpio_pin_toggle(LED_1); 毫秒延時:nrf_delay_ms(100); 實驗02 ...
  • ---------------------現在windows下的命令提示符只是一個軟體,操作方式和界面模擬dos操作系統 ...
  • 實習筆記1 2016年8月1日 14:12 Option Explicit 預設情況下,如果使用一個沒有聲明的變數,它將繼承“Variant”類型。在模塊、窗體和類的通用聲明區使用“OptionExplicit”能強制我們必須聲明變數後才能使用變數 Sample: 在通用聲明區聲明瞭“Option ...
  • 功能: 單擊選中行,雙擊打開詳細頁面 說明:單擊事件(onclick)使用了 setTimeout 延遲,根據實際需要修改延遲時間 ;當雙擊時,通過全局變數 dbl_click 來取消單擊事件的響應 常見處理行方式會選擇在 RowDataBound/ItemDataBound 中處理,這裡我選擇 P ...
  • 1.EF是什麼? EF是.net封裝的一個用於資料庫交互的實體層框架,它的全稱是Entity Framework。 2.EF搭建: 新建之後,我們就可以看到裡面的內容: 我們可以分別看一下它裡面有些什麼? 2.1.創建ef之後,我們EF裡面[打開方式-XML文本編輯器]看到它裡面最主要的有SSDL, ...
  • 首先,本人大學剛畢業,想把自己學習的一些東西記錄下來,也是和大家分享,如有不對之處還請多加指正。聲明:但凡是我博客里的文章均是本人實際操作遇到的例子,不會隨便從網上拷貝或者轉載,本著對自己和觀眾負責的態度。 什麼是WebAPI?我的理解是WebAPI+JQuery(前端)基本上能完成Web MVC的 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...