Spring Boot + Angular 8 CRUD 示例

本文详细介绍了如何在SpringBoot后端创建RESTful API并与Angular8前端集成,涵盖添加、查看、编辑和删除学生操作的完整步骤,包括数据库配置、依赖管理、实体定义及前端UI开发。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这个页面上,我们将把Spring Boot RESTful 服务与 Angular 8 集成,逐步执行创建、读取、更新和删除(CRUD)操作。Angular 是最流行的开源 Web 应用程序框架之一,而 Spring Boot 使您可以轻松地创建可以“直接运行”的独立、生产就绪的应用程序。

您将构建什么

在这个演示中,您将从头开始创建 Spring Boot RESTful API(后端)和 Angular 8 用户界面(前端)来执行以下操作:

  1. 添加学生
  2. 查看学生名单
  3. 编辑学生
  4. 删除学生

为了更容易理解,我们将本教程分为两部分:

  • 后端→ 使用 Spring Boot 创建 REST 端点并使用 Spring Data JPA 访问数据库。
  • 前端→ 使用 Angular 8 创建用户界面服务(网页)。

先决条件

我们在创建这个 Spring Boot + Angular 8 CRUD 应用程序时使用了以下技术。

  1. 后端
    • Spring Boot 2.1.9.RELEASE
    • Java 8
    • Spring Data JPA
    • MySQL 数据库
  2. 前端
    • Nodejs v10.16.2
    • npm 6.9.0
    • Angular CLI 8.3.3

让我们开始真正的编码……

1.后端-API开发

我们将创建一个公开 GET、ADD、EDIT、DELETE API 的 Spring Boot 应用程序,以便客户端可以使用它。

1.1 需要依赖

将以下依赖项添加到您的pom.xml文件中。

pom.xml
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.1.9.RELEASE</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.websparrow</groupId>
	<artifactId>AgularDemo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>Demo</name>
	<description>Demo project for Spring Boot+ Angular 8</description>
	<properties>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>
	</dependencies>
	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>
复制

1.2 项目结构

我们在 STS 4 IDE 中的应用程序的最终项目结构将如下所示:

1.3 创建数据库

打开您的 MySQL 数据库并通过以下命令创建一个新数据库。

#create database <database-name-of-your-choice>;
CREATE DATABASE spring_angular;
复制

您还可以使用之前创建的数据库。

不用担心创建表,Spring Data JPA 会管理它。

1.4 应用程序.properties

在application.properties文件中设置您的数据库连接字符串、服务器端口、上下文路径等。

application.properties

# Set application port and context path
server.servlet.context-path=/api
server.port=8080

# MySQL database connection strings
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.url=jdbc:mysql://localhost:3306/spring_angular

# JPA property settings
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.show_sql=true
复制

1.5 实体

创建一个Student包含学生所有属性​​的类。

Student.java

package org.websparrow.entity;

@Entity
@Table(name = "student")
public class Student implements Serializable {

	private static final long serialVersionUID = 1681261145191719508L;
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private int id;
	private String firstName;
	private String lastName;
	private String email;

	// Generate Getters and Setters...
}
复制

1.6 存储库

StudentRepository接口将扩展JpaRepository公开 CRUD 方法的接口。

StudentRepository.java
package org.websparrow.repository;

@Repository
public interface StudentRepository extends JpaRepository<Student, Integer> {

}
复制

1.7 数据访问层(DAO)

StudentDAO类将自动装配StudentRepository接口以在数据库级别执行操作。

StudentDAO.java
package org.websparrow.dao;

@Repository
public class StudentDAO {

	@Autowired
	private StudentRepository studentRepository;

	public List<Student> get() {
		return studentRepository.findAll();
	}

	public Student save(Student student) {
		return studentRepository.save(student);
	}

	public void delete(int id) {
		studentRepository.deleteById(id);
	}
}
复制

1.8 服务

服务层实现业务逻辑并从DAO对象调用方法。

StudentService.java

package org.websparrow.service;

@Service
public class StudentService {

	@Autowired
	private StudentDAO studentDAO;

	public List<Student> get() {
		return studentDAO.get();
	}

	public Student save(Student student) {
		return studentDAO.save(student);
	}

	public void delete(int id) {
		studentDAO.delete(id);
	}
}
复制

1.9 型号

