20210604のMySQLに関する記事は3件です。

簡単にtypescript + express + mysql で簡易 webAPI サーバー作成

MySQL + express + TypeScript で作成する記事がなかったので,備忘録がてらに記事を作成します. 一旦,エラーハンドリングは考えません. promise-mysql を使用しましたが,mysql でも問題ないと思います. ソースコードはこちら. はてなブログにも投稿しています. 全体構成 ディレクトリ構成は以下 . ├── movies-ddl.sql ├── package.json ├── src │   ├── app.ts │   └── config │   └── index.ts ├── tsconfig.json └── yarn.lock 環境構築 node.js プロジェクトを初期化 yarn init -y pakage を install yarn add promise-mysql @types/mysql express yarn add -D typescript ts-node @types/express @types/node package.json に以下の記述を追加 { ... "main": "src/app.ts", "scripts": { "build": "tsc", "start": "nodemon" } ... } データベース movie-ddl.sql を作成 drop database if exists MOVIE; create database MOVIE CHARACTER SET UTF8; CONNECT MOVIE; drop user if exists 'app-user'@'%'; set global validate_password_policy=LOW; create user 'app-user'@'%' identified by 'PaAsW0rD'; grant all privileges on MOVIE.* TO 'app-user'@'%'; create table if not exists MOVIE ( ID serial primary key, NAME varchar(100) not null, CREATED_AT timestamp(3) default current_timestamp(3) not null, UPDATED_AT timestamp(3) default current_timestamp(3) not null ); INSERT INTO MOVIE(NAME) VALUES ('天気の子'); INSERT INTO MOVIE(NAME) VALUES ('サマーウォーズ'); INSERT INTO MOVIE(NAME) VALUES ('ジョゼと虎と魚たち'); MySQL で ddl を読み込む mysql -u root -p # パスワードを入力 root@localhost> source /PATH/TO/express_api/movies-ddl.sql .env ファイル .env ファイルを作成して,環境変数を読み込む 作成する.env ファイル # express PORT=4000 # DB DB_HOST="localhost" DB_PORT="3306" DB_USER="app-user" DB_PASSWORD="PaAsW0rD" DB_DATABASE="MOVIE" 読み込みコマンド export $(cat .env | grep -v ^# | xargs) 実装 config src/config/index.ts export default { /** * APIサーバーのPORT番号 */ port: parseInt(process.env.PORT, 10), /** * databaseの設定 */ db: { host: process.env.DB_HOST, port: parseInt(process.env.DB_PORT, 10), user: process.env.DB_USER, password: process.env.DB_PASSWORD, database: process.env.DB_DATABASE, multipleStatements: true, }, }; app src/app.ts import express from "express"; import * as mysql from "promise-mysql"; import config from "./config"; const app: express.Express = express(); app.use(express.json()); app.use(express.urlencoded({ extended: true })); app.listen(config.port, () => { console.log(`Start on port ${config.port}.`); }); const connection = async () => { return await mysql.createConnection(config.db); }; // movie一覧取得 app.get("/movie", (req: express.Request, res: express.Response) => { connection() .then((connection) => { const result = connection.query("SELECT * FROM MOVIE"); connection.end(); return result; }) .then(function (rows) { res.send(rows); }); }); // movie単一取得 app.get("/movie/:movieId", (req: express.Request, res: express.Response) => { const movieId = req.params.movieId; connection() .then((connection) => { const result = connection.query("SELECT * FROM MOVIE WHERE ID = ?", [ movieId, ]); connection.end(); return result; }) .then(function (rows) { res.send(rows); }); }); // movie追加処理 app.put("/movie", (req: express.Request, res: express.Response) => { const name = req.body.name; connection() .then((connection) => { const result = connection.query("INSERT INTO MOVIE (NAME) VALUES (?)", [ name, ]); connection.end(); return result; }) .then(function (rows) { res.send(rows); }); }); // movie更新処理 app.patch("/movie/:movieId", (req: express.Request, res: express.Response) => { const movieId = req.params.movieId; const name = req.body.name; connection() .then((connection) => { const result = connection.query( "UPDATE MOVIE SET NAME = ? WHERE ID = ?", [name, movieId] ); connection.end(); return result; }) .then(function (rows) { res.send(rows); }); }); // movie削除処理 app.delete("/movie/:movieId", (req: express.Request, res: express.Response) => { const movieId = req.params.movieId; connection() .then((connection) => { const result = connection.query("DELETE FROM MOVIE WHERE ID = ?", [ movieId, ]); connection.end(); return result; }) .then(function (rows) { res.send(rows); }); }); 動作確認 API サーバーを起動 yarn start CURD を確認 READ 全権取得 curl -H "Content-Type: application/json" localhost:4000/movie/ | jq [ { "ID": 1, "NAME": "天気の子", "CREATED_AT": "2021-06-03T23:39:19.024Z", "UPDATED_AT": "2021-06-03T23:39:19.024Z" }, { "ID": 2, "NAME": "サマーウォーズ", "CREATED_AT": "2021-06-03T23:39:19.026Z", "UPDATED_AT": "2021-06-03T23:39:19.026Z" }, { "ID": 3, "NAME": "ジョゼと虎と魚たち", "CREATED_AT": "2021-06-03T23:39:19.026Z", "UPDATED_AT": "2021-06-03T23:39:19.026Z" } ] 単一取得 curl -H "Content-Type: application/json" localhost:4000/movie/1 | jq [ { "ID": 1, "NAME": "天気の子", "CREATED_AT": "2021-06-03T23:39:19.024Z", "UPDATED_AT": "2021-06-03T23:39:19.024Z" } ] CREATE 作成 curl -X PUT -H "Content-Type: application/json" localhost:4000/movie -d ' {"name": "青の通り道"}' {"fieldCount":0,"affectedRows":1,"insertId":4,"serverStatus":2,"warningCount":0,"message":"","protocol41":true,"changedRows":0} 確認 curl -H "Content-Type: application/json" localhost:4000/movie/4 | jq [ { "ID": 4, "NAME": "青の通り道", "CREATED_AT": "2021-06-03T23:42:42.477Z", "UPDATED_AT": "2021-06-03T23:42:42.477Z" } ] UPDATE 更新 curl -X PATCH -H "Content-Type: application/json" localhost:4000/movie/4 -d '{"name": "新聞記者"}' { "fieldCount": 0, "affectedRows": 1, "insertId": 0, "serverStatus": 2, "warningCount": 0, "message": "(Rows matched: 1 Changed: 1 Warnings: 0", "protocol41": true, "changedRows": 1 } 確認 curl -H "Content-Type: application/json" localhost:4000/movie/4 | jq [ { "ID": 4, "NAME": "新聞記者", "CREATED_AT": "2021-06-03T23:42:42.477Z", "UPDATED_AT": "2021-06-03T23:42:42.477Z" } ] DELETE 削除 curl -X DELETE -H "Content-Type: application/json" localhost:4000/movie/4 | jq { "fieldCount": 0, "affectedRows": 1, "insertId": 0, "serverStatus": 2, "warningCount": 0, "message": "", "protocol41": true, "changedRows": 0 } 確認 curl -H "Content-Type: application/json" localhost:4000/movie/ | jq [ { "ID": 1, "NAME": "天気の子", "CREATED_AT": "2021-06-03T23:39:19.024Z", "UPDATED_AT": "2021-06-03T23:39:19.024Z" }, { "ID": 2, "NAME": "サマーウォーズ", "CREATED_AT": "2021-06-03T23:39:19.026Z", "UPDATED_AT": "2021-06-03T23:39:19.026Z" }, { "ID": 3, "NAME": "ジョゼと虎と魚たち", "CREATED_AT": "2021-06-03T23:39:19.026Z", "UPDATED_AT": "2021-06-03T23:39:19.026Z" } ] まとめ MySQL + express + TypeScript で WebAPI サーバーを作成しました. 簡易的なものなので,Web アプリ作成時やポートフォリオにはアーキテクチャを考えて作り直した方がいいです. SQL を直接書きたくない or SQL を書かなくても O/R マッパーで十分,みたな状況だと TypeORM を使うと,アーキテクチャも作成してくれるので楽だということに気がつきました.
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

