Quarkus
使用Mutiny
模型提供了许多反应API。在本节中,我们将了解如何使用反应式PostgreSQL
驱动程序以非阻塞和反应式的方式与数据库交互。
手下先去安装一个PostgreSQL
,下载地址:https://www.enterprisedb.com/downloads/postgres-postgresql-downloads
那就直接开始操作,创建一个新的项目
mvn io.quarkus:quarkus-maven-plugin:1.11.0.Final:create \
-DprojectGroupId=org.acme \
-DprojectArtifactId=getting-started-reactive-crud \
-DclassName="org.acme.reactive.crud.FruitResource" \
-Dpath="/fruits" \
-Dextensions="resteasy-mutiny, resteasy-jackson, reactive-pg-client"
cd getting-started-reactive-crud
如果不想那么麻烦,只需要多新增几个依赖
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-jackson</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-reactive-pg-client</artifactId>
</dependency>
<dependency>
<groupId>io.quarkus</groupId>
<artifactId>quarkus-resteasy-mutiny</artifactId>
</dependency>
新建数据库
-- ----------------------------
-- Table structure for student
-- ----------------------------
DROP TABLE IF EXISTS "public"."student";
CREATE TABLE "public"."student" (
"id" varchar(225) COLLATE "pg_catalog"."default" NOT NULL,
"name" varchar(225) COLLATE "pg_catalog"."default",
"age" int4
)
;
-- ----------------------------
-- Primary Key structure for table student
-- ----------------------------
ALTER TABLE "public"."student" ADD CONSTRAINT "student_pkey" PRIMARY KEY ("id");
application.properties
#数据库类型
quarkus.datasource.db-kind=postgresql
#账号
quarkus.datasource.username=postgres
#密码
quarkus.datasource.password=123456
#连接地址
quarkus.datasource.reactive.url=postgresql://localhost:5432/school
Idea
可以识别yaml
文件,但是框架好像不能识别,这就很尴尬,或许我的操作有点问题
package top.lzmvlog.resteasyjackson.model;
import io.smallrye.mutiny.Multi;
import io.smallrye.mutiny.Uni;
import io.vertx.mutiny.pgclient.PgPool;
import io.vertx.mutiny.sqlclient.Row;
import io.vertx.mutiny.sqlclient.RowSet;
import io.vertx.mutiny.sqlclient.Tuple;
import java.util.stream.StreamSupport;
public class Student {
/**
* 学生id
*/
public String id;
/**
* 学生名称
*/
public String name;
/**
* 学生年龄
*/
public Integer age;
public Student() {
}
public Student(String id, String name, Integer age) {
this.id = id;
this.name = name;
this.age = age;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
/**
* 查询所有信息
*
* @param pool
* @return
*/
public static Multi<Student> findAll(PgPool pool) {
return pool.query("SELECT id, name, age FROM student").execute()
// Create a Multi from the set of rows:
.onItem().transformToMulti(set -> Multi.createFrom().items(() -> StreamSupport.stream(set.spliterator(), false)))
// For each row create a student instance
.onItem().transform(Student::from);
}
/**
* 根据id查询学生信息
*
* @param pool
* @param id
* @return
*/
public static Uni<Student> findById(PgPool pool, String id) {
return pool.preparedQuery("SELECT id, name, age FROM student WHERE id = $1").execute(Tuple.of(id))
.onItem().transform(RowSet::iterator)
.onItem().transform(iterator -> iterator.hasNext() ? from(iterator.next()) : null);
}
/**
* 保存用户信息
*
* @param pool
* @return
*/
public Uni<RowSet<Row>> save(PgPool pool) {
return pool.preparedQuery("INSERT INTO student (id, name, age) VALUES ($1,$2,$3)")
.execute(Tuple.of(id, name, age));
}
/**
* 更新用户信息
*
* @param pool
* @return
*/
public Uni<Boolean> update(PgPool pool, Student student) {
return pool.preparedQuery("UPDATE student SET name = $1,age = $2 WHERE id = $3")
.execute(Tuple.of(student.getName(), student.getAge(), student.getId()))
.onItem().transform(pgRowSet -> pgRowSet.rowCount() == 1);
}
/**
* 删除
*
* @param pool
* @param id
* @return
*/
public static Uni<Boolean> delete(PgPool pool, String id) {
return pool.preparedQuery("DELETE FROM student WHERE id = $1").execute(Tuple.of(id))
.onItem().transform(pgRowSet -> pgRowSet.rowCount() == 1);
}
private static Student from(Row row) {
return new Student(row.getString("id"), row.getString("name"), row.getInteger("age"));
}
API
,Resourcepackage top.lzmvlog.resteasyjackson.resource;
import io.smallrye.mutiny.Multi;
import io.smallrye.mutiny.Uni;
import io.vertx.mutiny.pgclient.PgPool;
import top.lzmvlog.resteasyjackson.model.Student;
import javax.inject.Inject;
import javax.ws.rs.*;
import javax.ws.rs.core.Response;
import java.net.URI;
@Path("student")
public class StudentResource {
/**
* 数据连接池
*/
@Inject
PgPool pool;
/**
* 获取所有信息
*
* @return
*/
@GET
@Path("getAll")
public Multi<Student> get() {
return Student.findAll(pool);
}
/**
* 根据id获取学生信息
*
* @param id
* @return
*/
@GET
@Path("getOne/{id}")
public Uni<Response> getOne(@PathParam("id") String id) {
return Student.findById(pool, id)
.onItem().transform(student -> student != null ? Response.ok(student) : Response.status(Response.Status.NOT_FOUND))
.onItem().transform(Response.ResponseBuilder::build);
}
/**
* 保存学生信息
*
* @param student 学生信息
* @return
*/
@POST
@Path("save")
public Uni<Response> save(Student student) {
return student.save(pool)
.onItem().transform(id -> URI.create("/student/" + id))
.onItem().transform(uri -> Response.created(uri).build());
}
/**
* 更新学生信息
*
* @param student 学生信息
* @return
*/
@PUT
@Path("update")
public Uni<Response> update(Student student) {
return student.update(pool, student)
.onItem().transform(updated -> updated ? Response.Status.OK : Response.Status.NOT_FOUND)
.onItem().transform(status -> Response.status(status).build());
}
/**
* 根据id删除学生信息
*
* @param id 学生id
* @return
*/
@DELETE
@Path("{id}")
public Uni<Response> delete(@PathParam("id") String id) {
return Student.delete(pool, id)
.onItem().transform(deleted -> deleted ? Response.Status.NO_CONTENT : Response.Status.NOT_FOUND)
.onItem().transform(status -> Response.status(status).build());
}
Quarkus
里面把控制器Controller
叫做资源,这也就是为什么是Resource
有点类似JDBC
的意思,不过有点麻烦,对别Spring JDBC
来说还是有差距的,不是那么方便,