SpringBoot:与JOOQ合作

在上一篇文章SpringBoot:与MyBatis一起工作中,我们学习了如何使用SpringBoot MyBatis Starter快速启动并运行Spring和MyBatis。 在本文中,我们将学习如何使用SpringBoot JOOQ Starter。

JOOQ(面向Java对象的查询)是包含SQL的持久性框架。

JOOQ提供以下功能:

  • 使用DSL API构建Typesafe SQL
  • 使用代码生成引用Typesafe数据库对象
  • 易于使用的API用于查询和数据提取
  • SQL记录和调试等

SpringBoot提供了一个启动程序spring-boot-starter-jooq ,以便能够与JOOQ快速集成。

在本文中,我们将逐步介绍如何使用spring-boot-starter-jooq

步骤1:创建SpringBoot Maven项目

创建一个基于SpringBoot Maven的项目并配置spring-boot-starter-jooq依赖项。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.sivalabs</groupId><artifactId>springboot-jooq-demo</artifactId><packaging>jar</packaging><version>1.0-SNAPSHOT</version><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>1.3.3.RELEASE</version></parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><java.version>1.8</java.version></properties><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jooq</artifactId></dependency><dependency><groupId>com.h2database</groupId><artifactId>h2</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency></dependencies>
</project>

我们将首先使用H2内存数据库,稍后将了解如何使用MySQL。

步骤2:创建数据库初始化脚本。

我们将创建一个包含2个表的简单数据库。

src / main / resources / schema.sql

DROP TABLE IF EXISTS POSTS;CREATE TABLE POSTS (ID int(11) NOT NULL AUTO_INCREMENT,TITLE varchar(200) NOT NULL,CONTENT LONGTEXT DEFAULT NULL,CREATED_ON datetime DEFAULT NULL,PRIMARY KEY (ID)
);DROP TABLE IF EXISTS COMMENTS;CREATE TABLE COMMENTS (ID int(11) NOT NULL AUTO_INCREMENT,POST_ID int(11) NOT NULL, NAME varchar(200) NOT NULL,EMAIL varchar(200) NOT NULL,CONTENT LONGTEXT DEFAULT NULL,CREATED_ON datetime DEFAULT NULL,PRIMARY KEY (ID),FOREIGN KEY (POST_ID) REFERENCES POSTS(ID)
);

我们将使用data.sql脚本填充一些示例数据。

src / main / resources / data.sql

insert into posts(id, title, content, created_on) values(1, 'Post 1', 'This is post 1', '2016-01-03');
insert into posts(id, title, content, created_on) values(2, 'Post 2', 'This is post 2', '2016-01-05');
insert into posts(id, title, content, created_on) values(3, 'Post 3', 'This is post 3', '2016-01-07');insert into comments(id, post_id, name, email, content, created_on) 
values(1, 1, 'User1', 'user1@gmail.com', 'This is comment 1 on post 1', '2016-01-07');insert into comments(id, post_id, name, email, content, created_on) 
values(2, 1, 'User2', 'user2@gmail.com', 'This is comment 2 on post 1', '2016-01-07');insert into comments(id, post_id, name, email, content, created_on) 
values(3, 2, 'User1', 'user1@gmail.com', 'This is comment 1 on post 2', '2016-01-07');

步骤3:配置JOOQ Maven Codegen插件以生成数据库工件

我们将使用Maven配置文件根据数据库类型配置jooq-codegen-maven配置属性。

