Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Jak używać MySQL z Deno i Oak?

Niedawno pisałem o tym, jak zrobić API Todo w Deno + Oak (bez użycia bazy danych) . Repozytorium można znaleźć w rozdziale_1:dąb na GitHubie.

W tym samouczku wracamy do miejsca, w którym poprzednie zostały przerwane, a ja omówię, jak zintegrować MySQL z projektem Deno i Oak.

Jeśli w dowolnym momencie zechcesz zobaczyć cały kod źródłowy użyty w tym samouczku, jest on dostępny pod adresem chapter_2:mysql . Jeśli Ci się spodoba, możesz przyznać mu gwiazdkę na GitHub.

Zakładam, że ukończyłeś już ostatni wspomniany wyżej samouczek. Jeśli nie, sprawdź to tutaj i wróć, gdy skończysz.

Zanim zaczniemy, upewnij się, że masz zainstalowanego i uruchomionego klienta MySQL:

  • Serwer społeczności MySQL [Pobierz tutaj]
  • MySQL Workbench [Pobierz tutaj]

Napisałem mały przewodnik dla użytkowników Mac OS na temat konfigurowania MySQL, ponieważ również miałem z nim problemy. Sprawdź to tutaj.

Jeśli korzystasz z komputera z systemem Windows, możesz użyć tych samych narzędzi lub możesz również użyć XAMPP, aby uruchomić instancję MySQL na swoim pulpicie nawigacyjnym.

Po uruchomieniu instancji MySQL możemy rozpocząć nasz samouczek.

Zacznijmy

Zakładając, że pochodzisz z tego artykułu, Todo API w Deno + Oak (bez użycia bazy danych) , zrobimy co następuje:

  • Utwórz połączenie z bazą danych MySQL
  • Napisz mały skrypt, który resetuje bazę danych za każdym razem, gdy uruchamiamy nasz serwer Deno
  • Wykonywanie operacji CRUD na stole
  • Dodaj funkcjonalność CRUD do naszych kontrolerów API

Ostatnia rzecz – tutaj jest cała różnica w zatwierdzaniu, która została dokonana w Rozdziale 1, aby dodać MySQL do projektu (kod źródłowy, który pokazuje nowe dodatki wykonane z rozdziału 1).

W folderze głównym twojego projektu – mój nazywa się chapter_2:mysql , chociaż Twój może być nazwany, jak chcesz – utwórz folder o nazwie db . Wewnątrz tego folderu utwórz plik o nazwie config.ts i dodaj do niego następującą treść:

export const DATABASE: string = "deno";
export const TABLE = {
  TODO: "todo",
};

Nic nadzwyczajnego, wystarczy zdefiniować nazwę naszej bazy danych wraz z obiektem dla tabel, a następnie go wyeksportować. Nasz projekt będzie miał jedną bazę danych o nazwie „deno”, a wewnątrz tej bazy danych będziemy mieć tylko jedną tabelę o nazwie „todo”.

Następnie w bazie folderu, utwórz inny plik o nazwie client.ts i dodaj następującą treść:

import { Client } from "https://deno.land/x/mysql/mod.ts";
// config
import { DATABASE, TABLE } from "./config.ts";

const client = await new Client();

client.connect({
  hostname: "127.0.0.1",
  username: "root",
  password: "",
  db: "",
});

export default client;

Dzieje się tutaj kilka rzeczy.

Importujemy Client z mysql biblioteka. Client pomoże nam połączyć się z naszą bazą danych i wykonać operacje w bazie danych.

client.connect({
  hostname: "127.0.0.1",
  username: "root",
  password: "",
  db: "",
});

Client udostępnia metodę o nazwie connect który przyjmuje obiekt, w którym możemy podać hostname , username , password i db . Dzięki tym informacjom może nawiązać połączenie z naszą instancją MySQL.

Upewnij się, że Twoja username nie ma password , ponieważ będzie to powodować konflikt z połączeniem z biblioteką MySQL firmy Deno. Jeśli nie wiesz, jak to zrobić, przeczytaj ten samouczek, który napisałem.

Opuściłem database pole puste tutaj, ponieważ chcę je później wybrać ręcznie w moim skrypcie.

