这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos
本篇敢号称比官方demo更简单,是因为官方关于操作数据库的demo中还有web服务的代码(如接收http请求和响应,以及web库的依赖),而本篇不会有这些代码和依赖,只有存粹的数据库操作和对应的单元测试类,至于web服务?欣宸应该会出《quarkus之web篇》吧(如果时间允许)
作为《数据库篇》的开篇,为了避免长文劝退大多数人的悲剧发生,本文被死死压制在Hello World级别,咱们用最简单的配置和代码完成数据库的增删改查操作,掌握quarkus下基本数据库操作全掌握,然后在后续文章中逐步深入,整体上就是一次从入门到精通之旅
本篇的具体内容是创建一个maven工程,此工程有内容是
名称 | 链接 | 备注 |
---|---|---|
项目主页 | 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协议 |
请确认PostgreSQL数据库已经就绪
开发阶段推荐用docker部署数据库,简单省事儿,参考命令如下,请将/xxx换为您自己的宿主机目录,用于保存数据库文件
docker run \
--name quarkus_test \
-e POSTGRES_USER=quarkus \
-e POSTGRES_PASSWORD=123456 \
-e POSTGRES_DB=quarkus_test \
-p 5432:5432 \
-v /xxx:/var/lib/postgresql/data \
postgres:13.3
<?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/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>quarkus-tutorials</artifactId>
<groupId>com.bolingcavalry</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>basic-db</artifactId>
<dependencies>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-arc</artifactId>
</dependency>
<!-- JDBC库 -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-agroal</artifactId>
</dependency>
<!-- hibernate库 -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-hibernate-orm</artifactId>
</dependency>
<!-- postgresql库 -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-jdbc-postgresql</artifactId>
</dependency>
<!-- 单元测试库 -->
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-junit5</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>${quarkus.platform.group-id}</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<extensions>true</extensions>
<executions>
<execution>
<goals>
<goal>build</goal>
<goal>generate-code</goal>
<goal>generate-code-tests</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
</configuration>
</plugin>
<plugin>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<systemPropertyVariables>
<java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
<maven.home>${maven.home}</maven.home>
</systemPropertyVariables>
</configuration>
</plugin>
</plugins>
</build>
</project>
quarkus.datasource.db-kind=postgresql
quarkus.hibernate-orm.log.sql=true
quarkus.datasource.jdbc.max-size=8
quarkus.datasource.jdbc.min-size=2
quarkus.datasource.username=quarkus
quarkus.datasource.password=123456
quarkus.datasource.jdbc.url=jdbc:postgresql://192.168.50.43:15432/quarkus_test
quarkus.hibernate-orm.database.generation=drop-and-create
quarkus.hibernate-orm.sql-load-script=import.sql
取值 | 含义 |
---|---|
none | 啥也不做 |
create | 第一次启动会建表,之后启动不会再改动 |
drop-and-create | 每一次启动应用的时候都删表(数据也没了),然后建表,再执行import.sql导入数据 |
drop | 启动应用的时候删表,不删库 |
update | 保留数据,升级表结构 |
validate | 检查表结构与entity是否匹配 |
INSERT INTO known_fruits(id, name) VALUES (1, 'Cherry');
INSERT INTO known_fruits(id, name) VALUES (2, 'Apple');
INSERT INTO known_fruits(id, name) VALUES (3, 'Banana');
package com.bolingcavalry.db.entity;
import javax.persistence.Cacheable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.NamedQuery;
import javax.persistence.QueryHint;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
@Entity
@Table(name = "known_fruits")
@NamedQuery(name = "Fruits.findAll", query = "SELECT f FROM Fruit f ORDER BY f.name", hints = @QueryHint(name = "org.hibernate.cacheable", value = "true"))
@Cacheable
public class Fruit {
@Id
@SequenceGenerator(name = "fruitsSequence", sequenceName = "known_fruits_id_seq", allocationSize = 1, initialValue = 10)
@GeneratedValue(generator = "fruitsSequence")
private Integer id;
@Column(length = 40, unique = true)
private String name;
public Fruit() {
}
public Fruit(String name) {
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
package com.bolingcavalry.db.service;
import com.bolingcavalry.db.entity.Fruit;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Inject;
import javax.persistence.EntityManager;
import javax.transaction.Transactional;
import java.util.List;
@ApplicationScoped
public class FruitService {
@Inject
EntityManager entityManager;
public List<Fruit> get() {
return entityManager.createNamedQuery("Fruits.findAll", Fruit.class)
.getResultList();
}
public Fruit getSingle(Integer id) {
return entityManager.find(Fruit.class, id);
}
@Transactional
public void create(Fruit fruit) {
entityManager.persist(fruit);
}
@Transactional
public void update(Integer id, Fruit fruit) {
Fruit entity = entityManager.find(Fruit.class, id);
if (null!=entity) {
entity.setName(fruit.getName());
}
}
@Transactional
public void delete(Integer id) {
Fruit entity = entityManager.getReference(Fruit.class, id);
if (null!=entity) {
entityManager.remove(entity);
}
}
}
package com.bolingcavalry;
import com.bolingcavalry.db.entity.Fruit;
import com.bolingcavalry.db.service.FruitService;
import io.quarkus.test.junit.QuarkusTest;
import org.junit.jupiter.api.*;
import javax.inject.Inject;
import java.util.List;
@QuarkusTest
@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class FruitServiceTest {
/**
* import.sql中导入的记录数量,这些是应用启动是导入的
*/
private static final int EXIST_RECORDS_SIZE = 3;
/**
* import.sql中,第一条记录的id
*/
private static final int EXIST_FIRST_ID = 1;
/**
* 在Fruit.java中,id字段的SequenceGenerator指定了initialValue等于10,
* 表示自增ID从10开始
*/
private static final int ID_SEQUENCE_INIT_VALUE = 10;
@Inject
FruitService fruitService;
@Test
@DisplayName("list")
@Order(1)
public void testGet() {
List<Fruit> list = fruitService.get();
// 判定非空
Assertions.assertNotNull(list);
// import.sql中新增3条记录
Assertions.assertEquals(EXIST_RECORDS_SIZE, list.size());
}
@Test
@DisplayName("getSingle")
@Order(2)
public void testGetSingle() {
Fruit fruit = fruitService.getSingle(EXIST_FIRST_ID);
// 判定非空
Assertions.assertNotNull(fruit);
// import.sql中的第一条记录
Assertions.assertEquals("Cherry", fruit.getName());
}
@Test
@DisplayName("update")
@Order(3)
public void testUpdate() {
String newName = "ShanDongBigCherry";
fruitService.update(EXIST_FIRST_ID, new Fruit(newName));
Fruit fruit = fruitService.getSingle(EXIST_FIRST_ID);
// 从数据库取出的对象,其名称应该等于修改的名称
Assertions.assertEquals(newName, fruit.getName());
}
@Test
@DisplayName("create")
@Order(4)
public void testCreate() {
Fruit fruit = new Fruit("Orange");
fruitService.create(fruit);
// 由于是第一次新增,所以ID应该等于自增ID的起始值
Assertions.assertEquals(ID_SEQUENCE_INIT_VALUE, fruit.getId());
// 记录总数应该等于已有记录数+1
Assertions.assertEquals(EXIST_RECORDS_SIZE+1, fruitService.get().size());
}
@Test
@DisplayName("delete")
@Order(5)
public void testDelete() {
// 先记删除前的总数
int numBeforeDelete = fruitService.get().size();
// 删除第一条记录
fruitService.delete(EXIST_FIRST_ID);
// 记录数应该应该等于删除前的数量减一
Assertions.assertEquals(numBeforeDelete-1, fruitService.get().size());
}
}
实测发现,使用上述方式,IDEA给我们设置的profile可能不是test,而是default,而default这个profile的配置文件是不存在的,因此单元测试启动就会失败
上述问题,我这边偶尔遇到过几次,目前无法稳定复现,针对此问题的解决方法如下
点击图标运行单元测试的时候,选择下图红框中的选项
《quarkus数据库篇》系列的开篇,编码实战最基础的数据库增删改查,数据库用的是PostgreSQL,在官方demo基础上进一步精简,极速入门quarkus数据库操作
本篇咱们从零开发一个quarkus应用,支持虚拟线程响应web服务,响应式操作postgresql数据库,并且在quarkus官方还未支持的情况下,率先并将其制作成docker镜像
本篇咱们从零开发一个quarkus应用,支持虚拟线程响应web服务,响应式操作postgresql数据库,并且在quarkus官方还未支持的情况下,率先并将其制作成docker镜像
本次实验学习记录主题为“FIFO_IP核实现算术求和”,主要内容是上位机通过串口向FPGA发送一定规格的数字矩阵,FPGA对矩阵处理,按规定逻辑实现求和运算,将结果返回串口转发至上位机。