<profiles><profile><id>h2</id><build><plugins><plugin><groupId>org.jooq</groupId><artifactId>jooq-codegen-maven</artifactId><executions><execution><goals><goal>generate</goal></goals></execution></executions><dependencies><dependency><groupId>com.h2database</groupId><artifactId>h2</artifactId><version>${h2.version}</version></dependency></dependencies><configuration><jdbc><driver>org.h2.Driver</driver><url>jdbc:h2:~/springbootjooq</url></jdbc><generator><name>org.jooq.util.DefaultGenerator</name><database><name>org.jooq.util.h2.H2Database</name><includes>.*</includes><excludes /><inputSchema>PUBLIC</inputSchema></database><target><packageName>com.sivalabs.demo.jooq.domain</packageName><directory>gensrc/main/java</directory></target></generator></configuration></plugin></plugins></build></profile><profile><id>mysql</id><build><plugins><plugin><groupId>org.jooq</groupId><artifactId>jooq-codegen-maven</artifactId><executions><execution><goals><goal>generate</goal></goals></execution></executions><dependencies><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>${mysql.version}</version></dependency></dependencies><configuration><jdbc><driver>com.mysql.jdbc.Driver</driver><url>jdbc:mysql://localhost:3306/test</url><user>root</user><password>admin</password></jdbc><generator><name>org.jooq.util.DefaultGenerator</name><database><name>org.jooq.util.mysql.MySQLDatabase</name><includes>.*</includes><excludes /><inputSchema>test</inputSchema></database><target><packageName>com.sivalabs.demo.jooq.domain</packageName><directory>gensrc/main/java</directory></target></generator></configuration></plugin></plugins></build></profile>
</profiles>

我们已经使用适当的JDBC配置参数配置了两个配置文件( h2mysql )。

我们已指定生成代码工件,并将其放置gensrc / main / java目录下的 com.sivalabs.demo.jooq.domain包中。

我们可以如下运行激活H2mysql配置文件的Maven构建:

mvn clean install -P h2 (or)
mvn clean install -P mysql

步骤4:配置Maven build-helper-maven-plugin插件以将生成的源添加为sources文件夹

我们将配置build-helper-maven-plugin插件,以便maven将添加JOOQ生成的代码驻留在
gensrc / main / java目录作为源文件夹。

<plugin><groupId>org.codehaus.mojo</groupId><artifactId>build-helper-maven-plugin</artifactId><executions><execution><phase>generate-sources</phase><goals><goal>add-source</goal></goals><configuration><sources><source>gensrc/main/java</source></sources></configuration></execution></executions>
</plugin>

步骤5:创建域对象。

我们可以使用这些域对象在整个层上传递数据,并使用JOOQ生成的数据库工件与数据库进行对话。

