JAXB –新手的观点,第1部分

我知道你们很多人已经在想什么了,所以让我们摆脱它:“ 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对类的默认处理是什么。 因此,我们将从最小的步骤开始,以将一个Employee实例“封送”到XML文档中。 如果对结果文档的外观感到满意,我们将交换解组代码; 如果没有,我们可以考虑自定义映射。

首先,我们需要配置一个JAXBContext实例以与我们的域类一起使用。

JAXBContext jaxb = JAXBContext.newInstance(Employee.class);

顺便说一句,我们可以传入包含类的包的名称,而不是将类对象传递给newInstance(),只要每个包都包含一个jaxb.in​​dex文件,该文件列出了要使用的类或ObjectFactory类,以及用于创建域类(和/或包装它们的JAXBElements)实例的方法。 如果您需要大量不相关的域类的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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/363024.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

初识C语言(五)

自定义函数 C语言提供了大量的库函数&#xff08;右侧资料下载中有&#xff09;&#xff0c;比如stdio.h提供输出函数&#xff0c;但是还是满足不了我们开发中的一些逻辑&#xff0c;所以这个时候需要自己定义函数&#xff0c;自定义函数的一般形式&#xff1a; 注意&#xff1…

bzoj2916: [Poi1997]Monochromatic Triangles 思路

bzoj2916: [Poi1997]Monochromatic Triangles 链接 bzoj 思路 总方案\(C_{n}^{3}-异色三角形\) 异色三角形有个特点。 会出现两个点有两条不同色的边。 然后统计就行了。 代码 #include <bits/stdc.h> #define ll long long using namespace std; const int _5e37; int n…

nodeJS实现简单网页爬虫功能

前面的话 本文将使用nodeJS实现一个简单的网页爬虫功能 网页源码 使用http.get()方法获取网页源码&#xff0c;以hao123网站的头条页面为例 http://tuijian.hao123.com/hotrank var http require(http);http.get(http://tuijian.hao123.com/hotrank,function(res){var data ;…

不能上网原因(查)

实验室不能上网原因记录&#xff1a;如果不是你电脑原因&#xff0c;很可能就是路由器和dns设置的问题。。把dns设置为寝室校园网专用dns试试可能就好了。。 网页打不开&#xff0c;浏览器打不开&#xff0c;这是上网时候广大网友经常碰见的问题&#xff0c;本文将针对网页打不…

JavaFX技巧6:使用透明颜色

为用户界面元素选择正确的颜色始终是一个很大的挑战&#xff0c;但是当您开发可重用的框架控件时&#xff0c;开发人员就无法控制使用它们的应用程序的外观和感觉&#xff0c;这甚至更具挑战性。 尽管您可能总是将元素添加到默认的灰色背景之上&#xff0c;但是嵌入控件的开发人…

bzoj2287【POJ Challenge】消失之物 缺一01背包

bzoj2287【POJ Challenge】消失之物 缺一01背包 链接 bzoj 思路 分治solve(l,r,arr)表示缺少物品\([l,r]\)的dp数组arr。 然后solve(l,mid,arr)用右边的物品更新&#xff0c;solve(mid1,r,arr)同理。 \(f(n)2*f(\frac{n}{2})(r-l1)*m\) 复杂度为\(O(nmlog{n})\) 缺点最短路也是…

38.QT-QAxObject快速写入EXCEL示例

参考链接: https://blog.csdn.net/czyt1988/article/details/52121360 http://blog.sina.com.cn/s/blog_a6fb6cc90101gv2p.html 1. QAxObject介绍 在QT中,有个自带的QAxObject类,可以直接操作EXCEL 除此之外,当我们操作某个文件夹下的EXCEL的时候,都会在该文件夹下出现一个隐藏…

EA常见画图(类图、包图、构件图、状态图、顺序图、活动图)

EA常见活动图&#xff0c;状态图画法 类图:111&#xff08;1&#xff09;给关系添加注释&#xff08;2&#xff09;设置关系线样式 包图&#xff1a;&#xff08;1&#xff09;创建包图&#xff08;2&#xff09;在包中添加子包&#xff1a;&#xff08;3&#xff09;在包中添加…

比萨问题–建造者与装饰者

问题陈述 我们需要为一家披萨公司构建软件&#xff0c;该公司想要准备各种类型的披萨&#xff0c;例如鸡肉披萨&#xff0c;扁平面包&#xff0c;意大利辣香肠披萨和额外的奶酪&#xff0c;并在上面放些配料。 让我们尝试看看哪种设计模式适合该问题说明以及在哪种情况下。 传…

