API Bahagian Belakang Perusahaan NestJS · Pelajaran

Operasi CRUD dengan TypeORM

Bangunkan fungsi Cipta, Baca, Kemas Kini dan Padam yang lengkap untuk entiti anda menggunakan repositori TypeORM.

Pelajaran 2 daripada 311 langkah

Operasi CRUD dengan TypeORM ialah pelajaran API Bahagian Belakang Perusahaan NestJS percuma di CoddyKit. Ini ialah pelajaran 2 daripada 3. Anda boleh membaca keseluruhan pelajaran di bawah secara percuma — kemudian berlatih secara praktikal dalam pelayar menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran API Bahagian Belakang Perusahaan NestJS, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus API Bahagian Belakang Perusahaan NestJS merangkumi sejumlah 3 pelajaran.

Asas CRUD dengan TypeORM

Selamat datang! Dalam pelajaran ini, kita akan menguasai operasi CRUD menggunakan TypeORM, iaitu Pemetaan Objek-Relasi yang berkuasa untuk TypeScript.

CRUD ialah singkatan bagi Create, Read, Update dan Delete. Ini ialah empat operasi asas untuk mengurus data dalam hampir mana-mana aplikasi.

TypeORM memudahkan interaksi dengan pangkalan data dengan memetakan baris pangkalan data kepada objek TypeScript, lalu menjadikan operasi ini lebih mudah difahami.

Mentakrifkan Entiti Product Kita

Sebelum melaksanakan CRUD, kita memerlukan entiti. Entiti ialah kelas yang dipetakan terus kepada jadual pangkalan data. Mari kita bayangkan entiti Product yang ringkas untuk contoh kita.

Dalam TypeORM, anda akan menggunakan penghias seperti @Entity(), @PrimaryGeneratedColumn() dan @Column() untuk menentukan strukturnya serta cara pemetaannya kepada skema pangkalan data anda.

Memahami Repositori

TypeORM menggunakan corak repositori. Repositori ibarat koleksi khusus yang mengendalikan capaian data untuk entiti tertentu (contohnya, ProductRepository untuk entiti Product).

Anda menyuntik repositori ini ke dalam perkhidmatan dan menggunakan kaedahnya untuk melaksanakan operasi CRUD. Repositori ini menyembunyikan kerumitan pertanyaan pangkalan data.

Cipta: Menambah Product Baharu

Untuk menambah data baharu ke pangkalan data, anda biasanya menggunakan kaedah .save() bagi repositori anda. Kaedah ini mengendalikan penyisipan baharu dan kemas kini entiti sedia ada dengan bijak.

Berikut ialah contoh ringkas untuk mencipta produk baharu:

class Product {
  id: number;
  name: string;
  price: number;
  constructor(name: string, price: number, id: number = 0) {
    this.id = id;
    this.name = name;
    this.price = price;
  }
}

class MockProductRepository {
  private products: Product[] = [];
  private nextId = 1;

  async save(product: Product): Promise<Product> {
    if (product.id === 0) { // Simulate new product
      product.id = this.nextId++;
      this.products.push(product);
    } else { // Simulate update
      const index = this.products.findIndex(p => p.id === product.id);
      if (index > -1) { this.products[index] = product; }
    }
    return product;
  }

  async find(): Promise<Product[]> {
    return this.products;
  }
}

async function main() {
  const repo = new MockProductRepository();
  console.log("--- Creating a Product ---");
  const newProduct = await repo.save(new Product("Keyboard", 75));
  console.log("Created:", newProduct);

  console.log("\n--- Current Products ---");
  const allProducts = await repo.find();
  console.log(allProducts);
}

main();

Baca: Mendapatkan Product

Membaca data ialah perkara asas. Repositori TypeORM menawarkan beberapa kaedah untuk mendapatkan entiti:

  • .find(): Mendapatkan semua entiti yang sepadan dengan kriteria yang diberikan.
  • .findOneBy(): Mendapatkan satu entiti berdasarkan syarat mudah (contohnya, berdasarkan ID).
  • .findBy(): Mendapatkan beberapa entiti berdasarkan syarat mudah.

Mari lihat cara mencari produk:

class Product {
  id: number;
  name: string;
  price: number;
  constructor(name: string, price: number, id: number = 0) {
    this.id = id;
    this.name = name;
    this.price = price;
  }
}

class MockProductRepository {
  private products: Product[] = [];
  private nextId = 1;

  async save(product: Product): Promise<Product> {
    if (product.id === 0) { product.id = this.nextId++; this.products.push(product); }
    else { const index = this.products.findIndex(p => p.id === product.id);
      if (index > -1) { this.products[index] = product; } }
    return product;
  }

  async find(): Promise<Product[]> { return this.products; }
  async findOneBy(criteria: Partial<Product>): Promise<Product | undefined> {
    return this.products.find(p =>
      Object.keys(criteria).every(key => p[key as keyof Product] === criteria[key as keyof Product])
    );
  }
}