WSL2でDockerを使ってRails 6 + MySQL 8の環境構築をしよう

下準備 WSLをインストールする WSLのバージョンを2にアップグレードする Microsoft StoreからDebian系OSをダウンロードし、インストールする Docker Desktopのインストーラをダウンロードし、それを使ってDocker Desktopをインストールする 下準備が終わったら 下準備が終わったらディストリビューションを開きます 1. myappディレクトリを作成して、そこに移動する cd ~ mkdir myapp cd myapp 2. エディタとDockerをインストールする 好みのエディタを使いましょう sudo apt update sudo apt install -y nano docker-compose 3. Dockerfileを作成する まず、Dockerfileを開きます sudo nano Dockerfile 以下のコードをコピペして保存し、終了します FROM ruby:3.0.0 RUN apt-get update && apt-get install -y curl apt-transport-https wget && \ curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add - && \ echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list && \ apt-get update && apt-get install -y yarn RUN curl -sL https://deb.nodesource.com/setup_12.x | bash - && \ apt-get install -y nodejs RUN mkdir /myapp WORKDIR /myapp COPY Gemfile /myapp/Gemfile COPY Gemfile.lock /myapp/Gemfile.lock RUN bundle install COPY . /myapp # Add a script to be executed every time the container starts. COPY entrypoint.sh /usr/bin/ RUN chmod +x /usr/bin/entrypoint.sh ENTRYPOINT ["entrypoint.sh"] 4. GemfileとGemfile.lockを作成する まず、Gemfileを開きます sudo nano Gemfile 以下のコードをコピペして保存し、終了します source 'https://rubygems.org' gem 'rails' gem 'mysql2' 次に、空のGemfile.lockを作成します touch Gemfile.lock 5. entrypoint.shを作成する プロセスを管理するためのシェルスクリプトを作成します #!/bin/bash set -e # Remove a potentially pre-existing server.pid for Rails. rm -f /myapp/tmp/pids/server.pid # Then exec the container's main process (what's set as CMD in the Dockerfile). exec "$@" 6. docker-compose.ymlを作成する まず、docker-compose.ymlを開きます sudo nano docker-compose.yml 以下のコードをコピペして保存し、終了します version: "3.7" services: web: build: . container_name: web volumes: - .:/myapp command: rails s -b 0.0.0.0 ports: - "3000:3000" networks: - myapp depends_on: - mysql mysql: image: mysql container_name: mysql command: --default-authentication-plugin=mysql_native_password environment: MYSQL_ROOT_PASSWORD: password ports: - "3306:3306" volumes: - mysql-data:/var/lib/mysql - ./mysql-files:/var/lib/mysql-files networks: - myapp networks: myapp: external: true volumes: mysql-data: 7. mysql-filesディレクトリを作成する mkdir mysql-files 8. Dockerのネットワークを作成する sudo docker network create myapp 9. Railsのプロジェクトを作成する sudo docker-compose run web rails new . -d mysql --skip-bundle --force --no-deps 10. コンテナを作成する sudo docker-compose build 11. DBに接続する際の設定を変更する まず、config/database.ymlを開きます sudo nano config/database.yml 以下のコードで上書きして保存し、終了します default: &default adapter: mysql2 encoding: utf8 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> host: mysql username: root passowrd: password development: <<: *default database: myapp_development test: <<: *default database: myapp_test production: <<: *default database: myapp_production username: myapp password: <%= ENV['MYAPP_DATABASE_PASSWORD'] %> 12. Webpackerをインストールする sudo docker-compose run web rails webpacker:install 13. DBを作成する sudo docker-compose run web rails db:create 14. RailsとMySQLを起動する sudo docker-compose up Railsが起動した旨のメッセージが表示されたら、ブラウザでlocalhost:3000にアクセスします ここまでの手順が上手くいっていれば、Yay! You're on Rails!という言葉が表示されます その言葉が表示されれば、Dockerを使ったRailsの環境構築は終了です、お疲れ様でした!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

SQLのIN句で指定できる値の上限について

SQLでIN句を使う時に、指定できる値は1000個が限界だと思っていて この前業務で 「このSQLのIN句には1200個くらい値が入る可能性があるのに普通に動いてしまってる、、これはバグだ!!」 と思い無駄に時間をくってしまったのでメモ 実際にはDBによって違うようです。 DB 上限 oracle 1000 postgreSQL 2の64乗、一つの単語が2kバイトまで mySQL 上限なし、ただしクエリの上限サイズまで mySQLのクエリの上限サイズは調べたいDBに接続して以下のコマンドを打つことで調べられます。 mysql> show variables like 'max_allowed_packet' +--------------------+----------+ | Variable_name | Value | +--------------------+----------+ | max_allowed_packet | 33554432 | +--------------------+----------+ DBサーバーに接続できるのであれば、設定ファイル(/etc/my.cnfのmax_allowed_packetの値)を変えてMySQLを再起動することで、制限値を変えることが可能です。 また、その接続の時だけ変えたい場合であればsetで変更ができます。 mysql> set max_allowed_packet=12345678; Query OK, 0 rows affected (0.00 sec) もし間違えていたらご教授いただけると幸いです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む