Dodajmy skrypt, który zainicjuje bazę danych o nazwie „deno”, wybierz ją i wewnątrz tej bazy utwórzmy tabelę o nazwie „todo”.

Wewnątrz db/client.ts plik zróbmy kilka nowych dodatków:

import { Client } from "https://deno.land/x/mysql/mod.ts";
// config
import { DATABASE, TABLE } from "./config.ts";

const client = await new Client();

client.connect({
  hostname: "127.0.0.1",
  username: "root",
  password: "",
  db: "",
});

const run = async () => {
  // create database (if not created before)
  await client.execute(`CREATE DATABASE IF NOT EXISTS ${DATABASE}`);
  // select db
  await client.execute(`USE ${DATABASE}`);

  // delete table if it exists before
  await client.execute(`DROP TABLE IF EXISTS ${TABLE.TODO}`);
  // create table
  await client.execute(`
    CREATE TABLE ${TABLE.TODO} (
        id int(11) NOT NULL AUTO_INCREMENT,
        todo varchar(100) NOT NULL,
        isCompleted boolean NOT NULL default false,
        PRIMARY KEY (id)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  `);
};

run();

export default client;

Tutaj importujemy DATABASE i TABLE z naszego pliku konfiguracyjnego, a następnie używając tych wartości w nowej funkcji o nazwie run() .

Podzielmy to run() funkcjonować. Dodałem komentarze w pliku, aby pomóc Ci zrozumieć przepływ pracy:

const run = async () => {
  // create database (if not created before)
  await client.execute(`CREATE DATABASE IF NOT EXISTS ${DATABASE}`);
  // select db
  await client.execute(`USE ${DATABASE}`);

  // delete table if it exists before
  await client.execute(`DROP TABLE IF EXISTS ${TABLE.TODO}`);
  // create table
  await client.execute(`
    CREATE TABLE ${TABLE.TODO} (
        id int(11) NOT NULL AUTO_INCREMENT,
        todo varchar(100) NOT NULL,
        isCompleted boolean NOT NULL default false,
        PRIMARY KEY (id)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
  `);
};

run();
  • Utwórz bazę danych o nazwie deno . Jeśli już istnieje, nie rób nic.
  • Następnie wybierz bazę danych do użycia, która nazywa się deno
  • Usuń tabelę wewnątrz deno o nazwie todo jeśli już istnieje.
  • Następnie utwórz nową tabelę w deno db, nazwij to todo i zdefiniuj jego strukturę:będzie miał unikalny automatyczny przyrost id która będzie liczbą całkowitą, innym polem o nazwie todo który będzie ciągiem, a na końcu polem o nazwie isCompleted co jest wartością logiczną. Definiuję również id jako mój klucz podstawowy.

Powodem, dla którego napisałem ten skrypt, było to, że nie chcę mieć dodatkowych informacji w instancji MySQL. Za każdym razem, gdy skrypt jest uruchamiany, po prostu ponownie inicjuje wszystko.

Nie musisz dodawać tego skryptu. Ale jeśli tego nie zrobisz, będziesz musiał ręcznie utworzyć bazę danych i tabelę.

Zapoznaj się również z dokumentacją biblioteki Deno MySQL dotyczącą tworzenia baz danych i tworzenia tabel.

Wracając do naszego programu, właśnie osiągnęliśmy dwie rzeczy z czterech wymienionych na początku artykułu:

  • Utwórz połączenie z bazą danych MySQL
  • Napisz mały skrypt, który resetuje bazę danych za każdym razem, gdy uruchamiamy nasz serwer Deno

To już 50% samouczka. Niestety w tej chwili niewiele się dzieje. Dodajmy szybko kilka funkcji, aby zobaczyć, jak działa.

Wykonywanie operacji CRUD na tabeli i dodawanie funkcjonalności do naszych kontrolerów API

Najpierw musimy zaktualizować nasz interfejs Todo. Przejdź do interfaces/Todo.ts plik i dodaj następujące:

export default interface Todo {
  id?: number,
  todo?: string,
  isCompleted?: boolean,
}

Co to jest ? robi to sprawia, że ​​klucz w obiekcie jest opcjonalny. Zrobiłem to, ponieważ później użyję różnych funkcji do przekazywania obiektów tylko z id , todo , isCompleted lub wszystkie na raz.

