如何:使用Json插入数据库并从中读取

在本文中,我们将为Speedment创建一个插件,该插件使用Gson生成序列化和反序列化逻辑,从而使其在数据库实体和JSON字符串之间进行映射非常容易。 这将有助于展示Speedment代码生成的可扩展性,同时探索Gson库的一些很酷的功能。

Speedment是用于Java的代码生成工具,它连接到数据库并用作生成项目的实体和管理器文件的参考。 该工具是非常模块化的,允许您编写自己的插件来修改结果代码的外观。 几个人在Gitter聊天中提到的一件事是,Speedment实体被声明为抽象的,这阻止了它们被自动反序列化。 在本文中,我们将研究如何通过自动为数据库中的每个表生成一个自定义TypeAdapter来使用Gson反序列化Speedment实体。 这不仅可以在使用数据库内容的JSON表示时为我们提供更好的性能,而且还可以作为有关如何扩展代码生成器以解决问题的一般示例。

步骤1:创建插件项目

在上一篇文章中,我详细介绍了如何为Speedment创建新的插件,所以这里是简短的版本。 创建一个新的Maven项目并将Speedment和Gson设置为依赖项。

pom.xml

<name>Speedment Gson Plugin</name>
<description>A plugin for Speedment that generates Gson Type Adapters for every table in the database.
</description><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>1.8</maven.compiler.source><maven.compiler.target>1.8</maven.compiler.target><speedment.version>2.3.7</speedment.version>
</properties><dependencies><dependency><groupId>com.speedment</groupId><artifactId>speedment</artifactId><version>${speedment.version}</version></dependency><dependency><artifactId>gson</artifactId><groupId>com.google.code.gson</groupId><version>2.6.2</version></dependency>
</dependencies>

步骤2:为类型适配器创建翻译器类

接下来,我们需要创建将为我们生成新型适配器的转换器。 翻译器是一个类,它描述生成的文件将具有的名称,路径和内容。 为此,它提供了许多便利的方法来简化代码生成。 转换器的基本结构如下所示。

GeneratedTypeAdapterTranslator.java