public class Post
{private Integer id;private String title;private String content;private Timestamp createdOn;private List<Comment> comments = new ArrayList<>();//setters & getters}
public class Comment
{private Integer id;private Post post;private String name;private String email;private String content;private Timestamp createdOn;//setters & getters
}

步骤6:使用JOOQ实施数据持久化方法,如下所示。

package com.sivalabs.demo;import static com.sivalabs.demo.jooq.domain.tables.Posts.POSTS;
import static com.sivalabs.demo.jooq.domain.tables.Comments.COMMENTS;import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;import org.jooq.DSLContext;
import org.jooq.Record;
import org.jooq.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;import com.sivalabs.demo.entities.Comment;
import com.sivalabs.demo.entities.Post;
import com.sivalabs.demo.jooq.domain.tables.records.CommentsRecord;
import com.sivalabs.demo.jooq.domain.tables.records.PostsRecord;@Service
@Transactional
public class BlogService
{@Autowiredprivate DSLContext dsl;public Post createPost(Post post){PostsRecord postsRecord = dsl.insertInto(POSTS).set(POSTS.TITLE, post.getTitle()).set(POSTS.CONTENT, post.getContent()).set(POSTS.CREATED_ON, post.getCreatedOn()).returning(POSTS.ID).fetchOne();post.setId(postsRecord.getId());return post;}public List<Post> getAllPosts(){        List<Post> posts = new ArrayList<>();       Result<Record> result = dsl.select().from(POSTS).fetch();for (Record r : result) {posts.add(getPostEntity(r));}return posts ;}public Post getPost(Integer postId){Record record = dsl.select().from(POSTS).where(POSTS.ID.eq(postId)).fetchOne();if(record != null){Post post = getPostEntity(record);Result<Record> commentRecords = dsl.select().from(COMMENTS).where(COMMENTS.POST_ID.eq(postId)).fetch();for (Record r : commentRecords) {post.addComment(getCommentEntity(r));}return post;}return null;}public Comment createComment(Comment comment){CommentsRecord commentsRecord = dsl.insertInto(COMMENTS).set(COMMENTS.POST_ID, comment.getPost().getId()).set(COMMENTS.NAME, comment.getName()).set(COMMENTS.EMAIL, comment.getEmail()).set(COMMENTS.CONTENT, comment.getContent()).set(COMMENTS.CREATED_ON, comment.getCreatedOn()).returning(COMMENTS.ID).fetchOne();comment.setId(commentsRecord.getId());return comment;}public void deleteComment(Integer commentId){dsl.deleteFrom(COMMENTS).where(COMMENTS.ID.equal(commentId)).execute();}private Post getPostEntity(Record r){Integer id = r.getValue(POSTS.ID, Integer.class);String title = r.getValue(POSTS.TITLE, String.class);String content = r.getValue(POSTS.CONTENT, String.class);Timestamp createdOn = r.getValue(POSTS.CREATED_ON, Timestamp.class);return new Post(id, title, content, createdOn);}private Comment getCommentEntity(Record r) {Integer id = r.getValue(COMMENTS.ID, Integer.class);Integer postId = r.getValue(COMMENTS.POST_ID, Integer.class);String name = r.getValue(COMMENTS.NAME, String.class);String email = r.getValue(COMMENTS.EMAIL, String.class);String content = r.getValue(COMMENTS.CONTENT, String.class);Timestamp createdOn = r.getValue(COMMENTS.CREATED_ON, Timestamp.class);return new Comment(id, postId, name, email, content, createdOn);}
}

观察到我们正在将DSLContext实例自动连接到我们的Spring Bean中,并使用它来构建TypeSafe查询。

步骤7:创建入口点类和JUnit测试。

@SpringBootApplication
public class SpringbootJooqDemoApplication
{public static void main(String[] args) {SpringApplication.run(SpringbootJooqDemoApplication.class, args);}
}
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(SpringbootJooqDemoApplication.class)
public class SpringbootJooqDemoApplicationTests
{@Autowiredprivate BlogService blogService;@Testpublic void findAllPosts()  {List<Post> posts = blogService.getAllPosts();assertNotNull(posts);assertTrue(!posts.isEmpty());for (Post post : posts){System.err.println(post);}}@Testpublic void findPostById()  {Post post = blogService.getPost(1);assertNotNull(post);System.out.println(post);List<Comment> comments = post.getComments();System.out.println(comments);}@Testpublic void createPost() {Post post = new Post(0, "My new Post", "This is my new test post", new Timestamp(System.currentTimeMillis()));Post savedPost = blogService.createPost(post);Post newPost = blogService.getPost(savedPost.getId());assertEquals("My new Post", newPost.getTitle());assertEquals("This is my new test post", newPost.getContent());}@Testpublic void createComment() {Integer postId = 1;Comment comment = new Comment(0, postId, "User4", "user4@gmail.com", "This is my new comment on post1", new Timestamp(System.currentTimeMillis()));Comment savedComment = blogService.createComment(comment);Post post = blogService.getPost(postId);List<Comment> comments = post.getComments();assertNotNull(comments);for (Comment comm : comments){if(savedComment.getId() == comm.getId()){assertEquals("User4", comm.getName());assertEquals("user4@gmail.com", comm.getEmail());assertEquals("This is my new comment on post1", comm.getContent());}}}}

假设您已经使用H2概要文件生成了代码,那么我们可以在不进行任何进一步配置的情况下运行JUnit测试。

但是,如果使用mysql配置文件生成了代码,则必须在application.properties中配置以下属性。

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=adminspring.jooq.sql-dialect=MYSQL


请注意,我们应该为数据库使用正确的SqlDialect ,否则在运行时可能会遇到SQL语法错误。

