jooq映射原理_JOOQ事实:从JPA批注到JOOQ表映射

jooq映射原理

JOOQ是一个简洁的框架,它解决了我在使用高级动态过滤查询时遇到的一个长期问题。 尽管Hibernate和JPA附带了一个有用的Criteria API(我已经使用了很长一段时间),但是您可以使用这些API进行操作有一些可以理解的限制。 例如,您不能超出简单SQL操作(例如,JOINS,NESTED SLECTS,AGGREGATION)并执行类似的操作: 窗口函数 , 用户定义的函数或简单的排序等 。

JOOQ不想和Hibernate竞争,但我觉得它可以完成它。 我一直在将Hibernate用于数据层的WRITE部分,因此使用它的名称或JPA中的“ Persisting”部分。 对于简单到中等复杂的查询,Hibernate会尽力而为,但是我不必仅依靠它来进行所有查询,是吗? 查询属性还有一个缺点,这是因为有时为了仅针对少数用例进行查询,有时必须向域模型添加关联。

因此,由于我不怕编写本机查询,因此可以以DSL方式和独立于供应商的方式来执行此操作。

尽管可以使用基于字符串的列命名,但JOOQ通过使用类型安全的元数据提供了一种更好的方法,因此,我们要做的第一件事是为数据库架构生成表映射。

由于我已经有了JPA模型,因此可以从中生成数据库模式DDL,为此,我们可以使用hibernatetool ant任务。

<plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-antrun-plugin</artifactId><executions><execution><id>generate-test-sql-scripts</id><phase>generate-test-resources</phase><goals><goal>run</goal></goals><configuration><tasks><property name="maven_test_classpath" refid="maven.test.classpath"/><path id="hibernate_tools_path"><pathelement path="${maven_test_classpath}"/></path><property name="hibernate_tools_classpath" refid="hibernate_tools_path"/><taskdef name="hibernatetool"classname="org.hibernate.tool.ant.HibernateToolTask"/><mkdir dir="${project.build.directory}/test-classes/hsqldb"/><hibernatetool destdir="${project.build.directory}/test-classes/hsqldb"><classpath refid="hibernate_tools_path"/><jpaconfiguration persistenceunit="testPersistenceUnit"propertyfile="src/test/resources/META-INF/spring/jdbc.properties"/><hbm2ddl drop="false" create="true" export="false"outputfilename="create_db.sql"delimiter=";" format="true"/><hbm2ddl drop="true" create="false" export="false"outputfilename="drop_db.sql"delimiter=";" format="true"/></hibernatetool></tasks></configuration></execution></executions><dependencies><dependency><groupId>org.hibernate</groupId><artifactId>hibernate-entitymanager</artifactId><version>${hibernate.version}</version><exclusions><exclusion><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.hibernate</groupId><artifactId>hibernate-tools</artifactId><version>${hibernate.tools.version}</version><exclusions><exclusion><groupId>org.hibernate</groupId><artifactId>hibernate-commons-annotations</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>${slf4j.version}</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-simple</artifactId><version>${slf4j.version}</version></dependency></dependencies>
</plugin>

这将生成一个“ create_db.sql”数据库DDL脚本,我们将使用“ maven.sql.plugin”将其用于填充基于文件的临时HSQLDB。 我本来希望使用内存中的HSQLDB,但不幸的是它没有保存插件执行之间的状态。

<plugin><groupId>org.codehaus.mojo</groupId><artifactId>sql-maven-plugin</artifactId><dependencies><dependency><groupId>org.hsqldb</groupId><artifactId>hsqldb</artifactId><version>${hsqldb.version}</version></dependency></dependencies><configuration><driver>org.hsqldb.jdbc.JDBCDriver</driver><url>jdbc:hsqldb:file:${project.build.directory}/hsqldb/db;shutdown=true</url><username>sa</username><password></password><autocommit>true</autocommit><settingsKey>hsql-db-test</settingsKey></configuration><executions><execution><id>create-test-compile-data</id><phase>process-test-resources</phase><inherited>true</inherited><goals><goal>execute</goal></goals><configuration><orderFile>ascending</orderFile><fileset><basedir>${project.build.directory}/test-classes/hsqldb/</basedir><includes><include>create_db.sql</include></includes></fileset><autocommit>true</autocommit></configuration></execution></executions>
</plugin>