Response模型类负责以有组织的格式显示 API 响应。

Response.java

package org.websparrow.model;

public class Response {

	// Generate Getters and Setters...
	private Object data;
	private Date date;

	public Response(Object data, Date date) {
		super();
		this.data = data;
		this.date = date;
	}
}
复制

1.10 控制器

创建StudentController将公开以下端点的类:

1. /api/student :获取学生列表

2. /api/student : POST添加一个新学生

3. /api/student : PUT更新现有学生

4. /api/student : DELETE删除学生

StudentController.java
package org.websparrow.controller;

@RestController(value = "/student")
public class StudentController {

	@Autowired
	private StudentService studentService;

	@GetMapping
	public ResponseEntity<Response> get() {
		return ResponseEntity.status(HttpStatus.OK)
				.body(new Response(studentService.get(), new Date()));
	}

	@PostMapping
	public ResponseEntity<Response> save(@RequestBody Student student) {
		return ResponseEntity.status(HttpStatus.OK)
				.body(new Response(studentService.save(student), new Date()));
	}

	@PutMapping
	public ResponseEntity<Response> update(@RequestBody Student student) {
		return ResponseEntity.status(HttpStatus.OK)
				.body(new Response(studentService.save(student), new Date()));
	}

	@DeleteMapping
	public ResponseEntity<Response> delete(@RequestParam("id") int id) {
		studentService.delete(id);
		return ResponseEntity.status(HttpStatus.OK)
				.body(new Response(true, new Date()));
	}
}
复制

1.11 Web MVC 配置

当我们尝试在后端项目之外使用 JavaScript 使用 API 时,Web 浏览器会发出有关CORS的警告。因此,为了处理这个问题,我们允许所有来源与我们的 API 连接。

WebConfiguration.java
package org.websparrow.config;

@Configuration
@EnableWebMvc
public class WebConfiguration implements WebMvcConfigurer {

	@Override
	public void addCorsMappings(CorsRegistry registry) {
		registry.addMapping("/**").allowedOrigins("*").allowedMethods("GET",
				"HEAD", "POST", "PUT", "DELETE", "OPTIONS", "PATCH");
		WebMvcConfigurer.super.addCorsMappings(registry);
	}
}
复制

最后,REST API 的开发完成并可以使用了。

2.前端-UI开发

用户界面是人类可以与计算机(应用程序)交互的地方。Angular 8 用于创建用户界面并将使用上述 API。

要进行前端开发,您必须按照以下步骤操作:

1.根据您的操作系统下载 Nodejs 表单,链接如下:

2.安装 Nodejs 后安装 Angular CLI:它是一个命令行工具,用于在您的机器上全局构建、搭建和安装 angular-cli:

npm install -g @angular/cli
复制

3.通过键入以下命令创建一个 Angular 项目。它将创建一个骨架项目结构,如下所示:

ng new springboot-angular8-ui
复制

4.让我们进入新创建的 Angular 项目:

cd springboot-angular8-ui
复制

2.1 项目结构

在 VS Code 中通过命令创建的 Angular 项目的基本骨架ng new springboot-angular8-ui如下所示:

让我们讨论一下上述结构中的一些主要文件和目录:

2.1.1 package.json

package.json文件是 Angular/Node 系统的主要构建块。它是包含项目元数据和依赖项的清单文件。NPM使用package.json文件来管理应用程序、依赖项和打包。您可以使用命令创建上述文件npm init,这将是我们下一篇文章的一部分。

2.1.2 tsconfig.json

tsconfig.json文件指导编译器生成 JavaScript 文件。它指定编译项目所需的根文件和编译器选项。

2.1.3 angular.json

该文件提供有关 Angular 应用程序环境的信息,该环境告诉系统在构建项目时替换哪些文件。它还描述了将项目的构建放在哪里以及将使用什么样的编译过程ex: aotjit.

2.1.4 源

此文件夹包含根级应用程序项目。

2.1.5 节点模块

它为整个项目提供npm包。

2.1.6 package-lock.json

当npm修改node_modules树或package.json时,会自动创建此文件。它描述了依赖关系树,以便保证队友、部署和持续集成安装完全相同的依赖关系。因此,用户不需要将node_modules推送到存储库。

2.2 接口

创建Student与数据库具有相同字段的接口:

ng g i interface/student
复制

student.interface.ts

export interface Student {
    id: number,
    firstName: string,
    lastName: string,
    email: string
}
复制

2.3 服务

现在让我们创建一个将使用 REST API 的服务。HttpClient用于与后端服务通信。在项目结构中使用以下命令。

ng g s services/web
复制

此命令将创建一个可注入服务,您将从中使用 REST API。

HttpClientModuleapp.module.ts中导入。该HttpClient服务包含在其中,HttpClientModule因此我们需要先导入它以启动XSRFrequest.

import { HttpClientModule } from "@angular/common/http";
复制

添加HttpClientModule内部导入:

app.module.ts
@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    HttpClientModule,
    AppRoutingModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
复制

与后端服务实现基于 REST 的通信。为此,您需要使用为浏览器公开的Angular 应用程序提供HTTPHttpClient客户端 API的包。@angular/common/httpXMLHttpRequest

web.service.ts

import { environment } from "../../environments/environment";
import { Observable } from 'rxjs';
import { Student } from '../interface/student.interface';
import { HttpClient } from "@angular/common/http";
import { Injectable } from "@angular/core";
@Injectable()
export class WebService {

    constructor(private httpClient: HttpClient) { }

    serverUrl: string = "http://localhost:8080/api/"

    get(url: string): Observable<any> {
        return this.httpClient.get(this.serverUrl + url);
    }

    post(url: string, data: Student): Observable<any> {
        return this.httpClient.post(this.serverUrl + url, data);
    }

    put(url: string, data: Student): Observable<any> {
        return this.httpClient.put(this.serverUrl + url, data);
    }

    delete(url: string, data: Student): Observable<any> {
        return this.httpClient.delete(this.serverUrl + url, { params: { id: data.id + "" } });
    }
}
复制

在app.module.ts中向提供者添加服务。您必须需要使用提供程序配置注入器,否则它将不知道如何创建依赖项。

app.module.ts
@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    HttpClientModule,
    AppRoutingModule
  ],
  providers: [WebService],
  bootstrap: [AppComponent]
})
export class AppModule { }
复制

2.4 组件

组件是 Angular 应用程序的基本 UI 构建块。它控制应用程序的视图。创建student-view将显示学生列表的组件:

ng g c student-view
复制

通过使用这个命令,你的大部分工作都是由 Angular CLI 完成的,你不需要在app.module.ts中声明你的组件

 

2.4.1 设计HTML页面

现在让我们设计 HTML 页面。Bootstrap CSS 用于在此应用程序中进行样式设置,因此您需要安装以下软件包:

npm install bootstrap –save
复制

如果您不想在应用程序中包含 Bootstrap CSS,则可以跳过此步骤。

在样式部分内的angular.json文件中添加bootstrap.min.css文件。

angular.json

"styles": [
    "src/styles.css",
    "node_modules/bootstrap/dist/css/bootstrap.min.css"
]
复制

student-view.component.html

<div class="container">
    <div class="row">
        <h1 style="text-align: center;">Spring Boot + Angular 8 CRUD Example</h1>
    </div>
    <div class="row">
        <form [formGroup]="myForm" (ngSubmit)="submitForm(myForm)">
            <div class="form-row align-items-center">
                <div class="col-auto">
                    <label class="sr-only" for="inlineFormInput">First Name</label>
                    <input type="text" class="form-control mb-2" id="inlineFormInput" placeholder="First name"
                        formControlName="firstName">
                </div>
                <div class="col-auto">
                    <label class="sr-only" for="inlineFormInputGroup">Last Name</label>
                    <input type="text" class="form-control" id="inlineFormInput" placeholder="Last name"
                        formControlName="lastName">
                </div>
                <div class="col-auto">
                    <label class="sr-only" for="inlineFormInputGroup">Email</label>
                    <input type="text" class="form-control" id="inlineFormInput" placeholder="Email"
                        formControlName="email">
                </div>
                <div class="col-auto">
                    <button type="submit" class="btn btn-primary mb-2" [disabled]="!myForm.valid">Save</button>
                </div>
            </div>
        </form>
    </div>
    <div class="row">
        <table class="table table-hover">
            <thead>
                <tr>
                    <th scope="col">#</th>
                    <th scope="col">First</th>
                    <th scope="col">Last</th>
                    <th scope="col">Email</th>
                    <th scope="col">Action</th>
                </tr>
            </thead>
            <tbody>
                <tr *ngFor="let student of usersList; let i=index">
                    <th scope="row">{{i+1}}</th>
                    <td>{{student.firstName}}</td>
                    <td>{{student.lastName}}</td>
                    <td>{{student.email}}</td>
                    <td>
                        <span style="margin-right: 10px"><button (click)="edit(student)"
                                class="btn btn-primary mb-2">Edit</button> </span>
                        <span><button (click)="delete(student)" class="btn btn-primary mb-2">Delete</button></span>
                    </td>
                </tr>
            </tbody>
        </table>
    </div>