系统启动

1.开机2.bios加电自检power on self test 由于此时显卡还未初始化&#xff0c;只能靠声音辨别错误3.将boot sector读入0000&#xff1a;7c00处4.检查0000&#xff1a;7def是否等于0xaa555.跳转到0000&#xff1a;7c00处执行MBR程序6.MBR将自己复制到0000&#xff1a;0600处执行…

bzoj3589 动态树 求链并 容斥

bzoj3589 动态树 链接 bzoj 思路 求链并。 发现只有最多5条链子&#xff0c;可以容斥。 链交求法&#xff1a;链顶是两条链顶深度大的那个&#xff0c;链底是两个链底的\(lca\) 如果链底深度小于链顶&#xff0c;就说明两条链没有交集。 复杂度\(m*2^klog^2n\) 还有一种做法。 …

NodeJS学习目录

前面的话 几年前&#xff0c;对于学习NodeJS可能还有所迟疑&#xff0c;怕分散了前端学习的精力。但到了现在&#xff0c;如果不学习nodeJS&#xff0c;前端的学习却可能无法再有所进展。技术的进步就是这么残酷。对新技术观望的时候&#xff0c;该技术已经大行其道了 小火柴将…

最佳加法表达式

题意&#xff1a;有一个由1..9组成的数字串.问如果将m个加号插入到这个数字串中,在各种可能形成的表达式中&#xff0c;值最小的那个表达式的值是多少。输入&#xff1a;5 31 2 3 4 5输出&#xff1a;24 1 #include<iostream>2 #include<algorithm>3 using namespa…

我最喜欢的IntelliJ IDEA功能

我已经是IntelliJ IDEA的长期用户&#xff08;和客户&#xff09;。 我想我是在2005年或2006年&#xff08;版本5.0&#xff09;左右开始使用它的。 那时我是Eclipse用户。 我的一些同事向我推荐了它&#xff0c;起初我没有被说服&#xff0c;但是在尝试之后我印象深刻。 现在…

[转载]PHP 计算时间差

我们常常在网站上看到某篇文章发表于“3天前”&#xff0c;“5个月前”&#xff0c;“4年前”。下面这个函数就提供了计算这个时间差的功能。 <?php/*** 时间差计算** param Timestamp $time* return String Time Elapsed* author Shelley Shyan* copyright http://phparch…

cd1101d 树形dp

cd1101d 简单dp 链接 codeforces 思路 所有数的质因数存下来&#xff0c;最多6个。 然后\(f[i][j][0/1]\)表示i子树内链gcd为j的i是否为链头。 暴力转移就行了 代码 #include <bits/stdc.h> using namespace std; const int _2e57,N2e5; int n,pri[_],vis[_],cnt; vector…

深入理解闭包系列第五篇——闭包的10种形式

前面的话 根据闭包的定义&#xff0c;我们知道&#xff0c;无论通过何种手段&#xff0c;只要将内部函数传递到所在的词法作用域以外&#xff0c;它都会持有对原始作用域的引用&#xff0c;无论在何处执行这个函数都会使用闭包。接下来&#xff0c;本文将详细介绍闭包的10种形式…

selenium 常见问题

启动selenium时报错如下异常&#xff1a; selenium.common.exceptions.WebDriverException: Message: geckodriver executable needs to be in PATH. 解决方式&#xff1a;需要下载geckodriver&#xff0c;并放在path的环境变量下&#xff0c;下载地址&#xff1a;https://gith…

通过示例了解挥发

我们已经花了几个月的时间来稳定Plumbr中的锁定检测功能 。 在此期间&#xff0c;我们遇到了许多棘手的并发问题。 许多问题是独特的&#xff0c;但是一种特殊类型的问题一直反复出现。 您可能已经猜到了–滥用volatile关键字。 我们已经发现并解决了许多问题&#xff0c;其中…

jQuery设计思想

前面的话 在深入了解jQuery的各个细节之前&#xff0c;需要对jQuery的设计思想有一个大致的了解。在遇到问题时&#xff0c; 知道应该使用jQuery的哪一个功能&#xff0c;然后迅速从手册中找到具体的用法。本文将详细介绍jQuery的设计思想 选择元素 jQuery的基本设计思想和主要…