  • 您可以在我的Github存储库中找到本文的源代码
    https://github.com/sivaprasadreddy/springboot-tutorials/tree/master/springboot-jooq-demo

有关JOOQ的更多信息,请访问http://www.jooq.org/learn/

翻译自: https://www.javacodegeeks.com/2016/03/springboot-working-jooq.html

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

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

相关文章

uni-app使用前的调研和开发心得

背景之前的工时系统是原生的小程序实现&#xff0c;由于产品逻辑需要优化&#xff0c;代码混乱又仅限微信平台使用&#xff0c;公司致力于想给工时系统重构后支持多平台&#xff0c;并对外开放使用&#xff0c;使之成为一款真正的商业产品。经过前期调研后&#xff0c;uni-app对…

EXPORT_SYMBOL使用

EXPORT_SYMBOL只出现在2.6内核中&#xff0c;在2.4内核默认的非static 函数和变量都会自动导入到kernel 空间的&#xff0c; 都不用EXPORT_SYMBOL() 做标记的。2.6就必须用EXPORT_SYMBOL() 来导出来&#xff08;因为2.6默认不到处所有的符号&#xff09;。 1、EXPORT_SYMBOL的…

技术人写作和写代码一样重要

也许当你老了会发出这样的感叹“曾经有无数条发财致富的道路摆在我面前&#xff0c;我不知道珍惜&#xff0c;现在老了才追悔莫及”。写技术文章无疑是做技术人工作之外一条很好的知识变现之路。而我也才最近顿悟&#xff0c;下定决心开始在coding的闲暇时间围绕自己的工作和兴…

ejb jsf jpa_完整的WebApplication JSF EJB JPA JAAS –第1部分

ejb jsf jpa这篇文章将是迄今为止我博客中最大的一篇文章&#xff01; 我们将看到完整的Web应用程序。 最新的技术&#xff08;直到今天&#xff09;都将完成&#xff0c;但是我将给出一些提示以显示如何使本文章适应较旧的技术。 在本文的结尾&#xff0c;您将找到要下载的源代…

Jzoj4782 Math

若一个数x是平方数&#xff0c;则d(x)为平方数 所以就是要考虑有多少对i*j为平方数 我们假设&#xff0c;ip*k^2&#xff0c;那么&#xff0c;jp*q^2时&#xff0c;i*j为平方数&#xff08;p不含平方因子&#xff0c;k&#xff0c;q为正整数&#xff09; 所以&#xff0c;我们对…

前端暗黑模式,你了解多少

关于使用越来越多的前端暗黑模式&#xff0c;手机的app或网站都将支持暗黑模式逐渐成为一种规范&#xff0c;这样做的目的是什么呢&#xff1f;从我最初的理解是为了在黑暗的环境下屏幕上阅读的体验考虑&#xff0c;但是看了文摘却有另一种意义。暗黑模式究竟能不能起到省电的作…

两全其美的

使用抽象文档模式的类型安全视图 您如何组织对象&#xff1f; 在本文中&#xff0c;我将介绍一种模式&#xff0c;该模式以无类型的方式在您的系统中组织所谓的名词类&#xff0c;然后使用特征公开数据的类型化视图。 这使得只需少量的牺牲就可以在Java之类的语言中获得JavaScr…

Windows内核函数

字符串处理 在驱动中一般使用的是ANSI字符串和宽字节字符串&#xff0c;在驱动中我们仍然可以使用C中提供的字符串操作函数&#xff0c;但是在DDK中不提倡这样做&#xff0c;由于C函数容易导致缓冲区溢出漏洞&#xff0c;针对字符串的操作它提供了一组函数分别用来处理ANSI字符…

前端应该关注的2021年UI设计趋势

UI设计趋势几乎每年都在发生变化&#xff0c;变化的原因是人们的审美在变导致的&#xff0c;还是设计越来越人性化。市场上是谁在主导设计趋势&#xff1f;其中原因不得而知&#xff0c;我们先看看究竟有哪些变化&#xff1a;1. 3D插图&#xff08;依然流行&#xff09;3D图像将…

如何让你在开发者工具中查看源代码有语法高亮和暗黑主题的效果

如何让你在Chrome浏览器开发者工具中查看源代码的时候&#xff0c;和在代码编辑器中有同样的代码语法高亮的效果&#xff0c;而且还是深色主题&#xff0c;如果你是深色主题的爱好者就更合你意了。国外的美女开发者为你实现了这样功能的浏览器拓展&#xff0c;她的Github主页&a…

Hitting refresh on my career(译)----重新定义我的事业

我是在PlanetXamarin这个网站上&#xff0c;看到的这篇文章&#xff0c;看完后&#xff0c;觉得挺能引起人的思考的,特别是我们广大程序员. "Hit Refresh"这两个单词&#xff0c;字面上理解&#xff1a;点击刷新按钮. 国内有人翻译为"拥抱变革",我觉得“拥…

冒泡排序 快速排序 插入排序 选择排序

最近面试好多公司考察算法&#xff0c;特意整理了一下&#xff1a; 1. 冒泡排序思路分析&#xff1a;在要排序的一组数中&#xff0c;对当前还未排好的序列&#xff0c;从前往后对相邻的两个数依次进行比较和调整&#xff0c;让较大的数往下沉&#xff0c;较小的往上冒。即&…

“太空语言”JavaScript编码标准规范指南

喷气推进实验室是 美国国家航空航天局的科研机构。 该实验室JPL开发大部分的软件是用在无人深度太空和其他行星探测的领域。他们拥有著名的 好奇号火星探测器 和 旅行者号探测器 。已经离开太阳系25年&#xff0c;仍然在飞行并提供科学信息。高水平的自动化和长期的任务导致了对…

如何在JUnit 5中替换规则

最近发布的JUnit 5&#xff08;又名JUnit Lambda&#xff09; Alpha版本引起了我的兴趣&#xff0c;在浏览文档时&#xff0c;我注意到规则以及跑步者和阶级规则都消失了。 根据文档&#xff0c;这些部分竞争的概念已被单个一致的扩展模型取代。 多年来&#xff0c; Frank和我…

sikuli 搜索例子

#coding:utf-8kw input(u"请输入您要搜索的关键字:")#openAPP(‪C:\Users\ceshi\AppData\Local\Google\Chrome\Application\chrome.exe)doubleClick("asm.png")wait("fEDi.png")type(Key.CTRL)type(www.baidu.com)type(Key.TAB)sleep(1)type(kw…

微页面设计开发指南

一、目标实现左侧&#xff1a;为可用的组件列表&#xff0c;可拖动任一组件到中间的预览区域中间&#xff1a;为页面预览效果页面&#xff0c;选中任一组件&#xff0c;可在右侧进行参数配置右侧&#xff1a;为组件的参数配置&#xff08;选中中间的组件时出现&#xff09;&…

商城商品购买数量增减的完美JS效果

商城商品购买数量增减的完美JS效果 近期在开发一个地方O2O租书项目&#xff0c;使用ASP.NET MVC技术&#xff0c;其中在图书详情页&#xff0c;用户可以输入借阅的数量&#xff0c;这里使用了js来控制数量的增减和校验。 数量一定是数字 点击增减按钮的时候要能自动加1或减1 …

这款插件让你在VSCode上也能答题背单词

在VSCode上也可以在线答题了&#xff0c;插件市场上线了一款答题的插件&#xff0c;免去了去其它网站或者软件的烦恼&#xff0c;代码写累了&#xff0c;随手打开答题功能&#xff0c;换换脑子&#xff0c;或者熟悉两个单词&#xff0c;程序员的别样休闲时光&#xff0c;哈哈&a…

java jaas_基于Java JAAS表单的身份验证

java jaas使用JAAS实现登录模块是一个高级主题&#xff0c;而且大多数开发人员也很少有机会参与这种开发。 但是JAAS登录模块的基本实现不是那么难实现&#xff0c;这是因为我打算将其发布。 在这里&#xff0c;我正在解释如何实现tomcat管理的身份验证模块。 此实现与容器无关…

在ubuntu上如何将多张图片或PDF合到一个PDF上

在日常工作中我们可能需要将不同的PDF或图像合并为一个PDF上&#xff0c;这种情况并不少见。 这时候我们需要学习使用一个非常强大的命令行工具ImageMagick。通过apt命令下载安装ImageMagick在Ubuntu 20.04版本中已经预装了ImageMagick&#xff0c;因为有许多软件包使用此工具作…