</div>
复制

编写组件以执行我们之前讨论的操作:

student-view.component.ts

import { Component, OnInit } from '@angular/core';
import { Student } from '../interface/student.interface';
import { FormGroup, FormBuilder, FormControl, Validators, Form } from '@angular/forms';
import { WebService } from '../sevices/web.service';

@Component({
  selector: 'app-student-view',
  templateUrl: './student-view.component.html',
  styleUrls: ['./student-view.component.css']
})
export class StudentViewComponent implements OnInit {

  ngOnInit(): void {
    this.createForm();
    this.getData();
  }
  url: string = 'student';
  title = 'Spring Boot + Angular 8 CRUD Example';
  usersList: Array<Student>
  student: Student = undefined
  myForm: FormGroup;

  constructor(private webService: WebService, private formBuilder: FormBuilder) { }


  private createForm() {
    this.myForm = this.formBuilder.group({
      firstName: new FormControl(this.student ? this.student.firstName : '', Validators.required),
      lastName: new FormControl(this.student ? this.student.lastName : '', Validators.required),
      email: new FormControl(this.student ? this.student.email : '', Validators.required)
    });
  }
  private submitForm(data: FormGroup) {
    if (data.valid)
      this.addStudent(data.value)
  }

  getData(): void {
    this.webService.get(this.url).subscribe(res => {
      let response = JSON.parse(JSON.stringify(res))
      this.usersList = response.data
    })
  }

  addStudent(student: Student): void {
    if (this.student)
      student.id = this.student.id
    this.webService.post(this.url, student).subscribe(res => {
      let response = JSON.parse(JSON.stringify(res))
      this.getData()
      this.myForm.reset()
      this.student = undefined
    }, error => {
    })
  }

  edit(student: Student): void {
    this.student = student
    this.myForm.controls['firstName'].setValue(this.student.firstName)
    this.myForm.controls['lastName'].setValue(this.student.lastName)
    this.myForm.controls['email'].setValue(this.student.email)
  }

  delete(student: Student): void {
    this.webService.delete(this.url, student).subscribe(res => {
      let data = JSON.parse(JSON.stringify(res))
      this.getData()
    }, error => {
    })
  }
}
复制

因为我们在我们的应用程序中使用表单。所以,我们需要用和更新我们的app.module.tsFormsModuleReactiveFormsModule

app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { FormsModule, ReactiveFormsModule } from "@angular/forms";
import { HttpClientModule } from "@angular/common/http";
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { StudentViewComponent } from './student-view/student-view.component';
import { WebService } from "./sevices/web.service";
@NgModule({
  declarations: [
    AppComponent,
    StudentViewComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    ReactiveFormsModule,
    HttpClientModule,
    AppRoutingModule
  ],
  providers: [WebService],
  bootstrap: [AppComponent]
})
export class AppModule { }
复制

现在最后一步是使用您的选择器更新app.component.html文件StutentViewComponent

app.component.html
<app-student-view></app-student-view>
复制

此标记将呈现您的学生视图组件。

3. 测试应用

最终完成后端(API)和前端(UI)的开发。要测试应用程序,您需要执行以下步骤:

1.启动您使用 Spring Boot 开发的后端 (API) 应用程序。

2.转到创建 Angular 项目的前端 (UI) 目录并点击以下命令:

npm install
复制

它将安装必要的依赖项/库/模块。

3.安装模块后,使用以下命令启动前端 (UI) 应用程序:

npm start
复制

4.现在,打开您喜欢的 Web 浏览器并点击 http://localhost:4200 URL 并执行 CRUD 操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值