[JAVA] Ich habe Angular Tutorial + SpringBoot + PostgreSQL ausprobiert

Angular + SpringBoot + PostgreSQL

Einführung

Frontend: Angular (TypeScript) Backend: Spring Boot (Java) DB: PostgreSQL

Mit Bezug auf diesen Artikel habe ich versucht, das zu machen, was der Titel sagt. Angular Tutorial + Ich habe Spring Boot ausprobiert

Voraussetzungen

Erstellen eines Projekts mit Spring Initializer Erstellt mit Maven Project Zu den Abhängigkeiten gehören "postgreSQL Driver" und "Lombok".

Der Name ist angemessen

Umgebung

Dieser Artikel wurde unter Mac erstellt, funktioniert jedoch unter Windows einwandfrei. (7 wurde bestätigt, 10 weiß es nicht)

% sw_vers
ProductName:    Mac OS X
ProductVersion: 10.15.2
BuildVersion:   19C57

% osascript -e 'version of app "IntelliJ IDEA"'   
2019.3.1

% java --version
java 11.0.4 2019-07-16 LTS
Java(TM) SE Runtime Environment 18.9 (build 11.0.4+10-LTS)
Java HotSpot(TM) 64-Bit Server VM 18.9 (build 11.0.4+10-LTS, mixed mode)

 % postgres --version
postgres (PostgreSQL) 12.1

% ng --version
Angular CLI: 8.3.4
Node: 11.12.0
OS: darwin x64
Angular: 
... 

Package                      Version
------------------------------------------------------
@angular-devkit/architect    0.803.4
@angular-devkit/core         8.3.4
@angular-devkit/schematics   8.3.4
@schematics/angular          8.3.4
@schematics/update           0.803.4
rxjs                         6.4.0

PostgreSQL Wir gehen davon aus, dass PostgreSQL bereits installiert ist. Dieses Mal verwende ich ein Schema.

Schemaerstellung & Tabellenerstellung

CREATE SCHEMA tutorial
CREATE TABLE tutorial.heroes(
    id INT,
    name VARCHAR(64)
)

Mock-Daten einfügen

INSERT INTO tutorial.heroes VALUES
(1, 'Kapitän Amerika'),
(2, 'Ironman'),
(3, 'Hulk'),
(4, 'Also Odinson'),
(5, 'Schwarze Witwe'),
(6, 'Falkenauge'),
(7, 'Wijon'),
(8, 'Scharlachrote Hexe'),
(9, 'Falke'),
(10, 'Kriegsmaschine'),
(11, 'Captain Marvel');

Jetzt ist PostgreSQL fertig.

Angular Wir gehen davon aus, dass alle Angular Tutorial abgeschlossen sind.

Serviceklasse

Ändern Sie die Serviceklasse heroUrl in die REST-API-URL.

hero.service.ts


...
//Abkürzung

export class HeroService {
// private heroesUrl = 'api/heroes';  //Web-API-URL
  private heroesUrl = 'http://localhost:8080'; // <=Hier hinzufügen

  httpOptions = {
    headers: new HttpHeaders({ "Content-Type": "application/json" })
  };

