jaxb_JAXB –新手的观点,第1部分
jaxb
我知道你們中的很多人已經在想什么,所以讓我們擺脫這個問題:“ JAXB? 如XML? 來吧,所有很棒的孩子都在使用JSON。”
關于XML與JSON的辯論以及許多促成它的論據都得到了很好的記錄。 我不會花很多時間在這里重新整理它們。 我相信每種格式都有其用途,但是即使您處在“從未使用過XML”的陣營中,您仍然可能想繼續閱讀,因為我討論的觀察結果和技術應同樣適用于與Jackson進行JSON數據綁定(或類似工具)。
在第1部分中,我描述了一個簡單的使用模式,該模式將JAXB的數據綁定功能與JPA配對。 當然,兩者之間的交互并不總是那么簡單,因此在第2部分中,我將研究如何解決可能遇到的一些復雜問題。
問題
在我當前的項目中,我們正在構建一套Java應用程序來管理制造過程中物料的轉移。 我們決定“從外而內”構建,以在任何給定的迭代之后促進面向用戶的演示。 因此,在第一個迭代中,我們使用硬編碼的虛擬數據構建了一些屏幕。 然后,在每次后續迭代中,我們都會在屏幕后面添加更多基礎架構和邏輯。
為了使早期的演示更具交互性,我們決定為中央應用程序創建一個“測試控制臺”。 一個人在控制臺上鍵入命令可以模擬系統“已實現網絡”部分的行為。 借助Antlr 4之類的工具可以簡化命令解析,構建控制臺的成本是適中的,并且我們認為使用控制臺進行測試和診斷具有長期價值。
我們已經達到了需要由另一個應用程序的數據來驅動系統行為的地步。 負責創建和維護此數據的“其他應用程序”尚未編寫,并且不會使用一段時間,因此我們需要一種通過控制臺加載示例數據的方法。
選件
本質上,我們的任務是構建(或利用)數據加載器。 我們選擇XML作為文件的可能格式,然后瀏覽我們的團隊通常會熟悉的工具列表。
DBUnit具有數據加載功能(旨在設置可重復的測試條件)。 它支持兩種不同的XML模式(“平面”和“完整”),每種模式顯然都是面向表的。 它還提供了替換變量,因此我們可以構建模板文件并允許控制臺輸入設置最終值。
我對以這種方式使用單元測試工具有些保留,但是在團隊顫抖的箭中,這可能是最合適的。 不管是好是壞,我第一次嘗試使用它都沒有成功(結果是我看的是DBUnit API的錯誤部分),這讓我開始思考。
我們已經有一種方法(即Hibernate)將數據推送到我們的數據庫中。 因此,當我用“如何從XML文檔創建實體實例”這一問題來表述問題時,JAXB顯然是競爭者。 我很高興發現Java附帶了JAXB實現,因此我開始嘗試一下。
新人的觀點
從未使用過JAXB,所以我開始進行一些研究。 我發現的許多材料都涉及從XML模式生成Java類。 這不足為奇-這是該工具可以完成的大部分工作-但就我而言,我想將數據綁定到現有的Hibernate映射域類。 這導致了一些令人驚訝的事情:我發現一些最全面的教程似乎并沒有預料到這種用法。 我認為這很好地說明了您對工具的初始假設可以影響您的想法和使用方式。
如果像幾個在線資源一樣,首先將JAXB與DOM進行比較,那么將編組操作的輸出視為需要遍歷和處理的文檔樹是很自然的,也許會將相關數據復制到并行的層次結構中。域對象。 遍歷和處理可能比使用DOM樹更容易(至少在概念上),但是作為權衡,您必須保持兩個類的層次結構直,這需要謹慎的命名約定。
毫無疑問,用例恰恰是必要的,但該工具不僅限于這種方法。 如果您相反地比較JAXB與Hibernate(作為將數據從外部源加載到您的域對象中的一種方式),那么自然會問“為什么我不能同時使用一組域對象?” 您至少可以在某些時候稍加注意。
簡單案例
在這些示例中,我將直接使用JAXB API。 我們只需撥打幾個簡單的電話即可完成我們的任務,因此這相當簡單。 值得注意的是,Spring確實也提供JAXB集成,尤其是如果您在整個應用程序中都使用Spring,則它提供的配置方法可能是更可取的。
假設您有一個EMPLOYEE表。 每個員工都有一個唯一的數字ID和名稱。 如果將注釋用于ORM映射數據,則可能具有如下域類:
@Entity @Table(name=”EMPLOYEE”) public class Employee {@Id@Column(name=”EMPLOYEE_ID”)private Integer employeeId;@Column(name=”FIRST_NAME”)private String firstName;@Column(name=”LAST_NAME”)private String lastName;// … getters and setters … };現在,我們要讓用戶提供一個Employee.xml數據文件。 假設我們沒有需要遵循的特定XML模式,那么我們不妨看看JAXB對該類的默認處理是什么。 因此,我們將從最小的步驟開始,將“雇員”實例“封送”到XML文檔中。 如果我們對結果文檔的外觀感到滿意,我們將交換解組代碼; 如果沒有,我們可以考慮自定義映射。
首先,我們需要配置一個JAXBContext實例以與我們的域類一起使用。
JAXBContext jaxb = JAXBContext.newInstance(Employee.class);順便說一句,我們可以傳入包含類的包的名稱,而不是將類對象傳遞給newInstance(),前提是每個包都包含一個jaxb.in??dex文件,該文件列出了要使用的類或ObjectFactory類以及用于創建域類(和/或包裝它們的JAXBElement)的方法的方法。 如果您需要大量無關域類的XML映射,則此方法可能更可取。
JAXBContext具有創建編組器(創建表示對象的XML文檔)和解組器(實例化對象并從XML文檔中的數據初始化它們)的方法。 我們可以像這樣檢查Employee類的默認映射:
Employee employee = new Employee();employee.setEmployeeId(37);employee.setFirstName(“Dave”);employee.setLastName(“Lister”);Marshaller marshaller = jaxb.createMarshaller();marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.marshal(employee, System.out);(嚴格來說,setProperty()調用不是必需的,但會使輸出更易于理解。)如果嘗試運行此代碼,則會收到異常消息,告訴我們尚未識別出根元素。 為了解決這個問題,我們將@XmlRootElement批注添加到Employee類中。
@XmlRootElement @Entity @Table(name=”EMPLOYEE”) public class Employee {@Id@Column(name=”EMPLOYEE_ID”)private Integer employeeId;@Column(name=”FIRST_NAME”)private String firstName;@Column(name=”LAST_NAME”)private String lastName;// … getters and setters … };默認情況下,編組器將映射每個公共bean屬性(getter / setter對)和每個公共字段。 因此,如果我們的Employee類具有您期望的getter和setter,則我們的輸出應類似于以下內容:
<?xml version=”1.0” encoding=”UTF-8” standalone=”yes”?> <employee><employeeId>37</employeeId><firstName>Dave</firstName><lastName>Lister</lastName> </employee>請注意,下面的元素將采用任意順序。 (在我的測試中,這是按字母順序排列的。)在這種情況下,效果很好,但是如果沒有,我們可以使用@XmlType注釋強制執行該順序。 默認情況下,解組器將以任何順序獲取元素。
JAXB很高興不了解JPA批注,而Hibernate(或您可能使用的任何JPA提供程序)將不理會JAXB批注,因此,我們現在可以通過簡單地要求JAXB從文件中解組數據來將XML文件中的數據加載到數據庫中。將結果對象傳遞給JPA提供程序。 解組代碼如下所示:
JAXBContext jaxb = JAXBContext.newInstance(Employee.class); Unmarshaller unmarshaller = jaxb.createUnmarshaller(); File xmlFile = /* … */; Employee employee = unmarshaller.unmarshal(xmlFile);默認情況下,如果從XML中省略了表示bean屬性之一的元素,則不會設置該屬性。 因此,例如,如果我們的JPA映射包括自動生成employeeId,則<employee>元素僅需要包含<firstName>和<lastName>。
好…
從理論上講,就是這樣。 (如果您知道理論與實踐之間的區別,則要額外加分。)幾個注釋和可能的十幾行代碼足以讓您入門。 另外一個好處是,您可以在一個帶注釋的.java文件中查看所有數據表示形式(XML,數據庫和Java對象)之間的關系。
不太好…
上面的例子很簡單,可以涵蓋大量的基本用例。 但是大多數真實的數據模型包括一對多關系和組合鍵之類的東西,它們會增加您可能會或可能不會看到的皺紋。 在第2部分(計劃于2014年8月25日)中,我將介紹我遇到的一些復雜問題,并討論解決每個復雜問題的合理簡單選擇。
翻譯自: https://www.javacodegeeks.com/2014/07/jaxb-a-newcomers-perspective-part-1.html
jaxb
總結
以上是生活随笔為你收集整理的jaxb_JAXB –新手的观点,第1部分的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: AWS Loft的数据库周
- 下一篇: m3a760m电脑主板(m3a78m主板
