1.简介
在本教程中,我们想使用流行的开源数据库PostgreSQL运行Spring Boot应用程序。在上一篇文章中,我们研究了Docker Compose一次处理多个容器。因此,我们将使用Docker Compose来运行Spring Boot和PostgreSQL ,而不是将PostgreSQL作为单独的应用程序安装。
2.创建Spring Boot项目
让我们转到Spring Initializer并创建我们的Spring Boot项目。我们将添加PostgreSQL Driver
和Spring Data JPA
模块。下载生成的ZIP文件并将其解压缩到文件夹后,我们可以运行我们的新应用程序:
./mvnw spring-boot:run
该应用程序失败,因为它无法连接到数据库:
***************************
APPLICATION FAILED TO START
***************************
Description:
Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.
Reason: Failed to determine a suitable driver class
3. Dockerfile
在使用Docker Compose启动PostgreSQL之前,我们需要将Spring Boot应用程序转换为Docker映像。第一步是将应用程序打包为JAR文件:
./mvnw clean package -DskipTests
在这里,在打包应用程序之前,我们首先清理以前的版本。另外,我们跳过了测试,因为它们在没有PostgreSQL的情况下失败了。
target
目录中有一个应用程序JAR文件。该文件的名称中包含项目名称和版本号,并以-SNAPSHOT.jar
。因此其名称可能是docker-spring-boot-postgres-0.0.1-SNAPSHOT.jar
。
让我们创建新的src/main/docker
目录。之后,我们将应用程序JAR文件复制到此处:
cp target/docker-spring-boot-postgres-0.0.1-SNAPSHOT.jar src/main/docker
最后,我们在同一目录中Dockerfile
FROM adoptopenjdk:11-jre-hotspot
ARG JAR_FILE=*.jar
COPY ${JAR_FILE} application.jar
ENTRYPOINT ["java", "-jar", "application.jar"]
这个文件描述了Docker应该如何运行我们的Spring Boot应用程序。它使用AdoptOpenJDK中的Java 11,并将应用程序JAR文件复制到application.jar
。然后,它将运行该JAR文件以启动我们的Spring Boot应用程序。
4. Docker撰写文件
现在,让我们编写我们的Docker Compose文件docker-compose.yml
,并将其保存在src/main/docker
:
version: '2'
services:
app:
image: 'docker-spring-boot-postgres:latest'
build:
context: .
container_name: app
depends_on:
- db
environment:
- SPRING_DATASOURCE_URL=jdbc:postgresql://db:5432/compose-postgres
- SPRING_DATASOURCE_USERNAME=compose-postgres
- SPRING_DATASOURCE_PASSWORD=compose-postgres
- SPRING_JPA_HIBERNATE_DDL_AUTO=update
db:
image: 'postgres:13.1-alpine'
container_name: db
environment:
- POSTGRES_USER=compose-postgres
- POSTGRES_PASSWORD=compose-postgres
我们应用程序的名称是app.
这是两项服务中的第一个(第4-15行):
- Spring Boot Docker映像的名称为
docker-spring-boot-postgres:latest
(第5行)。Dockerfile
构建该映像(第6-7行) - 容器名称是
app
(第8行)。它取决于db
服务(第10行)。这就是为什么它在db
容器之后开始 - 我们的应用程序使用
db
PostgreSQL容器作为数据源(第12行)。数据库名称,用户名和密码均为compose-postgres
(第12-14行) - Hibernate将自动创建或更新所需的任何数据库表(第15行)
PostgreSQL数据库的名称为db
,是第二个服务(第17-22行):
- 我们使用PostgreSQL 13.1(第18行)
- 容器名称是
db
(第19行) - 用户名和密码均为
compose-postgres
(第21-22行)
5.使用Docker Compose运行
让我们使用Docker Compose运行我们的Spring Boot应用程序和PostgreSQL :
docker-compose up
首先,这将为我们的Spring Boot应用程序构建Docker映像。接下来,它将启动一个PostgreSQL容器。最后,它将启动我们的应用程序Docker映像。这次,我们的应用程序运行良好:
Starting DemoApplication v0.0.1-SNAPSHOT using Java 11.0.9 on f94e79a2c9fc with PID 1 (/application.jar started by root in /)
[...]
Finished Spring Data repository scanning in 28 ms. Found 0 JPA repository interfaces.
[...]
Started DemoApplication in 4.751 seconds (JVM running for 6.512)
如我们所见,Spring Data找不到存储库接口。没错-我们还没有创建一个!
如果要停止所有容器,则需要先按[Ctrl-C]。然后,我们可以停止Docker Compose:
docker-compose down
6.创建客户实体和存储库
要在我们的应用程序中使用PostgreSQL数据库,我们将创建一个简单的客户实体:
@Entity
@Table(name = "customer")
public class Customer {
@Id
@GeneratedValue
private long id;
@Column(name = "first_name", nullable = false)
private String firstName;
@Column(name = "last_name", nullable = false)
private String lastName;
Customer
具有一个生成的id
属性和两个必需属性: firstName
和lastName
。
现在,我们可以为该实体编写存储库接口:
public interface CustomerRepository extends JpaRepository<Customer, Long> { }
通过简单地扩展JpaRepository
,我们继承了用于创建和查询Customer
实体的方法。
最后,我们将在我们的应用程序中使用以下方法:
@SpringBootApplication
public class DemoApplication {
@Autowired
private CustomerRepository repository;
@EventListener(ApplicationReadyEvent.class)
public void runAfterStartup() {
List allCustomers = this.repository.findAll();
logger.info("Number of customers: " + allCustomers.size());
Customer newCustomer = new Customer();
newCustomer.setFirstName("John");
newCustomer.setLastName("Doe");
logger.info("Saving new customer...");
this.repository.save(newCustomer);
allCustomers = this.repository.findAll();
logger.info("Number of customers: " + allCustomers.size());
}
}
- 我们通过依赖注入访问我们的
Customer
- 我们使用存储库查询现有客户的数量-这将为零
- 然后我们创建并保存客户
- 当我们再次查询现有客户时,我们希望找到刚才创建的客户
7.再次运行Docker Compose
要运行更新的Spring Boot应用程序,我们需要首先对其进行重建。因此,我们在项目根目录中再次执行以下命令:
./mvnw clean package -DskipTests
cp target/docker-spring-boot-postgres-0.0.1-SNAPSHOT.jar src/main/docker
我们如何使用此更新的应用程序JAR文件重建Docker映像?最好的方法是删除现有的Docker映像,该映像的名称我们在docker-compose.yml
指定。这将迫使Docker在下次启动Docker Compose文件时再次构建映像:
cd src/main/docker
docker-compose down
docker rmi docker-spring-boot-postgres:latest
docker-compose up
因此,在停止容器后,我们将删除应用程序Docker映像。然后,我们再次启动Docker Compose文件,该文件将重建应用程序映像。
这是应用程序的输出:
Finished Spring Data repository scanning in 180 ms. Found 1 JPA repository interfaces.
[...]
Number of customers: 0
Saving new customer...
Number of customers: 1
Spring Boot找到了我们空的客户仓库。因此,我们从没有客户开始,然后成功创建一个客户。
8.结论
在这个简短的教程中,我们首先为PostgreSQL创建一个Spring Boot应用程序。接下来,我们编写了一个Docker Compose文件,以将我们的应用程序容器与PostgreSQL容器一起运行。
最后,我们创建了一个客户实体和存储库,这使我们可以将客户保存到PostgreSQL。
0 评论