async function main() {
  const repo = new MockProductRepository();
  const product1 = await repo.save(new Product("Mouse", 25));
  const product2 = await repo.save(new Product("Monitor", 300));

  console.log("--- Finding All Products ---");
  let allProducts = await repo.find();
  console.log("All:", allProducts);

  console.log("\n--- Finding One Product by ID ---");
  const foundProduct = await repo.findOneBy({ id: product1.id });
  console.log("Found by ID:", foundProduct);

  console.log("\n--- Finding One Product by Name ---");
  const namedProduct = await repo.findOneBy({ name: "Monitor" });
  console.log("Found by Name:", namedProduct);
}

main();

Kemas Kini: Mengubah Butiran Product

Untuk mengubah data sedia ada, anda mempunyai dua pendekatan utama:

  • Dapatkan, Ubah, Simpan: Dapatkan entiti, kemas kini sifatnya, kemudian panggil .save() pada entiti yang telah diubah.
  • Kemas Kini Terus: Gunakan .update(criteria, partialEntity) untuk mengemas kini lajur tertentu bagi entiti yang sepadan dengan kriteria tertentu tanpa memuatkannya ke dalam memori terlebih dahulu. Kaedah ini lebih cekap untuk kemas kini pukal.
class Product {
  id: number;
  name: string;
  price: number;
  constructor(name: string, price: number, id: number = 0) {
    this.id = id;
    this.name = name;
    this.price = price;
  }
}

class MockProductRepository {
  private products: Product[] = [];
  private nextId = 1;

  async save(product: Product): Promise<Product> {
    if (product.id === 0) { product.id = this.nextId++; this.products.push(product); }
    else { const index = this.products.findIndex(p => p.id === product.id);
      if (index > -1) { this.products[index] = product; } }
    return product;
  }

  async findOneBy(criteria: Partial<Product>): Promise<Product | undefined> {
    return this.products.find(p =>
      Object.keys(criteria).every(key => p[key as keyof Product] === criteria[key as keyof Product])
    );
  }
  
  async update(id: number, partialEntity: Partial<Product>): Promise<void> {
    const index = this.products.findIndex(p => p.id === id);
    if (index > -1) {
      this.products[index] = { ...this.products[index], ...partialEntity };
    }
  }
}

async function main() {
  const repo = new MockProductRepository();
  const product = await repo.save(new Product("Headphones", 150));
  console.log("Initial product:", product);

  console.log("\n--- Updating Product Price ---");
  let fetchedProduct = await repo.findOneBy({ id: product.id });
  if (fetchedProduct) {
    fetchedProduct.price = 140; 
    await repo.save(fetchedProduct);
  }
  console.log("Updated via save:", await repo.findOneBy({ id: product.id }));

  const product2 = await repo.save(new Product("Webcam", 80));
  console.log("Initial product 2:", product2);
  await repo.update(product2.id, { price: 70, name: "HD Webcam" });
  console.log("Updated via update:", await repo.findOneBy({ id: product2.id }));
}

main();

Padam: Membuang Product

Untuk membuang entiti daripada pangkalan data, TypeORM menyediakan .delete() dan .remove():

  • .delete(criteria): Membuang entiti berdasarkan ID atau syarat tertentu. Kaedah ini cekap kerana entiti tidak dimuatkan ke dalam memori terlebih dahulu.
  • .remove(entityOrEntities): Membuang entiti yang telah dimuatkan ke dalam memori (iaitu anda mempunyai objek entiti lengkap).

Mari buang satu produk daripada pangkalan data olok-olok kita:

class Product {
  id: number;
  name: string;
  price: number;
  constructor(name: string, price: number, id: number = 0) {
    this.id = id;
    this.name = name;
    this.price = price;
  }
}

class MockProductRepository {
  private products: Product[] = [];
  private nextId = 1;

  async save(product: Product): Promise<Product> {
    if (product.id === 0) { product.id = this.nextId++; this.products.push(product); }
    else { const index = this.products.findIndex(p => p.id === product.id);
      if (index > -1) { this.products[index] = product; } }
    return product;
  }

  async find(): Promise<Product[]> { return this.products; }

  async delete(id: number): Promise<void> {
    this.products = this.products.filter(p => p.id !== id);
  }
  
  async remove(product: Product): Promise<Product> {
    this.products = this.products.filter(p => p.id !== product.id);
    return product; 
  }
}

async function main() {
  const repo = new MockProductRepository();
  const productA = await repo.save(new Product("Pen", 2));
  const productB = await repo.save(new Product("Notebook", 5));
  console.log("Initial products:", await repo.find());

  console.log("\n--- Deleting Product A by ID ---");
  await repo.delete(productA.id);
  console.log("Products after delete:", await repo.find());

  console.log("\n--- Removing Product B (by entity) ---");
  await repo.remove(productB);
  console.log("Products after remove:", await repo.find());
}

main();

CRUD dalam Perkhidmatan NestJS