...
public GeneratedTypeAdapterTranslator(Speedment speedment, Generator gen, Table table) {super(speedment, gen, table, Class::of);
}@Override
protected Class makeCodeGenModel(File file) {return newBuilder(file, getClassOrInterfaceName()).forEveryTable((clazz, table) -> {// Code generation goes here}).build();
}@Override
protected String getClassOrInterfaceName() {return "Generated" + getSupport().typeName() + "TypeAdapter";
}@Override
protected String getJavadocRepresentText() {return "A Gson Type Adapter";
}@Override
public boolean isInGeneratedPackage() {return true;
}
...

每个转换器都是使用可使用newBuilder()方法调用的构建器模式构建的。 稍后在我们要修改现有翻译器时,这一点变得很重要。 实际的代码在构建器的forEveryTable()方法内部生成。 这是一个回调,将针对感兴趣范围中遇到的每个表执行该回调。 在这种情况下,翻译器一次只能在一个表上执行,因此回调将只执行一次。

有关GeneratedTypeAdapterTranslator-class的完整资源,请转到此github页面 。

步骤3:创建用于修改管理器界面的装饰器

但是,仅生成一堆TypeAdapter是不够的。 我们希望将新代码集成到已经存在的管理器中。 为此,我们需要定义一个装饰器,该装饰器将在执行默认逻辑后应用于每个生成的管理器。

GeneratedManagerDecorator.java

public final class GeneratedManagerDecorator 
implements TranslatorDecorator<Table, Interface> {@Overridepublic void apply(JavaClassTranslator<Table, Interface> translator) {translator.onMake((file, builder) -> {builder.forEveryTable(Translator.Phase.POST_MAKE, (clazz, table) -> {clazz.add(Method.of("fromJson", translator.getSupport().entityType()).add(Field.of("json", STRING)));});});}
}

装饰器与翻译器类似,不同之处在于它仅定义应对现有文件进行的更改。 每个装饰器都在特定阶段执行。 在本例中,我们要在生成默认代码后执行,因此我们选择POST_MAKE。 我们要添加的逻辑很简单。 在接口中,我们需要fromJson(String)的其他方法。 我们不需要定义toJson,因为每个Speedment管理器都已经从继承的接口获得了toJson。

步骤4:创建用于修改Manager实施的装饰器

管理器实现的修改有些棘手。 我们需要为其添加一个Gson实例作为成员变量,刚刚添加的新接口方法的实现,使用Gson而不是内置序列化器的toJson方法的替代,并且我们需要修改manager构造函数使用我们的新TypeAdapter实例化Gson。

GeneratedManagerImplDecorator.java

public final class GeneratedManagerImplDecorator 
implements TranslatorDecorator<Table, Class> {@Overridepublic void apply(JavaClassTranslator<Table, Class> translator) {final String entityName = translator.getSupport().entityName();final String typeAdapterName = "Generated" + entityName + "TypeAdapter";final String absoluteTypeAdapterName =translator.getSupport().basePackageName() + ".generated." + typeAdapterName;Final Type entityType = translator.getSupport().entityType();translator.onMake((file, builder) -> {builder.forEveryTable(Translator.Phase.POST_MAKE, (clazz, table) -> {// Make sure GsonBuilder and the generated type adapter // are imported.file.add(Import.of(Type.of(GsonBuilder.class)));file.add(Import.of(Type.of(absoluteTypeAdapterName)));// Add a Gson instance as a private memberclazz.add(Field.of("gson", Type.of(Gson.class)).private_().final_());// Find the constructor and define gson in itclazz.getConstructors().forEach(constr -> {constr.add("this.gson = new GsonBuilder()",indent(".setDateFormat(\"" + DATE_FORMAT + "\")"),indent(".registerTypeAdapter(" + entityName + ".class, new " + typeAdapterName + "(this))"),indent(".create();"));});// Override the toJson()-methodclazz.add(Method.of("toJson", STRING).public_().add(OVERRIDE).add(Field.of("entity", entityType)).add("return gson.toJson(entity, " + entityName + ".class);"));// Override the fromJson()-methodclazz.add(Method.of("fromJson", entityType).public_().add(OVERRIDE).add(Field.of("json", STRING)).add("return gson.fromJson(json, " + entityName + ".class);"));});});}
}

步骤5:将所有新类安装到平台中

创建所有新类后,我们需要创建一个组件和一个组件安装程序,可以从要使用该插件的任何项目中引用该组件和组件安装程序。

GsonComponent.java

public final class GsonComponent extends AbstractComponent {public GsonComponent(Speedment speedment) {super(speedment);}@Overridepublic void onResolve() {final CodeGenerationComponent code = getSpeedment().getCodeGenerationComponent();code.put(Table.class, GeneratedTypeAdapterTranslator.KEY, GeneratedTypeAdapterTranslator::new);code.add(Table.class, StandardTranslatorKey.GENERATED_MANAGER, new GeneratedManagerDecorator());code.add(Table.class,StandardTranslatorKey.GENERATED_MANAGER_IMPL, new GeneratedManagerImplDecorator());}@Overridepublic Class<GsonComponent> getComponentClass() {return GsonComponent.class;}@Overridepublic Software asSoftware() {return AbstractSoftware.with("Gson Plugin", "1.0", APACHE_2);}@Overridepublic Component defaultCopy(Speedment speedment) {return new GsonComponent(speedment);}
}

GsonComponentInstaller.java

public final class GsonComponentInstaller 
implements ComponentConstructor<GsonComponent> {@Overridepublic GsonComponent create(Speedment speedment) {return new GsonComponent(speedment);}
}

用法

当我们想在项目中使用我们的新插件时,我们只需将其添加为pom中的依赖项部分中的依赖项,以及作为speedment maven插件下的依赖项。 然后,我们向插件添加配置标签,如下所示:

<plugin><groupId>com.speedment</groupId><artifactId>speedment-maven-plugin</artifactId><version>${speedment.version}</version><dependencies><dependency><groupId>com.speedment.plugins</groupId><artifactId>gson</artifactId><version>1.0.0</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.39</version></dependency></dependencies><configuration><components><component implementation="com.speedment.plugins.gson.GsonComponentInstaller" /></components></configuration>
</plugin>

然后,我们可以重新生成代码,然后应该可以访问新的序列化和反序列化逻辑。

final String pippi = "{" + "\"id\":1," +"\"bookId\":-8043771945249889258," +"\"borrowedStatus\":\"AVAILABLE\"," + "\"title\":\"Pippi Långström\"," + "\"authors\":\"Astrid Lindgren\"," + "\"published\":\"1945-11-26\"," + "\"summary\":\"A story about the world's strongest little girl.\"" + "}";books.fromJson(pippi).persist();

摘要

在本文中,我们创建了一个新的Speedment插件,该插件为数据库中的每个表生成了Gson TypeAdapters,并将这些适配器与现有的管理器集成在一起。 如果您想要更多有关如何使用Speedment代码生成器来提高生产力的示例, 请查看GitHub页面 !

直到下一次!

翻译自: https://www.javacodegeeks.com/2016/10/insert-read-database-using-json.html

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

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

相关文章

C语言pow()函数:求x的y次方(次幂)

1、头文件&#xff1a;#include2、原型&#xff1a;double pow(double x, double y);pow() 函数用来求 x 的 y 次幂&#xff08;次方&#xff09; pow()用来计算以x 为底的 y 次方值&#xff0c;然后将结果返回。设返回值为 ret&#xff0c;则 ret xy。 3、可能导致错误的…

本周学习总结JAVA

6. 为如下代码加上异常处理 byte[] content null; FileInputStream fis new FileInputStream("testfis.txt"); int bytesAvailabe fis.available();//获得该文件可用的字节数 if(bytesAvailabe>0){content new byte[bytesAvailabe];//创建可容纳文件大小的数组…

Day18 226翻转二叉树 101对称二叉树 100相同的树 572另一棵树的子树

226 翻转二叉树 递归前序遍历和后序遍历&#xff1a; class Solution { public:void swap(TreeNode*&a,TreeNode*&b){TreeNode*tmp a;a b;b tmp;}void reverseTree(TreeNode* cur){if(curnullptr) return;swap(cur->left,cur->right);reverseTree(cur->l…

python删除列表中字符串_python - 删除字符串中的字符列表

如果您正在使用python2并且您的输入是字符串(不是unicodes)&#xff0c;那么绝对最好的方法是remove_chars_translate_bytes&#xff1a;>>> chars_to_remove [., !, ?]>>> subj A.B!C?>>> subj.translate(None, .join(chars_to_remove))ABC否则…

C语言的格式控制符问题

写C程序遇到这样一个问题&#xff0c;定义了double变量&#xff0c;printf输出却要%f。一直以为应该用%lf&#xff0c;事实上VC6.0用%lf会报错。原因还要在探究。 贴吧有人说&#xff1a;double变量&#xff0c;scanf时必须用%lf&#xff0c;printf时要用%f或者%lf&#xff08;…

php无法用mail函数发送邮件之原因

[导读]PHP 需要一个已安装且正在运行的邮件系统&#xff0c;以便使邮件函数mail()可用。所用的邮件系统程序通过在 php.ini 文件中进行设置。用如下代码发送邮件&#xff0c;可总是发送失败。 [php] view plaincopyprint? 01.<?php 02.$to "xxxxxxxxqq.com";…

Linux内核设计与实现 总结笔记(第五章)系统调用

系统调用 内核提供了用户进程和内核交互的接口&#xff0c;使得应用程序可以受限制的访问硬件设备。 提供这些接口主要是为了保证系统稳定可靠&#xff0c;避免应用程序恣意妄行。 一、内核通信 系统调用在用户空间进程和硬件设备之间添加中间才能。作用有三&#xff1a; 为用户…

爬虫软件python彻底卸载_Python爬虫实践:如何优雅地删除豆瓣小组的帖子

前言文章起源于自己的一个需求&#xff1a;想要删除掉自己的若干个小号在豆瓣小组上的发帖及回复记录。这是一件看似简单的事情&#xff0c;但是一遍一遍的重复操作实在让我感到非常绝望&#xff0c;特别是删除自己的回复时&#xff0c;有时候回复的帖子的回复有好几十页&#…

高斯卷积核如何生成 C语言实现

对于学图像专业的人来说&#xff0c;对图像进行高斯滤波应该不会陌生&#xff0c;本质上就是将图像与高斯核进行卷积。 但是高斯核是如何生成的呢。matlab中有函数能自动生成高斯卷积核&#xff1a; gsfspecial(gaussian,3,1) gs 0.0751 0.1238 0.0751 0.1238 0.…

连接MySQL数据库时常见故障问题的分析与解决

连接MySQL数据库时常见故障问题的分析与解决 初学的mysql网友好象经常会碰到mysql无法连接的错误。特开贴收集这样问题的现象和原因。 先自己扔块砖头出来。 归纳如下&#xff1a; 故障现象 : 无法连接 mysql 错误信息1 &#xff1a;ERROR 1045 (28000): Access deni…

如何判断两个平面相交_七年级下册相交线与平行线全章节复习

5.1 相交线(一)相交线两条直线相交&#xff0c;形成4个角。1、两条直线相交所成的四个角中&#xff0c;相邻的两个角叫做邻补角&#xff0c;特点是两个角共用一条边&#xff0c;另一条边互为反向延长线&#xff0c;性质是邻补角互补&#xff1b;相对的两个角叫做对顶角&#xf…

spring dao层注解_Spring– DAO和服务层

spring dao层注解欢迎来到Spring教程的第三部分。 在这一部分中&#xff0c;我们将继续编写Timesheet应用程序&#xff0c;这次我们将实现DAO层&#xff0c;业务服务并编写一些测试。 在上一部分中&#xff0c;我们定义了GenericDao接口&#xff0c;该接口告诉我们需要对实体执…

Word 2007 如何自动生成目录以及设置正文第一页?

首先&#xff0c;讲解如何生成目录。 第一步&#xff0c;设置目录的小结的题目。这个需要对一级标题&#xff0c;二级标题&#xff0c;三级标题进行设置&#xff0c;设置方法如下图所示&#xff1a; 可以点击右键&#xff0c;对标题的格式进行修改。 第二步&#xff0c;直接生成…

python 优先队列_python中使用优先队列

相信对于队列的概念大家都不会陌生&#xff0c;这种先入先出的数据结构应用很广泛&#xff0c;像一般的生产消费都会用到队列&#xff0c;关于Queue的用法介绍可以参考我之前的文章 python中的Queue与多进程&#xff08;multiprocessing&#xff09;还有栈&#xff0c;栈是一种…

JHipster入门,第2部分

所以你回来了&#xff01; 在本系列的最后一部分中 &#xff0c;我们采用了单片路线创建了一个JHipster应用程序。 这是红色药丸路线&#xff1b; 生活与您习惯的差不多。 但是也许您喜欢挑战。 也许您想超越红色药丸并尝试蓝色药丸。 在这种情况下&#xff0c;Blue Pill是微服…

由于html元素加载导致的问题

js中要求执行的事件是在完全加载完&#xff0c;但由于本地环境测试一直没发现出问题&#xff0c;在上线后由于网络延迟导致元素加载慢&#xff0c;而事件执行完&#xff0c;没达到预期目标。 这时就需要用到属性 readyState readyState 属性返回当前文档的状态&#xff08;载入…

Linux下MySQL数据库常用基本操作 一

1、显示数据库 show databases; 2、选择数据库 use 数据库名; 3、显示数据库中的表 show tables; 4、显示数据表的结构 describe 表名; 5、显示表中记录 SELECT * FROM 表名 6、建库 create databse 库名; 7、建表 create table 表名 (字段设定列表)&#xff1b;mysql> cr…

C语言读取txt文档中的数据

1.说明 txt文档中的数据格式&#xff1a;前后数据用空格隔开&#xff1b;数据来源&#xff1a;matlab读取彩图的R、G、B三层的像素值&#xff0c;分别存放在三个txt文档中&#xff0c;用C读取到一维数组。动态申请数组&#xff0c;还是需要预先知道数组的大小&#xff0c;比静态…

cpickle支持的python版本_Python序列化模块pickle和cPickle

Python的序列化是指把变量从内存中变为可以储存/传输的数据/文件的过程. 在Python中叫pickling&#xff0c;在其他语言中也被称之为serialization&#xff0c;marshalling&#xff0c;flattening等等&#xff0c;都是一个意思。序列化之后&#xff0c;就可以把序列化后的内容写…

Intellij IDEA 4种配置热部署的方法

Intellij IDEA 4种配置热部署的方法 热部署可以使的修改代码后&#xff0c;无须重启服务器&#xff0c;就可以加载更改的代码。 第1种&#xff1a;修改服务器配置&#xff0c;使得IDEA窗口失去焦点时&#xff0c;更新类和资源 菜单Run -> EditConfiguration , 然后配置指定服…