发表时间:2022-03-22来源:网络
– 一个针对OpenJDK HotSpot和GraalVM量身定制的Kubernetes本机Java堆栈,它是从最佳Java库和标准中精制而成的。 –是一个容器优先的框架,针对快速启动时间和低内存消耗进行了优化。 该框架基于许多流行的Java库构建,并且为构建标准REST以及响应式和消息驱动型微服务提供支持。 由于快速的启动时间和较低的内存使用量,也可用于在无服务器环境中实现功能。 凭借统一的配置,出色的实时重装功能和工具支持,为快速开发应用程序提供了许多可能性。
了解如何开始使用和构建PetClinic REST API。
这篇博客文章涵盖:
开发环境要求 建立新专案 使用Java 11开发,构建和运行应用程序 使用Postgres和Flyway进行数据源配置 分页CRUD服务 创建集成测试 实时重新加载和调试 Docker化应用程序(本机和非本机)我决定重新使用在本博文Spring Boot和Spring Data REST中使用的PetClinic模型。
基本上,它是用于管理虚拟PetClinic的基本CRUD服务:宠物,兽医,来访等。
Docker将用于运行服务本身的dockerized版本,但也将用于运行PostgreSQL服务器。
PetClinic API将使用Java 11构建,因此必须安装JDK 11。 为了构建本机可执行文件,必须存在GraalVM 19.3+,并且由于它是基于OpenJDK 11构建的,因此这将是本教程的最佳选择。 安装(和管理Java SDK的多个版本)最简单的方法是使用SDKMAN!
了解如何使用SDKMAN管理多个Java SDK! 轻松
要支持本机映像,请确保安装所有必需的依赖项。 可以在GraalVM文档中找到更多信息: https ://www.graalvm.org/docs/reference-manual/native-image/
GraalVM官方文档: GraalVM
该服务是使用iTerm2和oh-my-zsh在macOS上开发的。 我还将httpie用作默认的HTTP客户端。
我首选的IDE是IntelliJ,我在从事此项目时就使用了它。
在本文中了解有关我在macOS上使用的工具的更多信息: macOS:(Java)开发人员的基本工具
该应用程序将连接到Postgres服务器,并根据配置文件( dev , test , prod )应用不同的配置。 为此,我们将需要运行三台服务器:每台服务器具有不同的数据库名称,端口和凭据。 为了简化设置,可以利用Docker。
您可以在命令行中使用Maven引导应用程序,也可以使用在线生成器。 在线生成器允许探索可以构成应用程序的扩展和技术,并且不需要本地Maven安装。 您可以在此处访问生成器: https : //code..io
需要以下扩展来构建PetClinic API服务:
RESTEasy JAX-RS –实现JAX-RS等的REST框架 RESTEasy Jackson –对RESTEasy的Jackson序列化支持 SmallRye OpenAPI –使用OpenAPI记录您的REST API – Swagger UI随附 带有Panache的Hibernate ORM –在带有Panache的Hibernate ORM中定义持久性模型 Hibernate Validator –验证进入您的REST端点的数据 JDBC驱动程序– PostgreSQL – PostgreSQL数据库连接器 Flyway –处理数据库架构迁移选择依赖项后,您可以下载zip,解压缩并开始开发服务。
下载的项目具有标准的Maven项目布局。 它包含Maven包装器,因此无需本地Maven安装即可开发项目。 您还会注意到src/main/docker带有本机和JVM映像的Docker文件。
主配置文件application.properties位于src/main/resources 。 此文件夹还包含META-INF/resources文件夹,用于存储应用程序的静态资源,例如index.html文件。
在线生成器默认情况下使用Java 8生成项目,因此要使用Java 11,需要进行一些调整。
在生成的项目的pom.xml中,更改Java版本: < maven.compiler.source >11 < maven.compiler.target >11 在src/main/docker/Dockerfile.jvm设置ARG JAVA_PACKAGE=java-11-openjdk-headless进行更改后,您可以启动应用程序。 打开终端,导航到项目的文件夹并运行以下命令:
$ ./mvnw compile :dev注意:具有三种内置模式: dev , test和prod取决于您如何运行应用程序。
在IntelliJ中,您只需打开项目的文件夹或pom.xml 。 ( File > Open )。 该项目只能使用Maven启动。 这可以通过Maven运行配置来完成,因为没有主类可以启动应用程序,例如在Spring Boot中 。
对我来说,使用进行开发时最好的体验是当我在IntelliJ外部的终端中运行应用程序时。
在开发模式下执行应用程序时,它将以启用的调试协议(在端口5005上)启动。 要在IntelliJ中调试应用程序,您需要通过Run > Attach to Process调试器附加到正在Run > Attach to Process 。 我没有调试应用程序的麻烦。
注意:可以在禁用调试的开发模式下运行该应用程序: ./mvnw :dev -Ddebug=false ,但老实说,默认情况下启用调试器时,我没有发现任何性能问题。
我认为,实时重新加载是最强大的功能。 效果惊人。 基本上,您可以更改源代码中所需的任何内容,执行请求,然后眨眼间即可重新加载应用程序。 我正在重新整理类和程序包,移动文件,添加和删除端点,而所有这些操作都没有一次重启。
所有属性都转到src/main/resources/application.properties 。
要设置模式(或配置文件)的特定属性,请使用%mode :
%dev..datasource.url=jdbc:postgresql: //localhost:5433/petclinic-dev %dev..datasource.username=petclinic-dev %dev..datasource.password=petclinic-dev另请参阅: https : //.io/guides/datasource
要使用Flyway,请在src/main/resources创建db/migration文件夹,然后添加迁移文件。 我的第一个迁移文件称为V1.0.0__PetClinic.sql ,其中包含该服务的所有架构(DDL)和示例数据。
注意:支持SQL导入,可以通过.hibernate-orm.sql-load-script为每个配置文件配置SQL导入,但是我无法使其工作。 请参阅我在Github上报告的问题: https : //github.com///issues/7358
另请参阅: https : //.io/guides/flyway
PetClinic的域模型相对简单,但是它包含一些单向和双向关联以及基本继承,这使其比简单的Hello World类型的模型要好一些。
请注意,在此示例中,JPA实体由相应的Panache存储库直接在JAX-RS资源中返回(请参见下文),因此,实体类包含JPA和Jackson批注的混合。
例如:
@Entity @Table (name = "visits" ) public class Visit extends BaseEntity { @Column (name = "visit_date" ) @JsonFormat (pattern = "yyyy/MM/dd HH:mm" ) private LocalDateTime date; @NotEmpty @Column (name = "description" ) private String description; @ManyToOne @JoinColumn (name = "pet_id" ) private Pet pet; @ManyToOne @JoinColumn (name = "vet_id" ) private Vet vet; public Visit() { this .date = LocalDateTime.now(); } } @Entity @Table (name = "vets" , uni = @Uni (columnNames = { "first_name" , "last_name" }) ) public class Vet extends Person { @ManyToMany (fetch = FetchType.EAGER) @JoinTable (name = "vet_specialties" , joinColumns = @JoinColumn (name = "vet_id" ), inverseJoinColumns = @JoinColumn (name = "specialty_id" )) @JsonIgnore private Set specialties; @OneToMany (cascade = CascadeType.ALL, mappedBy = "vet" , fetch = FetchType.EAGER) @JsonIgnore private Set visits; }所有实体都位于pl.codeleak.samples.petclinic.model包中。
如果您熟悉Spring,我想您已经听说过Spring Data项目。 在我看来, 带有Panache的Hibernate ORM具有相似的目标:通过消除重复和繁琐的工作,简化了JPA的开发。 Panache支持排序,分页, java.util.Optional和java.utitl.stream.Stream等。
你有两种方法来工作,以耀目:与创建实体PanacheEntity或创建库PanacheRepository 。 我在这个项目中尝试了两种方法,但是由于实体中的继承问题,我决定坚持使用老式的方法。
带有Panache的Hibernate ORM的基本存储库定义:
public class OwnerRepository implements PanacheRepository { List findByLastName(String lastName) { return list( "lastName" , lastName); } }所有存储库都位于pl.codeleak.samples.petclinic.repository包中。
另请参阅: https : //.io/guides/hibernate-orm-panache
使用带有RESTEasy的JAX-RS。 要创建API端点,我们需要创建JAX-RS资源:
@Path (OwnerResource.RESOURCE_PATH) @Produces (MediaType.APPLICATION_JSON) public class OwnerResource { public static final String RESOURCE_PATH = "/owners" ; @Context UriInfo uriInfo; @Inject OwnerRepository ownerRepository; @Inject PetRepository petRepository; @GET public Response getAll( @BeanParam PageRequest pageRequest) { } @GET @Path ( "{id}" ) public Response getOne( @PathParam ( "id" ) Long id) { } @GET @Path ( "{id}/pets" ) public List getPets( @PathParam ( "id" ) Long id) { } @POST @Consumes (MediaType.APPLICATION_JSON) @Transactional public Response create( @Valid Owner owner) { } }依赖注入是通过CDI完成的-上下文和依赖注入 。 资源对象将由自动配置。 必须将所有其他依赖项配置为具有CDI批注的依赖项注入。
例如,可以使用@ApplicationScoped注释存储库,然后使用@Inject注入存储库:
@ApplicationScoped public class OwnerRepository implements PanacheRepository { List findByLastName(String lastName) { return list( "lastName" , lastName); } } @ApplicationScoped public class PetRepository implements PanacheRepository { }所有资源都位于pl.codeleak.samples.petclinic.api包中。
另请参阅: https : //.io/guides/cdi-reference
如前所述,Panache为分页结果提供支持。 我们可以轻松地在我们的资源中轻松利用它:
@GET public Response getAll( @BeanParam PageRequest pageRequest) { return Response.ok(((PanacheRepository) petRepository).findAll() .page(Page.of(pageRequest.getPageNum(), pageRequest.getPageSize())) .list()).build(); }PageRequest是一个包含pageNum和pageSize查询参数的bean:
public class PageRequest { @ ( "pageNum" ) @DefaultValue ( "0" ) private int pageNum; @ ( "pageSize" ) @DefaultValue ( "10" ) private int pageSize; }使用httpie可以轻松完成分页请求:
$ http get : 8080 /owners pageNum== 0 pageSize== 2 HTTP/ 1.1 200 OK Content-Length: 250 Content-Type: application/json [ { "address" : "110 W. Liberty St." , "city" : "Madison" , "firstName" : "George" , "id" : 1 , "lastName" : "Franklin" , "telephone" : "6085551023" }, { "address" : "638 Cardinal Ave." , "city" : "Sun Prairie" , "firstName" : "Betty" , "id" : 2 , "lastName" : "Davis" , "telephone" : "6085551749" } ]在JPA中创建新对象需要活动事务。 为了将事务绑定到资源对象中的当前方法,请使用@Transactional ,否则在方法执行期间将引发异常:
@POST @Consumes (MediaType.APPLICATION_JSON) @Transactional public Response create( @Valid Owner owner) { ownerRepository.persist(owner); var location = uriInfo.getAbsolutePathBuilder() .path( "{id}" ) .resolveTemplate( "id" , owner.getId()) .build(); return Response.created(location).build(); }使用httpie创建新资源:
$ http post : 8080 /ownersCI框架连接数据库配置操作以及多数据库操作
C语言关键字及其解释介绍 C语言32个关键字详解
asp 简单读取数据表并列出来 ASP如何快速从数据库读取大量数据
C语言中sizeof是什么意思 c语言里sizeof怎样用法详解
将视频设置为Android手机开机动画的教程
IcePHP框架中的快速后台中的通用CRUD功能框架
java中的info是什么意思
PHP中include和require区别之我见
PHP中的魔术方法 :__construct, __destruct , __call, __callStatic,__get, __set, __isset, __unset , __sleep,
PHP中的(++i)前缀自增 和 (i++)后缀自增
2014-09-05
2014-09-05
2022-03-22
2014-09-05
2022-03-17
2017-05-10
2022-03-17
2014-09-05
2022-03-21
2022-03-22