Web应用的创建笔记(1)_创建一个简单的前后端+数据库的WEB应用

最近转到了研发部门,作为Product Owner,需要了解一下现在开发企业级应用的一些相关技术,为此把学习的成果记录下来,也希望有需要的朋友可以作为参考。

这个学习成果将会通过一系列的博客来记录下来。我的想法是,实现一个比较全面的WEB应用,这个应用将搭建在AZURE云平台,涉及到的相关技术包括了Spring boot, Angular, MySQL, Redis, Cassandra, Keycloak, KONG APIgateway, Docker, Microservice等等。

首先第一篇是先从简单的WEB应用搭建开始,演示一个简单的服务器端从数据库读取数据,通过REST API把查询结果返回给前端。前端采用Angular搭建,把结果呈现给客户。具体分为以下几个部分:

1.    数据库采用mysql搭建

2.    后端采用Springboot搭建,通过REST API提供数据

3.    前端用Angular搭建,通过HTTP来调用REST API

数据库的创建

先用MYSQL创建一个数据库test,里面包含一张数据表product

mysql> CREATE DATABASE test;
mysql> USE test
mysql> CREATE TABLE product (id Serial, name VARCHAR(20), description VARCHAR(512));
mysql> INSERT INTO product (name, description)
    -> VALUES ('product1','this is a test');
mysql> INSERT INTO product (name, description)
    -> VALUES ('product2','thisis another test');

后端的创建

在start.spring.io网页中,创建一个project,依赖关系要输入web, jpa, mysql

在IDEA里面打开刚才创建的project

新建一个product entity, 代码如下:

package com.example.demo;
import javax.persistence.Entity;
import javax.persistence.Table;
import javax.persistence.Column;
import javax.persistence.Id;

@Entity
@Table(name="product")
public class Product {
  @Id
  @Column(name="id")
  private Long id;
  @Column(name="name")
  private String name;
  @Column(name="description")
  private String description;
  public Long getId() {
    return id;
  }

  public void setId(Long id){
    this.id = id;
  }

  public String getName() {
    return name;
  }

  public void setName(Stringname) {
    this.name = name;
  }

  public String getDescription() {
    return description;
  }

  public void setDescription(String description) {
    this.description = description;
  }
}

建立一个数据存取的repository,代码如下:

package com.example.demo;
import java.util.List;
import org.springframework.data.jpa.repository.JpaRepository;

public interface ProductRepository extends JpaRepository<Product,Long>{
}

建立一个RestController,用于处理web请求,并把处理结果以JSON的格式返回,代码如下:

package com.example.demo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.CrossOrigin;
import java.util.List;

@RestController
public class ProductController {
  private ProductRepository productRepository;
  @Autowired
  public ProductController(
    ProductRepository productRepository) {
      this.productRepository = productRepository;
    }

  @CrossOrigin(origins ="http://localhost:4200")   //这个用于解决跨域访问的问题
  @RequestMapping("/all")
  public List allProducts(Model model) {
    List<Product>productList =
      productRepository.findAll();
    return productList;
  }
}

Springboot自动创建的Application不用更改,代码如下:

package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DemoApplication {
  public static voidmain(String[] args) {
    SpringApplication.run(DemoApplication.class,args);
  }
}

在application.properties文件中,增加以下配置信息:

server.port=9090
spring.datasource.url = jdbc:mysql://localhost:3306/test
spring.datasource.username = root
spring.datasource.password = 123456
spring.datasource.driverClassName = com.mysql.jdbc.Driver

REST API的WEB应用已经搭建好,在IDEA的Maven projects里面运行clean, install。然后plugin里面选Springboot:run,在浏览器中打开http://localhost:9090/all即可显示所有的产品的信息,以json的格式显示。

前端的创建

前端采用Angular搭建显示界面

1.   创建一个Angular项目,在命令行输入ngnew my-app

2.   在my-app/src/app目录下,创建一个product的类,代表数据实体。新建一个product.ts的文件,代码如下:

export class Product {
  id: number;
  name: string;
  description: string;
}

3.   创建一个显示所有product的component,在命令行输入ng generate component products。

对于新创建的my-app/src/app/products下面的products.component.ts文件,修改代码如下:

import { Component, OnInit } from '@angular/core';
import { Product } from '../product';
import { ProductService } from '../product.service';  //productServic是用于读取数据的Service

@Component({
  selector: 'app-products',
  templateUrl:'./products.component.html',
  styleUrls: ['./products.component.css']
})

export class ProductsComponent implements OnInit {
  products: Product[];
  constructor(private productService: ProductService) { } 
  ngOnInit() {
    this.getProducts();
  }

  getProducts(): void {
    this.productService.getProducts()
      .subscribe(products=> this.products = products); //subscribe是异步方式,在拿到数据后调用callback函数
  }

  selectedProduct: Product;

  onSelect(product: Product):void {
    this.selectedProduct = product;
  }
}

对于products.component.html,修改如下:

<h2>Products</h2>
<ul class="products">
  <li *ngFor="letproduct of products"
   [class.selected]="product === selectedProduct"
   (click)="onSelect(product)">
    <span class="badge">{{product.id}}</span> {{product.name}}
  </li>
</ul>
<!—这是显示product具体信息的一个component,其中的[product]表示其有一个@input的属性,是依赖于products component来绑定的-->
<app-product-detail [product]="selectedProduct"></app-product-detail>

4.   创建一个service,用于调用RESTAPI,读取数据。在命令行输入ng generate service product

在自动创建的my-app/src/app/product.service.ts文件中,修改代码如下:

import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Product } from './product';

@Injectable()
export class ProductService {
  private productsUrl ='http://localhost:9090/all';  //这是REST API的URL

  constructor(private http:HttpClient) { }

  getProducts ():Observable<Product[]> {
    returnthis.http.get<Product[]>(this.productsUrl)
  }
}

5.   创建一个用于显示具体product信息的component,在命令行输入ng generate component product-detail

对my-app/src/app/component/product-detail.component.ts文件,修改代码如下:

import { Component, OnInit, Input } from '@angular/core';
import { Product } from '../product';
@Component({
  selector:'app-product-detail',
  templateUrl:'./product-detail.component.html',
  styleUrls:['./product-detail.component.css']
})

export class ProductDetailComponent implements OnInit {
  @Input() product: Product;   //表示这个属性是需要外部输入的
  constructor() { }

  ngOnInit() {
  }
}

对于my-app/src/app/component/product-detail.component.html文件,修改代码如下:

<div *ngIf="product">
  <h2>{{ product.name |uppercase }} Details</h2>
  <div><span>id:</span>{{product.id}}</div>
  <div>
    <label>name:
      <input [(ngModel)]="product.name" placeholder="name"/>
    </label>
  </div>
  <div>
    <label>description:
      <input [(ngModel)]="product.description"placeholder="description"/>
    </label>
  </div>
</div>

6.   对于my-app/src/app/app.module.ts,需要修改代码如下:

import { NgModule } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { HttpClientModule }   from '@angular/common/http';
import { AppComponent } from './app.component';
import { ProductsComponent } from './products/products.component';
import { ProductDetailComponent } from'./product-detail/product-detail.component';
import { ProductService } from './product.service';

@NgModule({
  declarations: [
    AppComponent,
    ProductsComponent,
    ProductDetailComponent
  ],

  imports: [
    BrowserModule,
    FormsModule,
    HttpClientModule
  ],

  providers: [
    ProductService
  ],

  bootstrap: [AppComponent]
})

export class AppModule { }

7.   最后在命令行输入ng serve –open,在浏览器打开http://localhost:4020,即可看到显示了products列表,如果点击某一个product,在下方会显示该product的具体信息。


至此,一个简单的前后端+数据库的应用已经搭建完毕,以后将继续丰富这个应用的功能

猜你喜欢

转载自blog.csdn.net/gzroy/article/details/80136832