  constructor(
    private http: HttpClient,
    private messageService: MessageService
  ) {}

//Abkürzung
...

app.module.ts

Um die Daten zu erhalten, indem Sie tatsächlich auf die API klicken, anstatt sich zu verspotten Kommentieren Sie das HttpClientInMemoryWebApiModule aus, das sich wie ein API-Server verhält.

app.module.ts


@NgModule({
  declarations: [
    AppComponent,
    HeroesComponent,
    HeroDetailComponent,
    MessagesComponent,
    DashboardComponent,
    HeroSearchComponent
  ],
  imports: [
    BrowserModule,
    FormsModule,
    AppRoutingModule,
    HttpClientModule
    // HttpClientInMemoryWebApiModule.forRoot(
    //   InMemoryDataService, { dataEncapsulation: false }
    // )
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule {}

Heldenkomponente

heroes.component.ts


add(name: string): void {
    name = name.trim();
    //↓ Addiere 1 zum letzten Element als ID des neuen Helden
    let id = this.heroes.slice(-1)[0].id + 1;
    if (!name) { return; }
    //ID hinzufügen und Argument als Held übergeben
    this.heroService.addHero({ name, id } as Hero)
      .subscribe(hero => {
        this.heroes.push(hero);
      });
  }

Damit sind die Winkeländerungen abgeschlossen.

Backend-Seite (Java)

Hero class Erstellen Sie eine Heldenklasse für die Definition des Heldentyps. Da ich Lombok benutze, brauche ich keinen Setter und Getter. (In Intellij müssen Sie Lombok in Plugin setzen)

Hero.java


package tutorial.tutorial.model;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;

@AllArgsConstructor
@Data
@NoArgsConstructor
@ToString
public class Hero {
    private Integer id;
    private String name;
}

HeroDAO class Erstellen Sie eine DAO-Klasse, um auf die Datenbank zuzugreifen. Erstellen Sie die gesamte CRUD-Verarbeitung.

HeroDAO.java


package tutorial.tutorial.model;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

public class HeroDAO {

    /**
     *Methode zum Herstellen von DB-Verbindungsinformationen
     *
     * @Informationen zur Verbindungsverbindung zurückgeben
     */
    public Connection getConnection() throws ClassNotFoundException, SQLException {
        //Bereiten Sie Variablen zum Speichern von Verbindungsinformationen vor
        Connection conn = null;
        //Initialisieren
        Class.forName("org.postgresql.Driver");
        //Geben Sie die DB-Informationen ein
        conn = DriverManager.getConnection("jdbc:postgresql://localhost/postgres?currentSchema=tutorial", "postgres", "postgres");
        //Deaktivieren Sie die automatische Festschreibung
        conn.setAutoCommit(false);
        //Gibt Verbindungsinformationen zurück
        return conn;
    }

    /**
     *Methode, um alle Helden zu erhalten und zurückzugeben
     *
     * @Heldenliste zurückgeben Heldenliste
     */
    public List<Hero> findAll() throws ClassNotFoundException, SQLException {
        //Bereiten Sie Variablen zum Speichern von Verbindungsinformationen vor
        Connection conn = null;
        //Zum Speichern von Instanzen der Klasse dto
        List<Hero> heroes = new ArrayList<>();


        //Verbindung zur Datenbank herstellen
        try {
            conn = getConnection();
            //Objekterstellung zum Ausführen von SQL-Anweisungen
            Statement pstmt = conn.createStatement();
            //Ausgabe der SELECT-Anweisung
            String sql = "SELECT * FROM tutorial.heroes";
            //Ruft das Ausführungsergebnis der SQL-Anweisung ab (Wert von DB empfangen)
            ResultSet rs = pstmt.executeQuery(sql);

            //Wiederholen Sie den von DB empfangenen Wert für jeden Datensatz
            while (rs.next()) {
                // Hero(DTO)Erstellen Sie eine Instanz der Klasse
                Hero dto = new Hero();
                //Stellen Sie den Spalten-ID-Wert ein
                dto.setId(rs.getInt("id"));
                //Legen Sie den Wert des Spaltennamens fest
                dto.setName(rs.getString("name"));
                //Instanz in Liste speichern
                heroes.add(dto);
                //Fahren Sie mit der while-Anweisung mit der nächsten Datensatzverarbeitung fort(Wenn da ist)
            }
            //Fehler catch-Anweisung
        } catch (SQLException e) {
            e.printStackTrace();
            //Verarbeitung, die ausgeführt werden soll, unabhängig davon, ob eine Ausnahme auftritt
        } finally {
            //Wenn der Inhalt von conn enthalten ist, trennen Sie die Datenbankverbindung
            if (conn != null) {
                conn.close();
            }
        }
        //Gibt eine Liste der Instanzen der DTO-Klasse zurück
        return heroes;
    }


    /**
     *Eine Methode zum Abrufen und Zurückgeben von Hero, die der als Argument erhaltenen ID entspricht
     *
     * @param id
     * @return selectedHero
     */
    public Hero findOneHero(int id) throws ClassNotFoundException, SQLException {
        Connection conn = null;
        Hero selectedHero = new Hero();

        //Verbindung zur Datenbank herstellen
        try {
            conn = getConnection();
            //Ausgabe der SELECT-Anweisung
            String sql = "SELECT * FROM tutorial.heroes WHERE id = ?";

            //Objekterstellung zum Ausführen von SQL-Anweisungen
            PreparedStatement pstmt = conn.prepareStatement(sql);

            //Legen Sie die empfangene ID als Argument im Platzhalter fest.
            pstmt.setInt(1, id);

            //Ruft das Ausführungsergebnis der SQL-Anweisung ab (Wert von DB empfangen)
            ResultSet rs = pstmt.executeQuery();

            //Setzen Sie den von DB empfangenen Wert auf dto.
            while (rs.next()) {
                // Hero(DTO)Erstellen Sie eine Instanz der Klasse
                Hero dto = new Hero();
                //Stellen Sie den Spalten-ID-Wert ein
                dto.setId(rs.getInt("id"));
                //Legen Sie den Wert des Spaltennamens fest
                dto.setName(rs.getString("name"));
                //
                selectedHero = dto;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            if (conn != null) {
                conn.close();
            }
        }
        return selectedHero;
    }

    /**
     *Eine Methode zum Aktualisieren von Hero, die mit der im Argument empfangenen ID übereinstimmt
     *
     * @param hero
     */
    public void updateHero(Hero hero) throws ClassNotFoundException, SQLException {
        Connection conn = null;
        try {
            conn = getConnection();
            String sql = "UPDATE tutorial.heroes SET name = ? WHERE id = ?";
            PreparedStatement pstmt = conn.prepareStatement(sql);
            pstmt.setString(1, hero.getName());
            pstmt.setInt(2, hero.getId());
            pstmt.executeUpdate();
            conn.commit();

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            if (conn != null) {
                conn.close();
            }
        }
    }

    /**
     *Eine Methode zum Löschen von Hero, die mit der im Argument empfangenen ID übereinstimmt
     *
     * @param id id des Helden, den Sie löschen möchten
     */
    public void deleteHero(int id) throws ClassNotFoundException, SQLException {
        Connection conn = null;
        try {
            conn = getConnection();
            String sql = "DELETE FROM tutorial.heroes WHERE id = ?";
            PreparedStatement pstmt = conn.prepareStatement(sql);
            pstmt.setInt(1, id);
            pstmt.executeUpdate();
            conn.commit();

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            if (conn != null) {
                conn.close();
            }
        }
    }

    /**
     *Eine Methode zum Einfügen eines neuen Helden mit der ID und dem Namen, die als Argumente empfangen wurden
     *
     * @param hero
     */
    public void createHero(Hero hero) throws ClassNotFoundException, SQLException {
        Connection conn = null;
        try {
            conn = getConnection();
            String sql = "INSERT INTO tutorial.heroes VALUES(?, ?)";

            //Objekterstellung zum Ausführen von SQL-Anweisungen
            PreparedStatement pstmt = conn.prepareStatement(sql);

            //Legen Sie die empfangene ID als Argument im Platzhalter fest.
            pstmt.setInt(1, hero.getId());
            pstmt.setString(2, hero.getName());

            //Ruft das Ausführungsergebnis der SQL-Anweisung ab (Wert von DB empfangen)
            pstmt.executeUpdate();
            conn.commit();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            if (conn != null) {
                conn.close();
            }
        }
    }
}

HeroController class

Erstellen Sie eine REST-API. Ich habe die folgenden fünf erstellt. --GetHeroes gibt alle Helden zurück --getHero, um den mit id verknüpften Helden zurückzugeben --Erstelle einen neuen Helden

Die gemäß dem Tutorial empfangenen Daten sind auf Hero eingestellt.

HeroContoller.java


package tutorial.tutorial.controller;

import org.springframework.web.bind.annotation.*;
import tutorial.tutorial.model.*;
import java.sql.SQLException;
import java.util.*;

@RestController
public class HeroController {

    /**
     *Eine Methode, die alle Helden aus der DAO-Klasse empfängt
     *
     * @return heroList 
     */
    @GetMapping("/")
    public List<Hero> getHeroes() throws SQLException, ClassNotFoundException {
        HeroDAO dao = new HeroDAO();
        List<Hero> heroes = dao.findAll();
        List<Hero> heroList = new ArrayList<>();
        heroList.addAll(heroes);
        return heroList;
    }

    /**
     *Eine Methode, die den mit der ID verknüpften Helden von der DAO-Klasse empfängt
     *
     * @param id
     * @return hero
     */
    @GetMapping("/{id}")
    public Hero getHero(@PathVariable Integer id) throws SQLException, ClassNotFoundException {
        HeroDAO dao = new HeroDAO();
        Hero hero = dao.findOneHero(id);
        return hero;
    }

    /**
     *Eine Methode zum EINFÜGEN mit der empfangenen ID und dem Namen in der DAO-Klasse
     *
     * @param newHero
     * @return hero
     */
    @PostMapping("/")
    public Hero create(@RequestBody Hero newHero) throws SQLException, ClassNotFoundException {
        HeroDAO dao = new HeroDAO();
        dao.createHero(newHero);
        return newHero;
    }


    /**
     *Eine Methode zum LÖSCHEN des mit id in der DAO-Klasse verknüpften Helden
     *
     * @param id
     */
    @DeleteMapping("/{id}")
    public void delete(@PathVariable Integer id) throws SQLException, ClassNotFoundException {
        HeroDAO dao = new HeroDAO();
        dao.deleteHero(id);
    }

    /**
     *Eine Methode zum AKTUALISIEREN des Helden, der der ID in der DAO-Klasse zugeordnet ist
     *
     * @param updatedHero
     */
    @PutMapping("/")
    public Hero update(@RequestBody Hero updatedHero) throws SQLException, ClassNotFoundException {
        HeroDAO dao = new HeroDAO();
        dao.updateHero(updatedHero);
        return updatedHero;
    }

}

CORS-kompatibel

Aus Sicherheitsgründen kann Ajax usw. nur von SOP Ressourcen desselben Ursprungs erwerben. Da sich die Portnummern diesmal zwischen Angular und Spring Boot unterscheiden, muss CORS aktiviert werden, um die SOP nur zwischen vertrauenswürdigen Ursprüngen freizugeben.

WebConfig.java


package tutorial.tutorial.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer{
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/*")
                //Geben Sie die zuzulassende Portnummer an(Winkelseite)
                .allowedOrigins("http://localhost:3000")
                //Liste der zulässigen Methoden
                .allowedMethods("GET", "POST", "DELETE", "PUT")
                //Zulässiger Header
                .allowedHeaders("Origin", "X-Requested-With", "Content-Type", "Accept")
                .allowCredentials(false).maxAge(3600);
    }
}

Lauf

Lassen Sie uns TutorialApplication und Angular ausführen. Sie können bestätigen, dass die API aufgerufen wird und die Datenbank betrieben wird.

Zusammenfassung

Um zu verstehen, wie die Webanwendung aussieht, habe ich einen Austausch mit Angular als Front-End, Spring Boot als Back-End und PostgreSQL als Datenbank durchgeführt, die eng mit Ionic verwandt sind, das ich normalerweise verwende. ..

Recommended Posts

Ich habe Angular Tutorial + SpringBoot + PostgreSQL ausprobiert
[Ich habe es versucht] Spring Tutorial
Ich habe UPSERT mit PostgreSQL ausprobiert.
Ich habe versucht, OnlineConverter mit SpringBoot + JODConverter zu verwenden
Ich habe Angular gestartet
Ich habe es mit Spring versucht.
Ich habe versucht, Tomcat zu setzen
Ich habe youtubeDataApi ausprobiert.
Ich habe versucht, ① umzugestalten
Ich habe FizzBuzz ausprobiert.
Ich habe JHipster 5.1 ausprobiert
Ich habe versucht, Autoware auszuführen
Ich habe versucht, Gson zu benutzen
Ich habe sofort QUARKUS ausprobiert
Ich habe versucht, TestNG zu verwenden
Ich habe Spring Batch ausprobiert
Ich habe versucht, Galasa zu benutzen
Ich habe versucht, node-jt400 (Programme)
Ich habe versucht, node-jt400 (ausführen)
Ich habe versucht, node-jt400 (Transaktionen)
Ich habe versucht, node-jt400 (Umgebungskonstruktion)
Ich habe DI mit Ruby versucht
Ich habe versucht, node-jt400 (IFS schreiben)
Ich habe versucht, node-jt400 (SQL Update)
Ich habe versucht, Azure Cloud-Init zu verwenden
Ich habe Spring State Machine ausprobiert
Ich habe Drools (Java, InputStream) ausprobiert.
Ich habe Rails Anfänger ausprobiert [Kapitel 1]
Ich habe versucht, Apache Wicket zu verwenden
Ich habe versucht, node-jt400 (SQL-Abfrage)
Ich habe versucht, Java REPL zu verwenden
Ich habe versucht, den Quellcode zu analysieren
Ich habe das FizzBuzz-Problem ausprobiert
Ich habe versucht, node-jt400 (SQL-Stream)
Ich habe versucht, node-jt400 (IFS lesen)
Ich habe Rails Anfänger ausprobiert [Kapitel 2]
Ich habe BIND mit Docker ausprobiert
Ich habe versucht, yum-cron zu verifizieren
Ich habe versucht, Metaprogrammierung mit Java