Jeśli chcesz dowiedzieć się więcej o opcjonalnych właściwościach w TypeScript, przejdź do ich dokumentacji tutaj.

Następnie utwórz nowy folder o nazwie modele i wewnątrz tego folderu utwórz plik o nazwie todo.ts . Dodaj następującą zawartość do pliku:

import client from "../db/client.ts";
// config
import { TABLE } from "../db/config.ts";
// Interface
import Todo from "../interfaces/Todo.ts";

export default {
  /**
   * Takes in the id params & checks if the todo item exists
   * in the database
   * @param id
   * @returns boolean to tell if an entry of todo exits in table
   */
  doesExistById: async ({ id }: Todo) => {},
  /**
   * Will return all the entries in the todo column
   * @returns array of todos
   */
  getAll: async () => {},
  /**
   * Takes in the id params & returns the todo item found
   * against it.
   * @param id
   * @returns object of todo item
   */
  getById: async ({ id }: Todo) => {},
  /**
   * Adds a new todo item to todo table
   * @param todo
   * @param isCompleted
   */
  add: async (
    { todo, isCompleted }: Todo,
  ) => {},
  /**
   * Updates the content of a single todo item
   * @param id
   * @param todo
   * @param isCompleted
   * @returns integer (count of effect rows)
   */
  updateById: async ({ id, todo, isCompleted }: Todo) => {},
  /**
   * Deletes a todo by ID
   * @param id
   * @returns integer (count of effect rows)
   */
  deleteById: async ({ id }: Todo) => {},
};

W tej chwili funkcje są puste, ale to jest w porządku. Zapełnimy je jeden po drugim.

Następnie przejdź do controllers/todo.ts plik i upewnij się, że dodałeś następujące informacje:

// interfaces
import Todo from "../interfaces/Todo.ts";
// models
import TodoModel from "../models/todo.ts";

export default {
  /**
   * @description Get all todos
   * @route GET /todos
   */
  getAllTodos: async ({ response }: { response: any }) => {},
  /**
   * @description Add a new todo
   * @route POST /todos
   */
  createTodo: async (
    { request, response }: { request: any; response: any },
  ) => {},
  /**
   * @description Get todo by id
   * @route GET todos/:id
   */
  getTodoById: async (
    { params, response }: { params: { id: string }; response: any },
  ) => {},
  /**
   * @description Update todo by id
   * @route PUT todos/:id
   */
  updateTodoById: async (
    { params, request, response }: {
      params: { id: string };
      request: any;
      response: any;
    },
  ) => {},
  /**
   * @description Delete todo by id
   * @route DELETE todos/:id
   */
  deleteTodoById: async (
    { params, response }: { params: { id: string }; response: any },
  ) => {},
};

Tutaj też mamy puste funkcje. Zacznijmy je wypełniać.

[Pobierz] wszystkie API todos

Wewnątrz models/todo.ts , dodaj definicję funkcji o nazwie getAll :

import client from "../db/client.ts";
// config
import { TABLE } from "../db/config.ts";
// Interface
import Todo from "../interfaces/Todo.ts";

export default {
   /**
   * Will return all the entries in the todo column
   * @returns array of todos
   */
  getAll: async () => {
    return await client.query(`SELECT * FROM ${TABLE.TODO}`);
  },
}

Client udostępnia również inną metodę poza connect (użyliśmy metody "connect" w db/client.ts plik) i to jest query . client.query Metoda pozwala nam uruchamiać zapytania MySQL bezpośrednio z naszego kodu Deno, tak jak jest.

Następnie przejdź do controllers/todo.ts dodaj definicję dla getAllTodos :

// interfaces
import Todo from "../interfaces/Todo.ts";
// models
import TodoModel from "../models/todo.ts";

export default {
  /**
   * @description Get all todos
   * @route GET /todos
   */
  getAllTodos: async ({ response }: { response: any }) => {
    try {
      const data = await TodoModel.getAll();
      response.status = 200;
      response.body = {
        success: true,
        data,
      };
    } catch (error) {
      response.status = 400;
      response.body = {
        success: false,
        message: `Error: ${error}`,
      };
    }
  },
}

Wszystko, co robimy, to importowanie TodoModel i używając jego metody o nazwie getAll , który właśnie zdefiniowaliśmy. Ponieważ powraca jako obietnica, otoczyliśmy go async/await.