因此,现在用我们的JPA生成的模式填充了HSQLDB,我们最终可以调用JOOQ代码生成来构建表映射。

<plugin><groupId>org.jooq</groupId><artifactId>jooq-codegen-maven</artifactId><executions><execution><phase>process-test-classes</phase><goals><goal>generate</goal></goals></execution></executions><dependencies><dependency><groupId>org.hsqldb</groupId><artifactId>hsqldb</artifactId><version>${hsqldb.version}</version></dependency></dependencies><configuration><jdbc><driver>org.hsqldb.jdbc.JDBCDriver</driver><url>jdbc:hsqldb:file:${project.build.directory}/hsqldb/db</url><user>sa</user><password></password></jdbc><generator><name>org.jooq.util.JavaGenerator</name><database><name>org.jooq.util.hsqldb.HSQLDBDatabase</name><includes>.*</includes><excludes></excludes><inputSchema>PUBLIC</inputSchema></database><generate></generate><target><packageName>vladmihalcea.jooq.schema</packageName><directory>target/generated-sources/jooq</directory></target></generator></configuration>
</plugin>

通过maven运行,我们生成了表映射,因此让我们将Image类的JPA元模型与关联的JOOQ表映射进行比较:

JPA元模型如下所示:

@StaticMetamodel(Image.class)
public abstract class Image_ {public static volatile SingularAttribute<Image, Product> product;public static volatile SingularAttribute<Image, Long> id;public static volatile SetAttribute<Image, Version> versions;public static volatile SingularAttribute<Image, Integer> index;public static volatile SingularAttribute<Image, String> name;}

和JOOQ表映射

@javax.annotation.Generated(value    = { "http://www.jooq.org", "3.2.0" },comments = "This class is generated by jOOQ")
@java.lang.SuppressWarnings({ "all", "unchecked", "rawtypes" })
public class Image extends org.jooq.impl.TableImpl<vladmihalcea.jooq.schema.tables.records.ImageRecord> {private static final long serialVersionUID = 1596930978;/*** The singleton instance of <code>PUBLIC.IMAGE</code>*/public static final vladmihalcea.jooq.schema.tables.Image IMAGE = new vladmihalcea.jooq.schema.tables.Image();/*** The class holding records for this type*/@Overridepublic java.lang.Class<vladmihalcea.jooq.schema.tables.records.ImageRecord> getRecordType() {return vladmihalcea.jooq.schema.tables.records.ImageRecord.class;}/*** The column <code>PUBLIC.IMAGE.ID</code>. */public final org.jooq.TableField<vladmihalcea.jooq.schema.tables.records.ImageRecord, java.lang.Long> ID = createField("ID", org.jooq.impl.SQLDataType.BIGINT.nullable(false), this);/*** The column <code>PUBLIC.IMAGE.INDEX</code>. */public final org.jooq.TableField<vladmihalcea.jooq.schema.tables.records.ImageRecord, java.lang.Integer> INDEX = createField("INDEX", org.jooq.impl.SQLDataType.INTEGER, this);/*** The column <code>PUBLIC.IMAGE.NAME</code>. */public final org.jooq.TableField<vladmihalcea.jooq.schema.tables.records.ImageRecord, java.lang.String> NAME = createField("NAME", org.jooq.impl.SQLDataType.VARCHAR.length(255), this);/*** The column <code>PUBLIC.IMAGE.PRODUCT_ID</code>. */public final org.jooq.TableField<vladmihalcea.jooq.schema.tables.records.ImageRecord, java.lang.Long> PRODUCT_ID = createField("PRODUCT_ID", org.jooq.impl.SQLDataType.BIGINT, this);/*** Create a <code>PUBLIC.IMAGE</code> table reference*/public Image() {super("IMAGE", vladmihalcea.jooq.schema.Public.PUBLIC);}/*** Create an aliased <code>PUBLIC.IMAGE</code> table reference*/public Image(java.lang.String alias) {super(alias, vladmihalcea.jooq.schema.Public.PUBLIC, vladmihalcea.jooq.schema.tables.Image.IMAGE);}/*** {@inheritDoc}*/@Overridepublic org.jooq.Identity<vladmihalcea.jooq.schema.tables.records.ImageRecord, java.lang.Long> getIdentity() {return vladmihalcea.jooq.schema.Keys.IDENTITY_IMAGE;}/*** {@inheritDoc}*/@Overridepublic org.jooq.UniqueKey<vladmihalcea.jooq.schema.tables.records.ImageRecord> getPrimaryKey() {return vladmihalcea.jooq.schema.Keys.SYS_PK_10059;}/*** {@inheritDoc}*/@Overridepublic java.util.List<org.jooq.UniqueKey<vladmihalcea.jooq.schema.tables.records.ImageRecord>> getKeys() {return java.util.Arrays.<org.jooq.UniqueKey<vladmihalcea.jooq.schema.tables.records.ImageRecord>>asList(vladmihalcea.jooq.schema.Keys.SYS_PK_10059, vladmihalcea.jooq.schema.Keys.UK_OQBG3YIU5I1E17SL0FEAWT8PE);}/*** {@inheritDoc}*/@Overridepublic java.util.List<org.jooq.ForeignKey<vladmihalcea.jooq.schema.tables.records.ImageRecord, ?>> getReferences() {return java.util.Arrays.<org.jooq.ForeignKey<vladmihalcea.jooq.schema.tables.records.ImageRecord, ?>>asList(vladmihalcea.jooq.schema.Keys.FK_9W522RC4D0KFDKQ390IHV92GB);}/*** {@inheritDoc}*/@Overridepublic vladmihalcea.jooq.schema.tables.Image as(java.lang.String alias) {return new vladmihalcea.jooq.schema.tables.Image(alias);}
}