Dalam aplikasi NestJS sebenar, anda akan menggabungkan kaedah repositori ini dalam perkhidmatan. Perkhidmatan itu kemudiannya akan menyediakan kaedah aras lebih tinggi yang melaksanakan logik perniagaan tertentu dengan memanggil kaedah repositori yang mendasarinya.

Hal ini memastikan pengawal anda kekal kemas, dengan tumpuan hanya pada pengendalian permintaan HTTP dan penyerahan operasi data kepada lapisan perkhidmatan.

// products.service.ts (simplified NestJS service)
import { Injectable } from '@nestjs/common';
import { Repository } from 'typeorm';
import { InjectRepository } from '@nestjs/typeorm';
import { Product } from './product.entity'; // Your entity

@Injectable()
export class ProductsService {
  constructor(
    @InjectRepository(Product)
    private productsRepository: Repository<Product>,
  ) {}

  async create(productData: Partial<Product>): Promise<Product> {
    const newProduct = this.productsRepository.create(productData);
    return this.productsRepository.save(newProduct);
  }

  async findAll(): Promise<Product[]> {
    return this.productsRepository.find();
  }

  async findOne(id: number): Promise<Product | undefined> {
    return this.productsRepository.findOneBy({ id });
  }

  async update(id: number, productData: Partial<Product>): Promise<Product | undefined> {
    await this.productsRepository.update(id, productData);
    return this.findOne(id); 
  }

  async remove(id: number): Promise<void> {
    await this.productsRepository.delete(id);
  }
}

CRUD Kukuh: Amalan Terbaik

Membina operasi CRUD yang kukuh memerlukan lebih daripada sekadar memanggil kaedah repositori:

  • Pengesahan Data: Gunakan Objek Pemindahan Data (DTO) dan saluran pengesahan untuk memastikan data masuk adalah sah (dibincangkan dalam A2 L2).
  • Pengendalian Ralat: Kendalikan keadaan seperti 'entiti tidak ditemui' dengan baik dengan melontarkan pengecualian yang sesuai (contohnya, NotFoundException NestJS).
  • Transaksi: Untuk operasi kompleks yang melibatkan berbilang perubahan pangkalan data, gunakan transaksi (dibincangkan dalam C1 L2) bagi memastikan ketekalan data.

Kuiz Operasi CRUD

Kaedah repositori TypeORM manakah yang biasanya digunakan untuk mengemas kini medan tertentu sahaja bagi sesuatu entiti tanpa memuatkan keseluruhan entiti ke dalam memori terlebih dahulu?

Ulang Kaji: Menguasai CRUD

Syabas! Anda telah mempelajari perkara penting untuk melaksanakan operasi CRUD menggunakan repositori TypeORM.

  • Cipta: Gunakan .save() untuk menambah entiti baharu.
  • Baca: Gunakan .find(), .findOneBy() untuk mendapatkan entiti.
  • Kemas Kini: Ubah dan gunakan .save(), atau gunakan .update() untuk kemas kini separa.
  • Padam: Gunakan .delete() atau .remove() untuk membuang entiti.

Kemahiran ini penting untuk membina mana-mana API berasaskan data dengan NestJS dan TypeORM. Seterusnya, kita akan meneroka pengendalian ralat dan pencegat bagi menjadikan API anda lebih kukuh!

Percuma untuk bermula

Pelajari TypeScript dengan tutor kecerdasan buatan — percuma

Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.

Kursus
20
Pelajaran
76

Soalan Lazim

Adakah pelajaran “Operasi CRUD dengan TypeORM” percuma?

Ya — teks penuh “Operasi CRUD dengan TypeORM” boleh dibaca secara percuma di web ini. Untuk berlatih secara interaktif menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7, serta membuka kunci baki kursus API Bahagian Belakang Perusahaan NestJS, tingkat taraf kepada CoddyKit PRO. Kursus API Bahagian Belakang Perusahaan NestJS merangkumi sejumlah 3 pelajaran.

Apakah yang akan saya pelajari dalam “Operasi CRUD dengan TypeORM”?

Bangunkan fungsi Cipta, Baca, Kemas Kini dan Padam yang lengkap untuk entiti anda menggunakan repositori TypeORM. Anda berlatih API Bahagian Belakang Perusahaan NestJS menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.

Adakah saya memerlukan pengalaman untuk memulakan API Bahagian Belakang Perusahaan NestJS?

Tiada pengalaman terdahulu diperlukan. Pembelajaran API Bahagian Belakang Perusahaan NestJS di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 2 daripada 3.

Berapa lamakah pelajaran “Operasi CRUD dengan TypeORM” diambil?

Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.

Bolehkah saya menulis dan menjalankan kod dalam pelajaran API Bahagian Belakang Perusahaan NestJS ini?

Ya. Setiap pelajaran API Bahagian Belakang Perusahaan NestJS menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.

Semua pelajaran dalam kursus ini

  1. Laluan dan Pengendalian Permintaan
  2. Operasi CRUD dengan TypeORM
  3. Pengendalian Ralat dan Pencegat
← Kembali ke API Bahagian Belakang Perusahaan NestJS