Metoda TodoModel.getAll() zwróci nam tablicę, którą po prostu zwracamy do response.body ze status ustaw na 200 .

Jeśli obietnica się nie powiedzie lub wystąpi inny błąd, po prostu przechodzimy do naszego bloku catch i zwracamy status 400 z success ustawiony na fałsz. Ustawiamy również message do tego, co otrzymujemy z bloku catch.

To wszystko, skończyliśmy. Teraz odpalmy nasz terminal.

Upewnij się, że Twoja instancja MySQL jest uruchomiona. W swoim terminalu wpisz:

$ deno run --allow-net server.ts 

Twój terminal powinien wyglądać mniej więcej tak:

Moja konsola mówi mi tutaj dwie rzeczy.

  1. Że mój serwer Deno API działa na porcie 8080
  2. Że moja instancja MySQL działa na 127.0.0.1 , czyli localhost

Przetestujmy nasze API. Używam tutaj Postmana, ale możesz użyć swojego ulubionego klienta API.

W tej chwili zwraca tylko puste dane. Ale kiedy dodamy dane do naszego todo tabeli, zwróci te zadania tutaj.

Niesamowite. Jeden interfejs API nie działa, a jeszcze cztery.

[Opublikuj] dodaj API zadań

W models/todo.ts pliku, dodaj następującą definicję dla add() funkcja:

export default {
   /**
   * Adds a new todo item to todo table
   * @param todo
   * @param isCompleted
   */
  add: async (
    { todo, isCompleted }: Todo,
  ) => {
    return await client.query(
      `INSERT INTO ${TABLE.TODO}(todo, isCompleted) values(?, ?)`,
      [
        todo,
        isCompleted,
      ],
    );
  },
}

Funkcja add przyjmuje obiekt jako argument, który ma dwa elementy:todo i isCompleted .

Więc add: async ({ todo, isCompleted }: Todo) => {} można również zapisać jako ({todo, isCompleted}: {todo:string, isCompleted:boolean}) . Ale ponieważ mamy już interfejs zdefiniowany w naszych interfaces/Todo.ts plik, który jest

export default interface Todo {
  id?: number,
  todo?: string,
  isCompleted?: boolean,
}

możemy po prostu napisać to jako add: async ({ todo, isCompleted }: Todo) => {} . To informuje TypeScript, że ta funkcja ma dwa argumenty, todo , który jest ciągiem i isCompleted , który jest wartością logiczną.

Jeśli chcesz przeczytać więcej o interfejsach, TypeScript ma doskonały dokument na ten temat, który możesz znaleźć tutaj.

Wewnątrz naszej funkcji mamy:

return await client.query(
  `INSERT INTO ${TABLE.TODO}(todo, isCompleted) values(?, ?)`,
  [
    todo,
    isCompleted,
  ],
);

To zapytanie można podzielić na dwie części:

  • INSERT INTO ${TABLE.TODO}(todo, isCompleted) values(?, ?) . Dwa znaki zapytania tutaj oznaczają użycie zmiennych w zapytaniu.
  • Druga część, [todo, isCompleted] , to zmienne, które znajdą się w pierwszej części zapytania i być zastąpione przez (?, ?)
  • Table.Todo to tylko ciąg znaków pochodzący z pliku db/config.ts gdzie Table.Todo wartość to „todo "

Dalej w naszych controllers/todo.ts pliku, przejdź do definicji createTodo() funkcja:

export default {
   /**
   * @description Add a new todo
   * @route POST /todos
   */
  createTodo: async (
    { request, response }: { request: any; response: any },
  ) => {
    const body = await request.body();
    if (!request.hasBody) {
      response.status = 400;
      response.body = {
        success: false,
        message: "No data provided",
      };
      return;
    }

    try {
      await TodoModel.add(
        { todo: body.value.todo, isCompleted: false },
      );
      response.body = {
        success: true,
        message: "The record was added successfully",
      };
    } catch (error) {
      response.status = 400;
      response.body = {
        success: false,
        message: `Error: ${error}`,
      };
    }
  },
}

Podzielmy to na dwie części:

Część 1

const body = await request.body();
if (!request.hasBody) {
  response.status = 400;
  response.body = {
    success: false,
    message: "No data provided",
  };
  return;
}

