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

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

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

相关文章

Log4j Bug –减慢您的应用程序

最近&#xff0c;我们正在对流行的SaaS应用程序进行故障排除。 该应用程序间歇性地减慢了速度。 要从问题中恢复&#xff0c;必须重新启动应用程序。 在高流量期间&#xff0c;此应用有时会变慢&#xff1b; 有时在交通繁忙时也是如此。 没有凝聚力模式。 这种应用程序变慢并重…

androidstudio --debug 出现 source code not match bytecode

问题 如标题 原因 编译api版本与运行app的模拟器api版本不一致 解决 换成API版本一致的模拟器运行app即可

android monitor突然不能显示

问题 如题 原因 不清楚。。。。 解决 方式一-有副作用&#xff08;原因不明&#xff09;-debug可能会一直 wait attach&#xff0c;不能进入调试模式 先将Android NDK support plugin禁用&#xff08;重启androidstudio&#xff09;右击android monitor,选择remove from …

jvm虚拟机 基于栈_守护基于JVM的应用程序

jvm虚拟机 基于栈部署体系结构设计是任何定制服务器端应用程序开发项目的重要组成部分。 由于其重要性&#xff0c;部署架构设计应尽早开始&#xff0c;并与其他开发活动一起进行。 部署体系结构设计的复杂性取决于许多方面&#xff0c;包括所提供服务的可伸缩性和可用性目标&a…

ListView中让TextView中的文字进行单独滚动

TextView不能在ListeView中单独的滚动原因 默认ListView将会拦截MOVE事件向下传递 参见源码 case MotionEvent.ACTION_MOVE: {switch (mTouchMode) {case TOUCH_MODE_DOWN:int pointerIndex ev.findPointerIndex(mActivePointerId);if (pointerIndex -1) {pointerIndex 0;…

JPA @Embeddable和@Embedded

介绍&#xff1a; 作为一个面向对象的开发人员&#xff0c;我们希望避免使用带有大量不相关字段的大型类。 因此&#xff0c;我们可能经常感到有必要使用多个对象来表示JPA实体。 在本快速教程中&#xff0c;我们将学习如何使用JPA或Hibernate中的Embedded和Embeddable注释来实…

android monitor不能查看/data目录

问题 在android 7.0虚拟机上不能查看/data目录 解决 1. 修改目录权限 开始->cmd->adb shell->chmod -R 777 /data 2. root虚拟机 先执行 adb root&#xff0c;再执行 adb remount 出现remount succeeded表示可以了

Sqlite error- INSERT failed: datatype mismatch

问题 sqlite3 使用.import命令导入输入出现error-INSERT failed: datatype mismatch 原因 文件字段的默认分隔符为“|”&#xff0c;而从excel转换的.csv文件默认为逗号&#xff0c;所以导致文件解析出错&#xff0c;进而 “数据类型不匹配” 解决 在.import命令前修改分隔…

反射-获取java私有内部类反射类型、私有字段

获取JAVA私有内部类反射类型 方式一 Class.forName(“外部类完整路径$内部私有类类名”); 方式二 通过获取对应私有内部类的字段而获取 完整的类名 Class.forName(field.getType().getName()) 获取JAVA私有字段 Class.forName(“类完整路径”).getDelcaredField(“字段名…

javafx透明边框_JavaFX技巧6:使用透明颜色

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

android-创建sdcard

进入sdk 安装路径 tools目录下 mksdcard 100M D:\dxfSDCard.img //创建一个100M的sdcard

Apache Ivy 2.5.0发布

本周&#xff0c;我们发布了Apache Ivy的 2.5.0版本。 Apache Ivy是与Apache Ant构建工具集成的构建依赖项管理器。 可以照常从https://ant.apache.org/ivy/download.cgi下载该下载。 该2.5.0版本是在Ivy发行版中存在很大差距之后发布的。 2.4.0于2014年12月26日发布。此后&am…

android: a system image must be selected to continmue

问题&#xff1a;如题 原因&#xff1a; 没有对应的镜像文件 解决 android studio 进入setting -> appearance behavior -> system setting -> android sdk 下载对应的镜像文件即可

win10 更新 英特尔显示器音频 后显示器音箱没有声音

问题 如题&#xff0c;win10系统更新后显示器音箱没有声音&#xff0c;且右击桌面声音查看播放设备 &#xff08;说明&#xff1a;这是在解决问题之后截的图&#xff0c;没解决前&#xff0c;只有一个“扬声器/听筒”&#xff0c;原先是存在BenQ LCD的&#xff09; 解决过…

unity ppr_智能自动PPR更改事件策略

unity pprADF开发人员普遍认为&#xff0c;将迭代器绑定更改事件策略设置为ppr在性能方面不是一件好事&#xff0c;因为此策略会强制框架刷新每个请求上绑定到此迭代器的所有属性绑定。 这不是真的&#xff01; 框架仅刷新在请求期间已更改的属性和依赖于已更改属性的属性。 …

onenote创建快速笔记--此分区尚不可用,它是从其他设备添加的,该设备同步后才将可用

问题如题 解决 【文件】→【选项】->【保存和备份】 ->【修改】-> 选择新的分区存放快速笔记 图文并茂请参见&#xff1a;https://blog.sina.com.cn/s/blog_7012320d0102wsmw.html 其他&#xff1a; 同步不能连接服务器 解决该问题时&#xff0c;出现同步不成功&…

用Java匹配模式

如果您使用的是Java&#xff0c;那么您之前很有可能会看到其模式匹配。 String#matches(String)方法在内部使用Pattern类型&#xff0c;该类型包含更复杂的功能&#xff1a; 通过编译正则表达式来创建Pattern 。 该模式与任何输入字符串匹配&#xff0c;并且可以选择查找捕获组…

gradle-com.android.build.api.transform.TransformException:Error while generating the main dex list

问题 What went wrong: Execution failed for task >’:app:transformClassesWithMultidexlistForYm10000016Release’. com.android.build.api.transform.TransformException: Error while generating the main dex list. 原因 MultiDex未做初始化 解决 在application的…

Devc++- 源文件未编译”

问题&#xff1a;如题 解决&#xff1a; 删除D:\Software\DEV-CPP\Libexec\gcc\mingw32\3.4.2\目录中的collect2.exe&#xff08;最好修改名称或备份一下&#xff09;

如何构建一个Maven插件

使用Okta的身份管理平台轻松部署您的应用程序 使用Okta的API在几分钟之内即可对任何应用程序中的用户进行身份验证&#xff0c;管理和保护。 今天尝试Okta。 由于其插件生态系统的普及&#xff0c;Apache Maven仍然是Java领域中最流行的构建工具。 很容易找到一个现有的插件来…