8
5

More than 3 years have passed since last update.

【Express】ExpressにSequelizeを導入しORMでデーターベースを操作する。(SQLite3)

Last updated at Posted at 2020-11-26

sqlite3のインストール

npm install sqlite3

データベースアクセスの処理を作る

const sqlite3 = require('sqlite3');

const db = new sqlite3.Database('データ保存ファイル');
//Databaseオブジェクトを作成する。sqlite3.Databaseというオブジェクトに用意されている。

sequelize, sequlize-cliのインストール、 初期化

ターミナル.
npm install sequelize
npm install sequelize-cli
npx sequelize-cli init  //初期化

 
- config
- migrations
- models
- seeder

が作成される。

config.json

// SQLite3設定
{
  "development": {
    "database": "db-development",    //データベース名
    "dialect": "sqlite",
    "storage": "db-dev.sqlite3"      //データーベースファイル
  },
  "test": {
    "database": "db-test",
    "dialect": "sqlite",
    "storage": "db-test.sqlite3"
  },
  "production": {
    "database": "db-product",
    "dialect": "sqlite",
    "storage": "db.sqlite3"
  }
}

参考:mysqlの場合

config.json
{
    "username": ユーザーネーム,
    "password": パスワード,
    "database": データベー名
    "host": ホスト名,
    "dialect": "mysql"
}

モデルを作成する。例)userモデル

ターミナル.
npx sequelize-cli model:generate --name User --attributes name:string,pass:string

//(attributesはスペースは開けない)

npx ( npmを拡張したもの。標準でNode.jsに入っている ) のsequelize-cliコマンドを実行

モデルの情報(development)を元にマイグレートを実施

ターミナル.
 npx sequelize-cli db:migrate --env development

db-dev.sqlite3が生成される。(データーベースファイル)
maigrationファイルが作成される。

マイグレーションを一個前に戻す

npx sequelize-cli db:migrate:undo

マイグレーションを全て戻す

npx sequelize-cli db:migrate:undo:all

ベーシックなモデルの例(コマンドで生成されるものを簡略化)

model/user.js
'use strict';
module.exports = (sequelize, DataTypes) => {
  const User = sequelize.define('User', {
    name: DataTypes.STRING,
    pass: DataTypes.STRING,
  }, {});
  User.associate = function(models) {
    // アソシエーションを記載
  return User;
};

モジュールエクスポートで関数を返している。関数は最終的に変数Userをreturnする。

アソシエーションの書き方(UserがBookを多数持っている場合)

User.associate = function (models) {
  User.hasMany(models.Book);
};
Book.associate = function(models) {
  Book.belongsTo(models.User, {foreignKey: 'user_id'});
};
//第二引数に外部キーを渡す
'use strict';
const { Model } = require('sequelize');

module.exports = (sequelize, DataTypes) => {
  class Post extends Model {
    static associate(models) {
      Book.belongsTo(models.User, { foreignKey: 'user_id' });
    }
  };
  Post.init({
    title: DataTypes.STRING,
    content: DataTypes.STRING,
    user_id: DataTypes.INTEGER, //所属するほうに外部キーを設定
  }, {
    sequelize,
    modelName: 'Post',
  });
  return Post;
};

シーダーでダミーデーターを格納する。

シーダーの作成

ターミナル.
npx sequelize-cli seed:generate --name sample-user
sample-user.js
//作成例

'use strict';

module.exports = {
  up: async (queryInterface, Sequelize) => {
    return queryInterface.bulkInsert('Users', [
      {
        name: 'Taro',
        pass: 'lkfjaluadf',
        createdAt: new Date(),
        updatedAt: new Date()
      },
      {
        name: 'Hanako',
        pass: 'fdakljfa',
        createdAt: new Date(),
        updatedAt: new Date()
      }
    ]);
  },

  down: async (queryInterface, Sequelize) => {
    return queryInterface.bulkDelete('Users', null, {});
  }
};

シーダーの実行

ターミナル.
npx sequelize-cli db:seed:all

データベースクリアサンプル


const db = require('../models/index');

db.User.destroy({
  where: {},
  truncate: true
})

db.Post.destroy({
  where: {},
  truncate: true
})

SequelizeでORMを利用する。

モデルを使用するファイルで、models/index(自動生成される)を読み込み。
models/indexはmodels配下のモデルファイルを読み込んでる。

const db =require('models/index');

index.jsを読み込みdbに格納する。dbにSequelizeのあらゆる情報がまとめられる。

index.js
'use strict';

const fs = require('fs'); //fsのロード
const path = require('path');//pathをロード
const Sequelize = require('sequelize'); //sequelizeをロード
const basename = path.basename(__filename);//このファイル名をbasenameを格納
const env = process.env.NODE_ENV || 'development'; //環境変数NODE_ENVが設定されていたら返す。なければ'development'
const config = require(__dirname + '/../config/config.json')[env];//configファイルを指定し、envに入っている文字列と一致するプロパティーの内容をconfigに格納。
const db = {};

let sequelize;
if (config.use_env_variable) {
  sequelize = new Sequelize(process.env[config.use_env_variable], config);
} else {
  sequelize = new Sequelize(config.database, config.username, config.password, config);
}

fs
  .readdirSync(__dirname)//同じファイルのモデルを自動読み込み
  .filter(file => {
    return (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js');
  })
  .forEach(file => {
    const model = require(path.join(__dirname, file))(sequelize, Sequelize.DataTypes);
    db[model.name] = model;
  });//各ファイルから返されたモデル名をdbのmodelプロパティのプロパティに格納

Object.keys(db).forEach(modelName => {
  if (db[modelName].associate) {
    db[modelName].associate(db);
  }
});

db.sequelize = sequelize;
db.Sequelize = Sequelize;

module.exports = db;//dbをエクスポート

自動生成

config/config.json
{
  "development": {
    "username": "root",
    "password": "root",
    "database": "minna_db",
    "host": "mysql",
    "dialect": "mysql"
  },
  "test": {
    "username": "root",
    "password": null,
    "database": "database_test",
    "host": "127.0.0.1",
    "dialect": "mysql"
  },
  "production": {
    "username": "root",
    "password": null,
    "database": "database_production",
    "host": "127.0.0.1",
    "dialect": "mysql"
  }
}

findAllで取得する。

Userモデルから全件取得する場合

  db.User.findAll().then((users) => {
    var data = {
      title: 'Users/Index',
      content: users
    }
    res.render('users/index', data);
  });
});