Wszystko, co tutaj robimy, to sprawdzanie, czy użytkownik wysyła dane w treści. Jeśli nie, zwracamy status 400 aw treści zwróć success: false i message: <erromessage-string> .

Część 2

try {
  await TodoModel.add(
    { todo: body.value.todo, isCompleted: false },
  );
  response.body = {
    success: true,
    message: "The record was added successfully",
  };
} catch (error) {
  response.status = 400;
  response.body = {
    success: false,
    message: `Error: ${error}`,
  };
}

Jeśli nie ma błędu, TodoModel.add() funkcja jest wywoływana i po prostu zwraca stan 200 oraz wiadomość z potwierdzeniem dla użytkownika.

W przeciwnym razie po prostu wygeneruje podobny błąd, który zrobiliśmy w poprzednim API.

Teraz skończyliśmy. Uruchom terminal i upewnij się, że Twoja instancja MySQL działa. W swoim terminalu wpisz:

$ deno run --allow-net server.ts 

Przejdź do Postman i uruchom trasę API dla tego kontrolera:

To świetnie, teraz mamy dwa działające API. Jeszcze tylko trzy.

[GET] rzeczy do zrobienia według identyfikatora API

W swoim models/todo.ts plik, dodaj definicję dla tych dwóch funkcji, doesExistById() i getById() :

export default {
   /**
   * Takes in the id params & checks if the todo item exists
   * in the database
   * @param id
   * @returns boolean to tell if an entry of todo exits in table
   */
  doesExistById: async ({ id }: Todo) => {
    const [result] = await client.query(
      `SELECT COUNT(*) count FROM ${TABLE.TODO} WHERE id = ? LIMIT 1`,
      [id],
    );
    return result.count > 0;
  },
  /**
   * Takes in the id params & returns the todo item found
   * against it.
   * @param id
   * @returns object of todo item
   */
  getById: async ({ id }: Todo) => {
    return await client.query(
      `SELECT * FROM ${TABLE.TODO} WHERE id = ?`,
      [id],
    );
  },
}

Porozmawiajmy o każdej funkcji jeden po drugim:

  • doesExistById przyjmuje id i zwraca boolean wskazując, czy konkretne zadanie istnieje w bazie danych, czy nie.

Podzielmy tę funkcję:

const [result] = await client.query(
  `SELECT COUNT(*) count FROM ${TABLE.TODO} WHERE id = ? LIMIT 1`,
  [id],
);
return result.count > 0;

Po prostu porównujemy liczbę w tabeli z konkretnym identyfikatorem rzeczy do zrobienia. Jeśli liczba jest większa od zera, zwracamy true . W przeciwnym razie zwracamy false .

  • getById zwraca element do zrobienia z określonym identyfikatorem:
return await client.query(
  `SELECT * FROM ${TABLE.TODO} WHERE id = ?`,
  [id],
);

Po prostu uruchamiamy tutaj zapytanie MySQL, aby uzyskać zadanie według identyfikatora i zwrócić wynik bez zmian.

Następnie przejdź do controllers/todo.ts i dodaj definicję dla getTodoById metoda kontrolera:

export default {
   /**
   * @description Get todo by id
   * @route GET todos/:id
   */
  getTodoById: async (
    { params, response }: { params: { id: string }; response: any },
  ) => {
    try {
      const isAvailable = await TodoModel.doesExistById(
        { id: Number(params.id) },
      );

      if (!isAvailable) {
        response.status = 404;
        response.body = {
          success: false,
          message: "No todo found",
        };
        return;
      }

      const todo = await TodoModel.getById({ id: Number(params.id) });
      response.status = 200;
      response.body = {
        success: true,
        data: todo,
      };
    } catch (error) {
      response.status = 400;
      response.body = {
        success: false,
        message: `Error: ${error}`,
      };
    }
  },
}

Podzielmy to na dwie mniejsze części:

const isAvailable = await TodoModel.doesExistById(
  { id: Number(params.id) },
);

if (!isAvailable) {
  response.status = 404;
  response.body = {
    success: false,
    message: "No todo found",
  };
  return;
}

Najpierw sprawdzamy, czy zadanie istnieje w bazie danych z identyfikatorem za pomocą tej metody:

const isAvailable = await TodoModel.doesExistById(
  { id: Number(params.id) },
);

Tutaj musimy przekonwertować params.id w Number ponieważ nasz interfejs todo akceptuje tylko id jako liczba. Następnie po prostu przekazujemy params.id do doesExistById metoda. Ta metoda zostanie zwrócona jako wartość logiczna.

Następnie po prostu sprawdzamy, czy zadanie nie jest dostępne i zwracamy 404 metoda z naszą standardową odpowiedzią, jak w przypadku poprzednich punktów końcowych:

if (!isAvailable) {
  response.status = 404;
  response.body = {
    success: false,
    message: "No todo found",
  };
  return;
}

Następnie mamy:

try {
const todo: Todo = await TodoModel.getById({ id: Number(params.id) });
response.status = 200;
response.body = {
  success: true,
  data: todo,
};
} catch (error) {
response.status = 400;
response.body = {
  success: false,
  message: `Error: ${error}`,
};

Jest to podobne do tego, co robiliśmy w naszych poprzednich interfejsach API. Tutaj po prostu pobieramy dane z bazy danych, ustawiając zmienną todo , a następnie zwracając odpowiedź. Jeśli wystąpi błąd, po prostu zwracamy użytkownikowi standardowy komunikat o błędzie w bloku catch.

Teraz uruchom terminal i upewnij się, że Twoja instancja MySQL jest uruchomiona. W swoim terminalu wpisz:

$ deno run --allow-net server.ts 

Przejdź do Postman i uruchom trasę API dla tego kontrolera.

Pamiętaj, że za każdym razem, gdy restartujemy nasz serwer, resetujemy db. Jeśli nie chcesz tego zachowania, możesz po prostu zakomentować run funkcja w pliku db/client.ts .

zwróci zadanie dla tego identyfikatora, jeśli zostanie znaleziony" width="2000" height="1165" loading=" leniwy">

Do tej pory wykonaliśmy API dla:

  • Pobierz wszystkie rzeczy do zrobienia
  • Utwórz nowe zadanie
  • Zdobądź zadanie według identyfikatora

A oto pozostałe API:

  • Zaktualizuj zadanie według identyfikatora
  • Usuń zadanie według identyfikatora

[PUT] zaktualizuj todo przez id API

Najpierw stwórzmy model dla tego API. Wejdź do naszych models/todo.ts i dodaj definicję dla updateById funkcja:

**
 * Updates the content of a single todo item
 * @param id
 * @param todo
 * @param isCompleted
 * @returns integer (count of effect rows)
 */
updateById: async ({ id, todo, isCompleted }: Todo) => {
  const result = await client.query(
    `UPDATE ${TABLE.TODO} SET todo=?, isCompleted=? WHERE id=?`,
    [
      todo,
      isCompleted,
      id,
    ],
  );
  // return count of rows updated
  return result.affectedRows;
},

updateById przyjmuje 3 parametry:id , todo i isCompleted .

Po prostu uruchamiamy zapytanie MySQL w tej funkcji:

onst result = await client.query(
  `UPDATE ${TABLE.TODO} SET todo=?, isCompleted=? WHERE id=?`,
  [
    todo,
    isCompleted,
    id,
  ],
);

To aktualizuje todo pojedynczego elementu do zrobienia i isCompleted przez konkretny id .

Następnie zwracamy liczbę wierszy zaktualizowanych przez to zapytanie, wykonując:

  // return count of rows updated
  return result.affectedRows;

Liczba będzie wynosić 0 lub 1, ale nigdy więcej niż 1. Dzieje się tak, ponieważ w naszej bazie danych mamy unikalne identyfikatory – nie może istnieć wiele zadań z tym samym identyfikatorem.

Następnie przejdź do naszych controllers/todo.ts i dodaj definicję dla updateTodoById funkcja:

updateTodoById: async (
  { params, request, response }: {
    params: { id: string };
    request: any;
    response: any;
  },
) => {
  try {
    const isAvailable = await TodoModel.doesExistById(
      { id: Number(params.id) },
    );
    if (!isAvailable) {
      response.status = 404;
      response.body = {
        success: false,
        message: "No todo found",
      };
      return;
    }

    // if todo found then update todo
    const body = await request.body();
    const updatedRows = await TodoModel.updateById({
      id: Number(params.id),
      ...body.value,
    });
    response.status = 200;
    response.body = {
      success: true,
      message: `Successfully updated ${updatedRows} row(s)`,
    };
  } catch (error) {
    response.status = 400;
    response.body = {
      success: false,
      message: `Error: ${error}`,
    };
  }
},

To prawie to samo, co w przypadku naszych poprzednich interfejsów API, które napisaliśmy. Nowością jest to:

// if todo found then update todo
const body = await request.body();
const updatedRows = await TodoModel.updateById({
  id: Number(params.id),
  ...body.value,
});

Po prostu pobieramy treść, którą użytkownik wysyła nam w JSON i przekazujemy ją do naszego TodoModel.updateById funkcja.

Musimy przekonwertować id do liczby zgodnej z naszym interfejsem Todo.

Zapytanie jest wykonywane i zwraca liczbę zaktualizowanych wierszy. Stamtąd po prostu zwracamy to w naszej odpowiedzi. Jeśli wystąpi błąd, przechodzi do bloku catch, w którym zwracamy naszą standardową wiadomość odpowiedzi.

Uruchommy to i zobaczmy, czy to działa. Upewnij się, że Twoja instancja MySQL jest uruchomiona i uruchom następujące polecenie z terminala:

$ deno run --allow-net server.ts 

Przejdź do Postman i uruchom trasę API dla tego kontrolera:

[DELETE] todo przez id API

W swoim models/todo.ts plik utwórz funkcję o nazwie deleteById :

/**
 * Deletes a todo by ID
 * @param id
 * @returns integer (count of effect rows)
 */
deleteById: async ({ id }: Todo) => {
  const result = await client.query(
    `DELETE FROM ${TABLE.TODO} WHERE id = ?`,
    [id],
  );
  // return count of rows updated
  return result.affectedRows;
},

Tutaj po prostu przekazujemy id jako parametr, a następnie użyj zapytania delete MySQL. Następnie zwracamy zaktualizowaną liczbę wierszy. Zaktualizowana liczba będzie wynosić 0 lub 1, ponieważ identyfikator każdego zadania jest unikalny.

Następnie przejdź do swoich controllers/todo.ts plik i zdefiniuj deleteByTodoId metoda:

/**
 * @description Delete todo by id
 * @route DELETE todos/:id
 */
deleteTodoById: async (
  { params, response }: { params: { id: string }; response: any },
) => {
  try {
    const updatedRows = await TodoModel.deleteById({
      id: Number(params.id),
    });
    response.status = 200;
    response.body = {
      success: true,
      message: `Successfully updated ${updatedRows} row(s)`,
    };
  } catch (error) {
    response.status = 400;
    response.body = {
      success: false,
      message: `Error: ${error}`,
    };
  }
},

To całkiem proste. Przekazujemy params.id do naszego TodoModel.deleteById metody i zwróć liczbę wierszy zaktualizowanych za pomocą tego zapytania.

Jeśli coś pójdzie nie tak, w bloku catch zgłaszany jest błąd, który zwraca naszą standardową odpowiedź na błąd.

Sprawdźmy to.

Upewnij się, że Twoja instancja MySQL jest uruchomiona. W swoim terminalu wpisz:

$ deno run --allow-net server.ts 

Przejdź do Postman i uruchom trasę API dla tego kontrolera:

Z tym skończyliśmy z naszym samouczkiem Deno + Oak + MySQL.

Cały kod źródłowy jest dostępny tutaj:https://github.com/adeelibr/deno-playground. Jeśli znajdziesz problem, po prostu daj mi znać. Lub złóż żądanie ściągnięcia, a przyznam ci kredyt w repozytorium.

Jeśli uznałeś ten samouczek za pomocny, udostępnij go. I jak zawsze jestem dostępny na Twitterze pod @adeelibr. Bardzo chciałbym poznać Twoje przemyślenia na ten temat.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. TABELA UPUSZCZANIA MySQL

  2. Zainstaluj MySQL na Ubuntu bez pytania o hasło

  3. Jak obliczyć procent kolumny w MySQL?

  4. Zainstaluj Innotop, aby monitorować wydajność serwera MySQL

  5. Strona internetowa z najlepszymi praktykami w wielu językach