quarkus数据库篇之二:无需数据库也能运行增删改查(dev模式)
欢迎访问我的GitHub
这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos
本篇概览
本篇内容并非数据库相关的核心知识,而是对一个实用工具的说明介绍,此工具在官方介绍中被称为Zero Config Setup (Dev Services),(零配置的设置,忒莫名其妙)
我这边简单总结为:如果你没有数据库可用,只要你有docker,quarkus应用就能进行数据库相关的开发工作,增删改查啥都行,和有数据库的时候没啥区别
看到这里,经验丰富的您应该会觉得:既然有docker,那么用docker run装一个数据库不就行了吗,和quarkus工具有啥关系?
其实这个Zero Config Setup还算是有那么一点自己的特色,和自己动手在docker中装数据库有一丢丢区别,我做了个对比图如下

可见Zero Config Setup的好处是啥都不用配,有docker就行,劣势是必须要用mvn quarkus:dev启动应用,profile固定是dev
看到这里,您是否会这么觉得:哦,知道了,那我去建一个application-dev.properites文件,里面没有数据库配置,然后执行mvn quarkus:dev启动应用就行了,就这点内容呗,欣宸你别写了,太啰嗦...
确实内容少,但是它有坑啊,所以请您随本文一同实战吧,等到操作成功的那一刻,新技能get带来的舒适感相信您也不会拒绝,然后用起Zero Config Setup直呼666
接下来咱们亲自动手体验这个Zero Config Setup,看看适不适合开发阶段使用
关于数据库操作的源码
- quarkus操作数据库的代码,就直接用前文《quarkus数据库篇之一》的代码吧,除了从前文拷贝,您也可以在我的GitHub仓库下载,,地址和链接信息如下表所示(https://github.com/zq2599/blog_demos)
| 名称 | 链接 | 备注 |
|---|---|---|
| 项目主页 | https://github.com/zq2599/blog_demos | 该项目在GitHub上的主页 |
| git仓库地址(https) | https://github.com/zq2599/blog_demos.git | 该项目源码的仓库地址,https协议 |
| git仓库地址(ssh) | git@github.com:zq2599/blog_demos.git | 该项目源码的仓库地址,ssh协议 |
- 这个git项目中有多个文件夹,本次实战的源码在quarkus-tutorials文件夹下,如下图红框

- quarkus-tutorials是个父工程,里面有多个module,本篇实战的module是basic-db,如下图红框

提前下载docker镜像
- 建议先把镜像下载到本地才能使用Zero Config Setup功能,否则如果等quarkus框架自动下载镜像,可能会有如下错误发生
[INFO] Compiling 1 source file to /Users/zhaoqin/github/blog_demos/quarkus-tutorials/basic-db/target/test-classes
Listening for transport dt_socket at address: 5005
2022-05-08 10:52:56,714 ERROR [com.git.doc.api.asy.ResultCallbackTemplate] (docker-java-stream-1954350275) Error during callback: com.github.dockerjava.api.exception.InternalServerErrorException: Status 500: {"message":"Head \"https://registry-1.docker.io/v2/testcontainers/ryuk/manifests/0.3.3\": unauthorized: incorrect username or password"}
at org.testcontainers.shaded.com.github.dockerjava.core.DefaultInvocationBuilder.execute(DefaultInvocationBuilder.java:247)
at org.testcontainers.shaded.com.github.dockerjava.core.DefaultInvocationBuilder.lambda$executeAndStream$1(DefaultInvocationBuilder.java:269)
at java.base/java.lang.Thread.run(Thread.java:829)
2022-05-08 10:52:57,019 INFO [io.qua.dep.dev.IsolatedDevModeMain] (main) Attempting to start live reload endpoint to recover from previous Quarkus startup failure
2022-05-08 10:52:57,037 ERROR [io.qua.dep.dev.IsolatedDevModeMain] (main) Failed to start quarkus: java.lang.RuntimeException: io.quarkus.builder.BuildException: Build failure: Build failed due to errors
[error]: Build step io.quarkus.datasource.deployment.devservices.DevServicesDatasourceProcessor#launchDatabases threw an exception: java.lang.RuntimeException: com.github.dockerjava.api.exception.InternalServerErrorException: Status 500: {"message":"Head \"https://registry-1.docker.io/v2/testcontainers/ryuk/manifests/0.3.3\": unauthorized: incorrect username or password"}
at io.quarkus.datasource.deployment.devservices.DevServicesDatasourceProcessor.startDevDb(DevServicesDatasourceProcessor.java:314)
at io.quarkus.datasource.deployment.devservices.DevServicesDatasourceProcessor.launchDatabases(DevServicesDatasourceProcessor.java:121)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at io.quarkus.deployment.ExtensionLoader$2.execute(ExtensionLoader.java:882)
at io.quarkus.builder.BuildContext.run(BuildContext.java:277)
at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18)
at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2449)
at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1478)
at java.base/java.lang.Thread.run(Thread.java:829)
at org.jboss.threads.JBossThread.run(JBossThread.java:501)
Caused by: com.github.dockerjava.api.exception.InternalServerErrorException: Status 500: {"message":"Head \"https://registry-1.docker.io/v2/testcontainers/ryuk/manifests/0.3.3\": unauthorized: incorrect username or password"}
at org.testcontainers.shaded.com.github.dockerjava.core.DefaultInvocationBuilder.execute(DefaultInvocationBuilder.java:247)
at org.testcontainers.shaded.com.github.dockerjava.core.DefaultInvocationBuilder.lambda$executeAndStream$1(DefaultInvocationBuilder.java:269)
at java.base/java.lang.Thread.run(Thread.java:829)
- 为了避免上述错误,以下两种方式都可以,请您二选一即可
- 提前下载docker镜像,命令是docker pull testcontainers/ryuk:0.3.3(当您看到此文是,tag可能不是0.3.3了,你可以从错误信息中确定您那边的tag)
- 如果您有docker账号,执行命令docker login index.docker.io登录docker
dev这个profile的配置文件
- 新增名文件application-dev.properties,里面就一行内容
quarkus.hibernate-orm.sql-load-script=import.sql
- 可见和之前的application-test.properties相比,dev这个profile下的配置文件中,不能有任何数据库配置(数据库IP、端口、库名、账号、密码等)
启动应用
- 进入目录quarkus-tutorials/basic-db,执行命令mvn quarkus:dev启动应用,控制台输入如下
[INFO] Nothing to compile - all classes are up to date
Listening for transport dt_socket at address: 5005
2022-05-08 17:51:48,010 INFO [io.qua.dat.dep.dev.DevServicesDatasourceProcessor] (build-12) Dev Services for the default datasource (postgresql) started.
2022-05-08 17:51:48,011 INFO [io.qua.hib.orm.dep.HibernateOrmProcessor] (build-5) Setting quarkus.hibernate-orm.database.generation=drop-and-create to initialize Dev Services managed database
__ ____ __ _____ ___ __ ____ ______
--/ __ \/ / / / _ | / _ \/ //_/ / / / __/
-/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/
2022-05-08 17:51:48,244 INFO [io.agr.pool] (Quarkus Main Thread) Datasource '<default>': Initial size smaller than min. Connections will be created when necessary
Hibernate:
drop table if exists known_fruits cascade
2022-05-08 17:51:48,510 WARN [org.hib.eng.jdb.spi.SqlExceptionHelper] (JPA Startup Thread: <default>) SQL Warning Code: 0, SQLState: 00000
2022-05-08 17:51:48,511 WARN [org.hib.eng.jdb.spi.SqlExceptionHelper] (JPA Startup Thread: <default>) table "known_fruits" does not exist, skipping
Hibernate:
drop sequence if exists known_fruits_id_seq
2022-05-08 17:51:48,512 WARN [org.hib.eng.jdb.spi.SqlExceptionHelper] (JPA Startup Thread: <default>) SQL Warning Code: 0, SQLState: 00000
2022-05-08 17:51:48,512 WARN [org.hib.eng.jdb.spi.SqlExceptionHelper] (JPA Startup Thread: <default>) sequence "known_fruits_id_seq" does not exist, skipping
Hibernate: create sequence known_fruits_id_seq start 10 increment 1
Hibernate:
create table known_fruits (
id int4 not null,
name varchar(40),
primary key (id)
)
Hibernate:
alter table if exists known_fruits
add constraint UK_57g3m8wr3qxoj706a6hsqg6ye unique (name)
Hibernate:
INSERT INTO known_fruits(id, name) VALUES (1, 'Cherry')
Hibernate:
INSERT INTO known_fruits(id, name) VALUES (2, 'Apple')
Hibernate:
INSERT INTO known_fruits(id, name) VALUES (3, 'Banana')
2022-05-08 17:51:48,558 INFO [io.quarkus] (Quarkus Main Thread) basic-db 1.0-SNAPSHOT on JVM (powered by Quarkus 2.7.3.Final) started in 2.706s.
2022-05-08 17:51:48,559 INFO [io.quarkus] (Quarkus Main Thread) Profile dev activated. Live Coding activated.
2022-05-08 17:51:48,559 INFO [io.quarkus] (Quarkus Main Thread) Installed features: [agroal, cdi, hibernate-orm, jdbc-postgresql, narayana-jta, smallrye-context-propagation]
--
--
Tests paused
Press [r] to resume testing, [o] Toggle test output, [:] for the terminal, [h] for more options>
- 从上述信息可见,即便是没有数据库,也没有数据库配置,quarkus也会通过docker为应用把数据库备好,让应用顺利启动、连接、执行初始化SQL
执行单元测试
- 从上述控制台信息可见,目前的控制条已经处于命令行交互模式,先输入o开启测试日志输出开关
- 然后再输入r开始执行单元测试,控制台输出如下,可见和上一篇的操作并没有什么区别(还省去了数据库的部署和配置)