.UserでUserモデルを取り出す。
findAll()メソッドで全件取得。
thenメソッドで非同期処理完了後の処理をつなげる。引数に取得したデータが格納される。

findAll( )のオプション

引数にオプションを渡す。

findAll ( { 設定1 : 値1, 設定2 : 値2 } )

whereの場合

db.User.findeAll ( { where: {id : 1} } );

Opから演算子を指定して検索する。

const { Op } = require("sequelize");

sequelizeのOpプロパティをロードし、変数Opに格納する。

Opで演算子から検索する方法

where: { フィールド : {[ Op.演算子 ] : } }

Opの演算子プロパティ

eq : =
ne : !=
lt : <
lte : <=
gt : >
gte : >=
like : like
ilike : ilike

idが3以上のユーザーを取得の場合

db.User.findAll( {where: { id: {[Op.gte] : 3} } )

AND条件 1以上,3以下の場合

db.User.findAll(
  {where: {
    id: {
      [Op.gte] : 1,
      [Op.lte] : 3,
    }
  }
)

OR条件

where { [Op.or]:[ {条件1}, {条件2} ] }

名前かメールにtaroが含まれるレコードを検索する。


 db.User.findAll({
    where: {
      [Op.or]:[
        {name:{[Op.like]:'%'+'taro'+'%'}},
        {mail:{[Op.like]:'%'+'taro'+'%'}}
      ]
    }

findByPkで検索する。

主キーで検索する場合

db.User.findByPk(主キー);

createで新規作成する。

モデル.create( {各プロパティ: } );
  db.sequelize.sync()
    .then(() => db.User.create({
      name: "taro",
      pass: "fakdjfakjf",
    }))
    .then((user) => {
    });
});

Sequelizeオブジェクトのsyncメソッドを用いて、同期処理を行う。実際の処理は.thenに任せる。

モデルを書き換えて更新する。

db.User.findByPk(1)
  .then(usr => {
    usr.name = "jiro";
    usr.pass = "fdafdafadf";
    usr.save()
    .then(()=>{
  });

レコードの削除


db.User.findByPk(1)
  .then(usr => {
    usr.destroy().then(()=>{
  });

Sequelizeを用いてバリデーションをかける。

モデルに定義する。

'use strict';

module.exports = (sequelize, DataTypes) => {
  const User = sequelize.define('User', {
    name: {
      type:DataTypes.STRING,
      //バリデーションを設定
      validate: {
        notEmpty: true
      }
    },
  }, {});

  return User;
};
router.get('/add',(req, res, next)=> {
  var data = {
    //新しいレコードを作成し、fromに格納
    form: new db.User(),
    //errは空
    err:null
  }
  res.render('users/add', data);
});

//作成された場合の処理
router.post('/add',(req, res, next)=> {
  const form = {
    name: req.body.name,
    pass: req.body.pass,
  };
  db.sequelize.sync()
    .then(() => db.User.create(form)
    .then(usr=> {
      res.redirect('/users')
    })
    //バリデーションにかかった場合の処理
    .catch(err=> {
      var data = {
        form: form,
        //errにエラー情報が格納されている。
        err: err
      }
      res.render('users/add', data);
    })
    )
});

表示をカスタマイズ

name: {
      type:DataTypes.STRING,
      //バリデーションを設定
      validate: {
        notEmpty: {
          msg: "必ず入力してください";
      }
    },

notEmptyオブジェクトのmsgプロパティを書き換える。

8
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
5