介绍
Quarkus在日常开发中是可以替代SpringBoot的。
Quarkus是 Red Hat为GraalVM 和 HotSpot 量身定制用程序。特点是启动超快,内存极低,并且在容器编排平台(如Kubernetes)中提供了近乎即时的向上扩展和高密度的内存利用率。并且基于GraalVM,为我们提供了编译成native程序的能力。如果你觉得SpringBoot的启动速度太慢了内存占用率太高了,那么可以在日常开发中尝试一下Quarkus,也许会给你不一样的体验。我将通过一系列的教程,来介绍如何使用Quarkus。
准备
本文将用Quarkus快速实现一个CRUD操作。
项目创建
可以通过IDEA快速来创建一个Quarkus的项目。
我们先选择如下依赖,resteasy 相当于springmvc,openapi相当于swagger。这里还差一个mybatisplus的依赖,我们一会在pom里面再添加。
项目结构如下
我们在pom中再添加一下mybatisplus跟lombok的依赖
<dependency>
<groupId>io.quarkiverse.mybatis</groupId>
<artifactId>quarkus-mybatis-plus</artifactId>
<version>1.0.3</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
<scope>provided</scope>
</dependency>
添加mysql的配置
quarkus.datasource.db-kind=mysql
quarkus.datasource.password=root
quarkus.datasource.username=root
quarkus.datasource.jdbc.url=jdbc:mysql://localhost/test
创建一张user表
CREATE TABLE `t_user` (
`id` bigint(20) NOT NULL,
`address` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`age` int(11) DEFAULT NULL,
`name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
`password` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
再创建一个user的实体类
package com.billetsdoux.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@Data
@TableName("t_user")
public class User {
@TableId(type = IdType.AUTO)
private Long id;
private String name;
private String address;
private Integer age;
private String password;
}
repository层的如下
package com.billetsdoux.repository;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.billetsdoux.entity.User;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserRepository extends BaseMapper<User> {
}
service层如下,查询单个,分页查询,更新,删除,新增操作
package com.billetsdoux.service;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.billetsdoux.entity.User;
import com.billetsdoux.repository.UserRepository;
import javax.inject.Inject;
import javax.inject.Singleton;
@Singleton
public class UserService {
@Inject
UserRepository userRepository;
public User findById(Long id){
return userRepository.selectById(id);
}
public Page<User> list(String name,String address,Integer age,Integer pageNo,Integer pageSize){
Page<User> page = userRepository.selectPage(new Page<>(pageNo, pageSize), new QueryWrapper<User>()
.eq(StringUtils.isNotBlank(name), "name", name)
.eq(StringUtils.isNotBlank(address), "address", address)
.eq(null!=age, "age", age));
return page;
}
public boolean insert(User user){
return userRepository.insert(user)>0;
}
public boolean update(User user){
return userRepository.updateById(user) > 0;
}
public boolean delete(Long id){
return userRepository.deleteById(id) > 0;
}
}
controller层
package com.billetsdoux.controller;
import com.billetsdoux.entity.User;
import com.billetsdoux.service.UserService;
import com.billetsdoux.util.BaseResponse;
import javax.inject.Inject;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import java.util.List;
@Path("/user")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public class UserController {
@Inject
UserService userService;
@GET
@Path("/search/{id}")
public User searchById(@PathParam("id") Long id){
return userService.findById(id);
}
@GET
@Path("/list")
public BaseResponse<List<User>> list(@QueryParam("name") String name,
@QueryParam("address") String address,
@QueryParam("age") Integer age,
@QueryParam("pageNo") Integer pageNo,
@QueryParam("pageSize") Integer pageSize
){
return BaseResponse.success(userService.list(name, address, age, pageNo, pageSize).getRecords());
}
@POST
@Path("/add")
public BaseResponse addUser(User user){
return userService.insert(user) ? BaseResponse.success() : BaseResponse.error();
}
@DELETE
@Path("/delete/{id}")
public BaseResponse delete(@PathParam("id") Long id){
return userService.delete(id) ? BaseResponse.success() : BaseResponse.error();
}
@PUT
@Path("/update")
public BaseResponse updateUser(User user){
return userService.update(user) ? BaseResponse.success() : BaseResponse.error();
}
}
新增了一个BaseResponse
package com.billetsdoux.util;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class BaseResponse<T> {
private static final int CODE_SUCCESS = 200;
private static final int CODE_FAIL = 500;
private static final int CODE_ERROR = 500;
private static final int CODE_NO_LOGIN = 300;
private int code;
private String msg;
private T data;
public BaseResponse(int code, String msg, T data) {
this.setCode(code);
this.setMsg(msg);
this.setData(data);
}
public static <T> BaseResponse<T> success() {
return new BaseResponse<T>(CODE_SUCCESS, "success", null);
}
public static <T> BaseResponse<T> success(String message) {
return new BaseResponse<T>(CODE_SUCCESS, message, null);
}
public static <T> BaseResponse<T> success(T data) {
return new BaseResponse<T>(CODE_SUCCESS, "success", data);
}
public static <T> BaseResponse<T> success(String message, T data) {
return new BaseResponse<T>(CODE_SUCCESS, message, data);
}
public static <T> BaseResponse<T> error() {
return new BaseResponse<T>(CODE_ERROR, "fail", null);
}
public static <T> BaseResponse<T> error(String message) {
return new BaseResponse<T>(CODE_ERROR, message, null);
}
public static <T> BaseResponse<T> error(T data) {
return new BaseResponse<T>(CODE_ERROR, "fail", data);
}
public static <T> BaseResponse<T> error(String message, T data) {
return new BaseResponse<T>(CODE_ERROR, message, data);
}
public static <T> BaseResponse<T> badrequest() {
return new BaseResponse<T>(CODE_FAIL, "no identifier arguments", null);
}
public static <T> BaseResponse<T> badrequest(String message) {
return new BaseResponse<T>(CODE_FAIL, message, null);
}
public static <T> BaseResponse<T> badrequest(T data) {
return new BaseResponse<T>(CODE_FAIL, "no identifier arguments", data);
}
public static <T> BaseResponse<T> badrequest(String message, T data) {
return new BaseResponse<T>(CODE_FAIL, message, data);
}
public static <T> BaseResponse<T> noLogin(String message) {
return new BaseResponse<T>(CODE_NO_LOGIN, message, null);
}
}
简单的crud的代码就只有这些,然后我们去页面上测试一下。
页面测试
由于它没有main方法作为入口,所以我们需要在命令行之行如下命令启动项目。
./mvnw compile quarkus:dev
第一次启动的时候会去下载一些插件所以会花费点时间,等启动好了,访问 localhost:8080/q/swagger-ui 进入swagger页面
我们先添加一条数据
再查询一下刚添加的数据
更新一下
至此,我们用quarkus+mybatisplus完成了基础的crud操作。
native
前面我们说过了Quarkus的一个优势是借助GraalVM可以将我们的代码打包成native code 所以我们来打包一下。
执行
./mvnw package -Pnative
等待编译,这个编译的时间会比较久一点。
编译成功后我们进入target文件夹中可以看到编译后的可执行的文件,直接运行它就可以了。
可以看到我们的应用程序很快就启动完成了