现在,我们还需要使Maven意识到我们新生成的JOOQ元数据类,以便它可以在下一个测试编译阶段对其进行编译。

<plugin><groupId>org.codehaus.mojo</groupId><artifactId>build-helper-maven-plugin</artifactId><executions><execution><id>add-source</id><phase>process-test-sources</phase><goals><goal>add-test-source</goal></goals><configuration><sources><source>${project.build.directory}/generated-sources/java</source></sources></configuration></execution></executions>
</plugin>

现在,我可以开始玩JOOQ了。 让我们将DSLContext添加到我们的Spring应用程序上下文中:

<bean id="jooqContext" class="org.jooq.impl.DSL" factory-method="using"><constructor-arg ref="dataSource"/><constructor-arg value="#{T(org.jooq.SQLDialect).HSQLDB}"/>
</bean

我们将编写一个测试来检查一切是否正常:

private List<ImageProductDTO> getImageProductDTOs_JOOQ() {return transactionTemplate.execute(new TransactionCallback<List<ImageProductDTO>>() {@Overridepublic List<ImageProductDTO> doInTransaction(TransactionStatus transactionStatus) {return jooqContext.select(IMAGE.NAME, PRODUCT.NAME).from(IMAGE).join(PRODUCT).on(IMAGE.PRODUCT_ID.equal(PRODUCT.ID)).where(PRODUCT.NAME.likeIgnoreCase("%tv%")).and(IMAGE.INDEX.greaterThan(0)).orderBy(IMAGE.NAME.asc()).fetch().into(ImageProductDTO.class);}});
}

生成以下SQL

SELECT "PUBLIC"."image"."name","PUBLIC"."product"."name"
FROM     "PUBLIC"."image"JOIN "PUBLIC"."product"ON "PUBLIC"."image"."product_id" = "PUBLIC"."product"."id"
WHERE   ( Lower("PUBLIC"."product"."name") LIKE Lower('%tv%')AND "PUBLIC"."image"."index" > 0 )
ORDER   BY "PUBLIC"."image"."name" ASC

这是我第一次使用JOOQ,并且不需要花太多时间浏览文档并在Hibernate Facts编码示例中进行所有设置。 JOOQ查询的构建感觉很自然,就像编写本机SQL代码一样,因此我不必真正学习API就能知道如何使用它。 我将很自豪地将其添加到我的Java Data Toolbox中。

这个编码示例将JOOQ映射生成到test-classes文件夹中,因此您不能在main / java源文件中使用它们。 这可以解决,但是需要通过将模型类移动到单独的Maven模块中来重构现有解决方案。 您可以在此单独的模块中生成JOOQ模式,在打包之前,您可以在其中将模式类从测试类移至classes文件夹。 然后,您将必须包含这个新模块,通常在其中使用JOOQ模式。