- 至此,Zero Config Setup的体验就完成了,虽然省去了数据库的部署和配置,但profile被限定在dev,这怕是很多人不情愿的,另外这都是后台命令的操作,IDEA的单元测试页面也不知道如何与quarkus的dev模式结合起来用,又是个巨大损失,所以,Zero Config Setup到底适不适用也是见仁见智
接受数据库的license
- 如果您用的数据库是DB2或者MSSQL,在使用Zero Config Setup的时候会涉及到接受license的操作,您需要新增文件src/main/resources/container-license-acceptance.txt,内容如下,就是数据库的镜像名
ibmcom/db2:11.5.0.0a
mcr.microsoft.com/mssql/server:2017-CU12
MySQL的配置
- 在使用MySQL的时候,我们可能对其做一些配置,那么Zero Config Setup提供的MySQL就无法满足我们的需求了,这里可以通过配置来指定MySQL配置信息(个人的感觉,就是为了解决一个问题而引入了新的问题)
quarkus.datasource.devservices.container-properties.TC_MY_CNF=testcontainers/mysql-conf
发现神秘信息
接下来聊聊一次偶然的发现,既有惊喜也有疑惑,还希望亲爱的读者能够给予指导和建议
回想一下,当您使用mvn quarkus:dev启动应用后,控制台提示如下信息
Press [r] to resume testing, [o] Toggle test output, [:] for the terminal, [h] for more options>
- 于是,我按照上述提示输入冒号,进入quarkus的终端模式,控制条提示如下
You are now in Quarkus Terminal. Your app is still running. Use `help` or tab completion to explore, `quit` or `q` to return to your application.
quarkus$
- 然后,输入postgres print-command,就会看到quarkus创建的数据库信息,账号、密码、端口、库名、啥都有,如下,真是神奇啊
quarkus$ postgres print-command
PGPASSWORD=quarkus psql --host=localhost --port=49294 --username=quarkus default
- 上述信息,应该是quarkus在docker上创建的数据库信息,于是我兴冲冲地用IDEA的数据库工具去连接这个数据库,如下图,天哪,连接成功了