参考: JOOQ事实:从JPA注释到我们的JCG合作伙伴 Vlad Mihalcea在Vlad Mihalcea博客博客上的JOOQ 表映射 。

翻译自: https://www.javacodegeeks.com/2013/12/jooq-facts-from-jpa-annotations-to-jooq-table-mappings.html

jooq映射原理

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

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

相关文章

c语言开发工具程序代码是什么文件,【C语言】开发工具--GCC使用入门

来自&#xff1a; 51CTO GCC使用入门通常所说的GCC是GUN Compiler Collection的简称&#xff0c;除了编译程序之外&#xff0c;它还含其他相关工具&#xff0c;所以它能把易于人类使用的高级语言编写的源代码构建成计算机能够直接执行的二进制代码。GCC是Linux平台下最常用的编…

【渝粤教育】广东开放大学 文学创意写作 形成性考核 (58)

选择题 题目&#xff1a;“熟读唐诗三百首&#xff0c;不会吟诗也会吟”&#xff0c;说明阅读对于写作的作用之重要。 题目&#xff1a;从写作者的主观角度来看&#xff0c;文本思想体现着写作者的写作意图和写作目的。 题目&#xff1a;所谓结构&#xff0c;简单说就是文本内部…

【渝粤题库】广东开放大学标准文献检索与应用 形成性考核

选择题 题目&#xff1a;按文献出版的类型分&#xff1a;图书、期刊、 。 题目&#xff1a;按文献载体种类分&#xff1a;印刷型文献、缩微型文献、机读型文献、 、实物型。 题目&#xff1a;检索的手段包括 题目&#xff1a;检索系统的类型&am…

无服务器安全性:将其置于自动驾驶仪上

Ack &#xff1a;本文是从个人经验以及从无服务器安全性的其他多个来源学到的东西的混合。 我无法在这里列出或确认所有这些信息&#xff1b; 但是&#xff0c;应该特别感谢The Register &#xff0c; Hacker Noon &#xff0c; PureSec以及Serverless Status和Serverless&…

c语言构造报文,构造一个缓冲区溢出的C语言的例子

满意答案wk05122013.06.01采纳率&#xff1a;45% 等级&#xff1a;12已帮助&#xff1a;15719人#include #include #include void function(char *str){char buffer[16];strcpy(buffer, str);}void evilfunc(){printf("Am I Evil?\n");}int main(int argc, char*…

【渝粤题库】陕西师范大学152113 统计学 作业

《统计学》作业 一、单项选择题 1、“统计”一词的三种含义是&#xff08; &#xff09;。 A. 统计调查、统计整理、统计分析 B. 统计工作、统计资料、统计学 C. 统计信息、统计咨询、统计监督 D. 统计理论、统计方法、统计技能 2、社会统计的研究对象是&#xff08; &#xff…

【渝粤题库】陕西师范大学180212 定价理论与策略 作业(专升本)

《价格理论与实务》作业 一、单选题 1、当一切商品的价值共同表现在充当一般等价物的商品上时&#xff0c;此时的价值形式就是( )。 A&#xff0e;简单价值形式 B&#xff0e;扩大的价值形式 C&#xff0e;一般价值形式 D&#xff0e;货币价值形式 2、各种商品价格之间相互衔接…

android自动退出对话框,Android开发 在用EditText对话框Dialog退出后实现输入盘的退出...

前言在使用继承的Dialog的方式实现自定义Dialog&#xff0c;如果这个Dialog我们还添加了EditText就会发现一个问题。在输入盘显示后&#xff0c;Dialog退出输入盘不会退出。网上有一些奇怪的解决办法&#xff0c;最奇怪的是去根据Touch事件判断Touch坐标来确定是否点击了空白在…

【渝粤题库】陕西师范大学200481 高级英语(一)

《高级英语(一)》作业 I. Explain the italicized words in English 1.The very act …was for me a far greater adventure than any trip or any reportorial assignment I’d previously taken. 2.Others were using little red telephones that hung on the facades of gro…

mongodb插入速度每秒_MongoDB事实:商品硬件上每秒插入80000次以上

mongodb插入速度每秒在尝试一些时间序列集合时&#xff0c;我需要一个大型数据集来检查我们的聚合查询在增加数据负载的情况下不会成为瓶颈。 我们解决了5000万份文档&#xff0c;因为超出此数目我们仍然会考虑分片。 每次事件如下所示&#xff1a; {"_id" : Objec…

【渝粤题库】陕西师范大学201691 日语(二) 作业

一、按要求标注&#xff1a; &#xff08;一&#xff09;给下列汉字注上假名 1、全部   2、世紀   3、政治    4、文化   5、空港  6、生活   7、本棚   8、工夫    9、意見   10、理科 11、案内  12、相談   13、満足   14、社会  15、都会 …

parallels for linux,在 Parallels Desktop 上安装 Remix OS PC

前言个人觉得呢&#xff0c;像 Remix OS 和 Phoenix OS 这样的国产安卓桌面操作系统还是很划时代的。赋予了安卓平台多任务操作的能力&#xff0c;这可以给二合一设备的体验带来一定的变化&#xff0c;但是不像 Surface 一样后面有巨硬给撑腰可以做大做强起来&#xff0c;但是这…

【渝粤题库】陕西师范大学210014幼儿园科学教育作业(高起专)

《幼儿园科学教育》作业 一、填空题 1&#xff0e;科学教育中常采用的观察方法是 ① 、 ② 、 ③ 。 2&#xff0e;幼儿劳动的种类包括 ① 、 ② 、 ③ 、 ④ 。 3&#xff0e;在幼儿科学教育中&#xff0c;情感的目标非常广泛。《纲要》突出了其中两个方面&#xff1a; ① 、 …

模拟用户输入并检查输出的简单方法

最近&#xff0c;我的一些学生向我询问了赫尔辛基大学MOOC提供的单元测试的机制&#xff0c;我检查了它们的实现&#xff0c;并认为这对于初学者了解实际发生的情况是有帮助的&#xff0c;因此在此发表了这篇小文章。 我们将以“机场”项目为例&#xff0c;这是OOP2第一周的最…

android bench内存测试,华为p10内存测试软件(androbench) v5.0.1 免费版

华为p10内存测试软件(androbench)其实是androbench这款内存测试软件&#xff0c;可以用于测试你的华为p10&#xff0c;是一款不错的华为p10内存测试软件&#xff0c;可以测试你的手机闪存性能&#xff0c;其他的手机也可以免费测试哦。华为p10内存测试软件介绍AndroBench是衡量…

【渝粤题库】陕西师范大学400011 思想政治教育学科教学论 作业(专升本)

《思想政治学科教学论》作业 一、多选择题 在下列选项中至少有一项是符合题目要求的 &#xff11;、思想政治学科教学论的学科特点包括&#xff1a; A&#xff0e;社会性 B&#xff0e;综合性 C &#xff0e;实践性 D&#xff0e;系统性   E&#xff0e;完整性 &#xff12;、…

【渝粤题库】陕西师范大学700007 生态学

《生态学》作业 一、名词解释 Meta-种群生态系统次生演替边缘效应初级生产量可持续发展岛屿效应主导因子种群空间分布格局营养级物种多样性生态入侵耐性限度生态位光周期现象趋同适应生态恢复同资源种团原生演替协同进化食物链生态平衡繁殖成效内禀增长率 二、简答题简述丹麦学…

android对话框字体大小,Android Dialog 设置字体大小的具体方法

先看下面图片&#xff1a;这是我在做登录页面的时候&#xff0c;调用系统的progressdialog 进行等待&#xff0c;可是看起来很不协调&#xff0c;左边的等待图片过大&#xff0c;右边文字过小&#xff0c;看起来老别扭&#xff0c;虽然功能上不存在什么问题&#xff0c;但是我有…

国家开放大学2021春1062文学英语赏析题目

教育 教育 试卷代号&#xff1a; 1062 2021年春季学期期末统一考试 文学英语赏析 试题 2021年7月 注意事项 一、将你的学号、姓名及分校&#xff08;工作站&#xff09;名称填写在答题纸的规定栏内。考试结束后&#xff0c;把试卷和答题纸放在桌上。试卷和答题纸均不得带出考…

android custom toast,Android自定义Toast

核心代码&#xff1a;package com.huatec.myapplication;import android.content.Context;import android.graphics.Bitmap;import android.support.annotation.ColorInt;import android.support.annotation.DrawableRes;import android.view.Gravity;import android.view.Layo…