- 然后查看表的数据,如下图,正是初始化脚本import.sql中新增的内容

本以为发现了quarkus的惊天秘密,今后开发中随时可以连接此数据库查看数据,结果发现单元测试对数据的任何写操作,都不会改变上图表中的内容,这和使用自己的数据库是完全不同的,上一篇文章中,咱们执行完单元测试后,写操作的结果在数据库中是可以查到的
目前还没有查到上述问题的原因,估计是quarkus自己内部的处理机制吧,例如自动rollback,或者某些程度的可见性隔离等,这都是猜的,亲爱的读者,如果您知道了原因,麻烦您在回复中指点一二,谢谢了
其实这也不是什么问题,不去查那个表就行了,单元测试的读写功能是正常的,也就是说单元测试中,数据发生变化后程序可以读取到变化后的数据,只是我们用工具看不到变化而已(官方文档也没有提及用工具去连接那个表,应该是不推荐这么做)
至此,quarkus的Zero Config Setup体验完成,希望这个小技能可以对您有所帮助,以更简单的操作度过编码和自测的时光
欢迎关注博客园:程序员欣宸
quarkus数据库篇之二:无需数据库也能运行增删改查(dev模式)的更多相关文章
- BitAdminCore框架应用篇:(二)创建一个简单的增删改查模块
NET Core应用框架之BitAdminCore框架应用篇系列 框架演示:http://bit.bitdao.cn 框架源码:https://github.com/chenyinxin/cookie ...
- 第二百七十六节,MySQL数据库,【显示、创建、选定、删除数据库】,【用户管理、对用户增删改查以及授权】
MySQL数据库,[显示.创建.选定.删除数据库],[用户管理.对用户增删改查以及授权] 1.显示数据库 SHOW DATABASES;显示数据库 SHOW DATABASES; mysql - 用户 ...
- entity framework 新手入门篇(2)-entity framework基本的增删改查
经过前两节的简单描述,终于可以进入entity framework的使用部分了.本节将对entity framework原生的增删改查进行讲解. 承接上面的部分,我们有一个叫做House的数据库,其中 ...
- SQLAlchemy(二):SQLAlchemy对数据的增删改查操作、属性常用数据类型详解
SQLAlchemy02 /SQLAlchemy对数据的增删改查操作.属性常用数据类型详解 目录 SQLAlchemy02 /SQLAlchemy对数据的增删改查操作.属性常用数据类型详解 1.用se ...
- VS连接Access数据库--连接字符串及执行查询语句的方法(增删改查,用户名查重,根据用户获取密码查询)
ACCESS数据的连接及语句执行操作,不难,久不用会生疏,每次都要找资料,干脆自己整理下,记录下来,需要的时候,直接查看,提高效率.也供初学者参考 1.连接字符串 public static stri ...
- 数据库学习(MySQL):JDBC的简单增删改查实现
本文为原创,转载请注明出处: https://www.cnblogs.com/Tom-shushu/p/9171896.html 这里我们先在数据库建立一个userinfo表: CREATE TABL ...
- MongoDB 数据库创建删除、表创建删除、数据增删改查
一.管理 mongodb 数据库:mongo 查看所有数据库列 表 show dbs 二. 创建数据库 创建 数据库 use student 如果真的想把这个数据库创建成功,(collections) ...
- django(八)之数据库表的一对多,多对多表-增删改查
单表操作 表记录的添加 方式一: Book() b=Book(name="python基础",price=99,author="yuan",pub_date=& ...
- python学习之老男孩python全栈第九期_数据库day001知识点总结 —— MySQL操作数据库以及数据表、基本数据类型、基本增删改查、外键定义以及创建
一. 学习SQL语句规则以及外键 1. 操作文件夹 create database db2; 创建文件夹 create database db2 default charset utf8; 创建文件夹 ...
- C#_会员管理系统:开发二(会员资料管理界面的‘增删改查’)
会员资料管理界面: 新建一个窗体,窗体界面和控件如下: 窗体中的控件dgvManager更改FullRowSelect属性(点击选中效果)为:FullRowSelect 会员资料管理界面窗体的详细代码 ...
随机推荐
- 2022-08-19:以下go语言代码输出什么?A:equal;B:not equal;C:不确定。 package main import ( “fmt“ “reflect“ )
2022-08-19:以下go语言代码输出什么?A:equal:B:not equal:C:不确定. package main import ( "fmt" "refle ...
- 2022-05-18:假设数组a和数组b为两组信号: 1) length(b) <= length(a); 2) 对于任意0<=i<length(b), 有b[i+1] - b[i] == a[i+1
2022-05-18:假设数组a和数组b为两组信号: length(b) <= length(a): 对于任意0<=i<length(b), 有b[i+1] - b[i] == a[ ...
- idea构建grpc项目
转载请注明出处: 安装protocbuf插件 idea 建议下载一个 protobuf的插件, 可以有代码提示. 这里直接去pluging里搜就行了. 在idea的plugins中搜索proto,然后 ...
- linux ssh远程登录
目录 一.ssh概念 二.配置文件 三.ssh组成结构 四.远程控制过程 五.远程复制 六.配置密钥 七.wraooers防火墙 一.ssh概念 ssh:一种安全通道协议 功能:1.实现字符界面远程登 ...
- web自动化10-窗口截图、验证码处理
窗口截图 1.是什么 说明:把当前操作的页面,截图保存到指定位置 2.代码中怎么使用? 说明:在Selenium中,提供了截图方法,我们只需要调用即可 方法: driver.get_screensho ...
- .NET 创建无边框的跨平台应用
.NET 创建无边框的跨平台应用 在创建了Photino应用程序以后我们发现它自带了一个标题栏,并且非常丑,我们现在要做的就是去掉这个很丑的自带标题栏,并且自定义一个更好看的,下面我们将用Masa B ...
- 论c++实现sql连接
寻找关于c++ 对 sql连接的过程非常艰辛. 今天要做一个简单项目,要求在远程sql上实现对数据的实时模拟,每五分钟进行一次随机产生数据并写入. 在此之前我并没有用过代码实现sql连接的经历,在翻阅 ...
- JVM监控工具jstat使用介绍
jstat 是 Java 自带的一个命令行工具,用于监控 JVM 运行时的状态信息.它可以通过以下格式的命令来调用: jstat [option] <vmid> [<interval ...
- ASP.NET Core 6框架揭秘实例演示[40]:基于角色的授权
ASP.NET应用并没有对如何定义授权策略做硬性规定,所以我们完全根据用户具有的任意特性(如性别.年龄.学历.所在地区.宗教信仰.政治面貌等)来判断其是否具有获取目标资源或者执行目标操作的权限,但是针 ...
- Nginx+php关联
nginx配置php选项,解除对IIS.Apache的php环境依赖 php.ini配置 取消extension_dir注释 取消cgi.fix_pathinfo注释 nginx.conf配置 取消 ...