본문 바로가기

블록체인 기반 핀테크 및 응용 SW개발자 양성과정 일기

[37일차] 20210504 sequelize 세팅하기(visual studio) , sequelize 사용해보기

반응형

1. npm install express nunjucks sequelize sequelize-cli mysql2 설치하기 

 

nodemon - 편하고 좋은 것 (server 껏다 켰다 연습하기 때문에 지금은 안쓸 것!) 

 

 

2. npx sequelizes init (폴더, 폴더 안 파일들을 줌) 

 

npm - 우리가 다운을 받지 않은 상태 - 폴더를 다운받은 것 - 기본적인 틀 제공

npx - install 해서 다운받은 폴더를 실행시켜서 세팅해준 것 

 

 

* config 폴더 안 config 파일 존재, models 폴더 안 index.js 파일 존재  

config - 접속 정보를 저장해주는 객체 

실 서버의 정보를 development

연습(test server)은 test

상품 정보는 production에 담아 달라 

 

3. config - config 파일 안 development 정보 내 컴퓨터 정보로 바꾸기 

{
  "development": {
    "username": "root",
    "password": "d",              //변경
    "database": "joinn",           //변경
    "host": "127.0.0.1",
    "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"
  }
}

 

 

4. models- index.js 분석

'use strict';  //없어도 상관 없다.

const fs = require('fs');
const path = require('path');
const Sequelize = require('sequelize');  //Sequelize
const basename = path.basename(__filename);
const env = process.env.NODE_ENV || 'development'; //test할 때 development를 test로 바꿔 
const config = require(__dirname + '/../config/config.json')[env]; // env 위에 정의되어 있음. 우리는env 설정안했음. 지금 env = development 값 / config는 요걸 가져옴 
// config = config파일 안 development 의 객체 값이 된다. 
const db = {};  //빈 객체로 선언 

let sequelize;  //sequelize
if (config.use_env_variable) { // 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);
} // new = 함수가 객체로 변한다 / 결과적으로 요 값이 객체로 변하겠구나~ 알 수 있음.  config 어디서 가져왓냐면 위에 8번줄
// development 객체 안의 내용을 내 db 내용과 같도록 정보 바꾸기 

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;
  });

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

db.sequelize = sequelize;   //sequelize, Sequelize 두가지 속성 값을 db에 넣었다. 
db.Sequelize = Sequelize;

module.exports = db; // db라는 변수를 결과적으로 넘기는구나 
//db라는 파일을 불러왔을 때 객체로 받는구나 알 수 있음.
//팁 : 얘는 결국 무엇을 넘기나 아랫줄에 module을 쳌! 그거에 대한 결과값이 무엇인가 무언가를 담아서 보냈는가 를 쳌 

 

5. app.js 파일 생성 & 기본구조 코드 작성 (서버 실행할 때 이걸로 실행하겠다.

const express = require('express');
const app = express();

app.get('/',(req,res)=>{
    res.send('hello world');
})

app.listen(3000,()=>{
    console.log('server start 3000')
})

 

6. index.js 파일을 가져오기  

 

const express = require('express');
const app = express();
const sequelize=require('./models') //index생략가능   요것만 추가함 

console.log(sequelize)

app.get('/',(req,res)=>{
    res.send('hello world');
})

app.listen(3000,()=>{
    console.log('server start 3000')
})

console.log로 sequelize 내용 쳌

{
  sequelize: <ref *1> Sequelize {   //요기 sequelize안에 들어감 sequelize는 Sequeliz의 객체로 된
    options: {
      dialect: 'mysql',
      dialectModule: null,
      dialectModulePath: null,     
      host: '127.0.0.1',
      protocol: 'tcp',
      define: {},
      query: {},
      sync: {},
      timezone: '+00:00',
      clientMinMessages: 'warning',
      standardConformingStrings: true,
      logging: [Function: log],
      omitNull: false,
      native: false,
      replication: false,
      ssl: undefined,
      pool: {},
      quoteIdentifiers: true,
      hooks: {},
      retry: [Object],
      transactionType: 'DEFERRED',
      isolationLevel: null,
      databaseVersion: 0,
      typeValidation: false,
      benchmark: false,
      minifyAliases: false,
      logQueryParameters: false,
      username: 'root',
      password: 'd',
      database: 'joinn'
    },
    config: {
      database: 'joinn',
      username: 'root',
      password: 'd',
      host: '127.0.0.1',
      port: 3306,
      pool: {},
      protocol: 'tcp',
      native: false,
      ssl: undefined,
      replication: false,
      dialectModule: null,
      dialectModulePath: null,
      keepDefaultTimezone: undefined,
      dialectOptions: undefined
    },
    dialect: MysqlDialect {
      sequelize: [Circular *1],
      connectionManager: [ConnectionManager],
      queryGenerator: [MySQLQueryGenerator],
      queryInterface: [MySQLQueryInterface]
    },
    queryInterface: MySQLQueryInterface {
      sequelize: [Circular *1],
      queryGenerator: [MySQLQueryGenerator]
    },
    models: {},
    modelManager: ModelManager { models: [], sequelize: [Circular *1] },
    connectionManager: ConnectionManager {
      sequelize: [Circular *1],
      config: [Object],
      dialect: [MysqlDialect],
      versionPromise: null,
      dialectName: 'mysql',
      pool: [Pool],
      lib: [Object]
    }
  },
  Sequelize: <ref *5> [class Sequelize] { //Sequelize는 class 다 
    version: '6.6.2',
    options: { hooks: {} },
    Utils: {
      classToInvokable: [Function: classToInvokable],
      joinSQLFragments: [Function: joinSQLFragments],
      useInflection: [Function: useInflection],
      camelizeIf: [Function: camelizeIf],
      underscoredIf: [Function: underscoredIf],
      isPrimitive: [Function: isPrimitive],
      mergeDefaults: [Function: mergeDefaults],
      merge: [Function: merge],
      spliceStr: [Function: spliceStr],
      camelize: [Function: camelize],
      underscore: [Function: underscore],
      singularize: [Function: singularize],
      pluralize: [Function: pluralize],
      format: [Function: format],
      formatNamedParameters: [Function: formatNamedParameters],
      cloneDeep: [Function: cloneDeep],
      mapFinderOptions: [Function: mapFinderOptions],
      mapOptionFieldNames: [Function: mapOptionFieldNames],
      mapWhereFieldNames: [Function: mapWhereFieldNames],
      mapValueFieldNames: [Function: mapValueFieldNames],
      isColString: [Function: isColString],
      canTreatArrayAsAnd: [Function: canTreatArrayAsAnd],
      combineTableNames: [Function: combineTableNames],
      toDefaultValue: [Function: toDefaultValue],
      defaultValueSchemable: [Function: defaultValueSchemable],
      removeNullValuesFromHash: [Function: removeNullValuesFromHash],
      now: [Function: now],
      TICK_CHAR: '`',
      addTicks: [Function: addTicks],
      removeTicks: [Function: removeTicks],
      flattenObjectDeep: [Function: flattenObjectDeep],
      SequelizeMethod: [class SequelizeMethod],
      Fn: [class Fn extends SequelizeMethod],
      Col: [class Col extends SequelizeMethod],
      Cast: [class Cast extends SequelizeMethod],
      Literal: [class Literal extends SequelizeMethod],
      Json: [class Json extends SequelizeMethod],
      Where: [class Where extends SequelizeMethod],
      getOperators: [Function: getOperators],
      getComplexKeys: [Function: getComplexKeys],
      getComplexSize: [Function: getComplexSize],
      isWhereEmpty: [Function: isWhereEmpty],
      generateEnumName: [Function: generateEnumName],
      camelizeObjectKeys: [Function: camelizeObjectKeys],
      defaults: [Function: defaults],
      nameIndex: [Function: nameIndex],
      intersects: [Function: intersects]
    },
    Op: {
      eq: Symbol(eq),
      ne: Symbol(ne),
      gte: Symbol(gte),
      gt: Symbol(gt),
      lte: Symbol(lte),
      lt: Symbol(lt),
      not: Symbol(not),
      is: Symbol(is),
      in: Symbol(in),
      notIn: Symbol(notIn),
      like: Symbol(like),
      notLike: Symbol(notLike),
      iLike: Symbol(iLike),
      notILike: Symbol(notILike),
      startsWith: Symbol(startsWith),
      endsWith: Symbol(endsWith),
      substring: Symbol(substring),
      regexp: Symbol(regexp),
      notRegexp: Symbol(notRegexp),
      iRegexp: Symbol(iRegexp),
      notIRegexp: Symbol(notIRegexp),
      between: Symbol(between),
      notBetween: Symbol(notBetween),
      overlap: Symbol(overlap),
      contains: Symbol(contains),
      contained: Symbol(contained),
      adjacent: Symbol(adjacent),
      strictLeft: Symbol(strictLeft),
      strictRight: Symbol(strictRight),
      noExtendRight: Symbol(noExtendRight),
      noExtendLeft: Symbol(noExtendLeft),
      and: Symbol(and),
      or: Symbol(or),
      any: Symbol(any),
      all: Symbol(all),
      values: Symbol(values),
      col: Symbol(col),
      placeholder: Symbol(placeholder),
      join: Symbol(join),
      match: Symbol(match)
    },
    TableHints: {
      NOLOCK: 'NOLOCK',
      READUNCOMMITTED: 'READUNCOMMITTED',
      UPDLOCK: 'UPDLOCK',
      REPEATABLEREAD: 'REPEATABLEREAD',
      SERIALIZABLE: 'SERIALIZABLE',
      READCOMMITTED: 'READCOMMITTED',
      TABLOCK: 'TABLOCK',
      TABLOCKX: 'TABLOCKX',
      PAGLOCK: 'PAGLOCK',
      ROWLOCK: 'ROWLOCK',
      NOWAIT: 'NOWAIT',
      READPAST: 'READPAST',
      XLOCK: 'XLOCK',
      SNAPSHOT: 'SNAPSHOT',
      NOEXPAND: 'NOEXPAND'
    },
    IndexHints: { USE: 'USE', FORCE: 'FORCE', IGNORE: 'IGNORE' },
    Transaction: <ref *2> [class Transaction] {
      Transaction: [Circular *2],
      default: [Circular *2]
    },
    QueryTypes: {
      SELECT: 'SELECT',
      INSERT: 'INSERT',
      UPDATE: 'UPDATE',
      BULKUPDATE: 'BULKUPDATE',
      BULKDELETE: 'BULKDELETE',
      DELETE: 'DELETE',
      UPSERT: 'UPSERT',
      VERSION: 'VERSION',
      SHOWTABLES: 'SHOWTABLES',
      SHOWINDEXES: 'SHOWINDEXES',
      DESCRIBE: 'DESCRIBE',
      RAW: 'RAW',
      FOREIGNKEYS: 'FOREIGNKEYS',
      SHOWCONSTRAINTS: 'SHOWCONSTRAINTS'
    },
    Validator: <ref *3> {
      version: '10.11.0',
      toDate: [Function],
      toFloat: [Function],
      toInt: [Function],
      toBoolean: [Function],
      equals: [Function],
      contains: [Function: contains],
      matches: [Function],
      isEmail: [Function],
      isURL: [Function],
      isMACAddress: [Function],
      isIP: [Function],
      isIPRange: [Function],
      isFQDN: [Function],
      isBoolean: [Function],
      isAlpha: [Function: isAlpha],
      isAlphaLocales: [Array],
      isAlphanumeric: [Function: isAlphanumeric],
      isAlphanumericLocales: [Array],
      isNumeric: [Function],
      isPort: [Function],
      isLowercase: [Function],
      isUppercase: [Function],
      isAscii: [Function],
      isFullWidth: [Function: isFullWidth],
      isHalfWidth: [Function: isHalfWidth],
      isVariableWidth: [Function],
      isMultibyte: [Function],
      isSurrogatePair: [Function],
      isInt: [Function],
      isFloat: [Function: isFloat],
      isFloatLocales: [Array],
      isDecimal: [Function: isDecimal],
      isHexadecimal: [Function],
      isDivisibleBy: [Function],
      isHexColor: [Function],
      isISRC: [Function],
      isMD5: [Function],
      isHash: [Function],
      isJWT: [Function],
      isJSON: [Function],
      isEmpty: [Function],
      isLength: [Function],
      isByteLength: [Function],
      isUUID: [Function],
      isMongoId: [Function],
      isAfter: [Function],
      isBefore: [Function],
      isIn: [Function],
      isCreditCard: [Function],
      isIdentityCard: [Function],
      isISIN: [Function],
      isISBN: [Function],
      isISSN: [Function],
      isMobilePhone: [Function: isMobilePhone],
      isMobilePhoneLocales: [Array],
      isPostalCode: [Function: _default],
      isPostalCodeLocales: [Array],
      isCurrency: [Function],
      isISO8601: [Function],
      isRFC3339: [Function],
      isISO31661Alpha2: [Function],
      isISO31661Alpha3: [Function],
      isBase64: [Function],
      isDataURI: [Function],
      isMagnetURI: [Function],
      isMimeType: [Function],
      isLatLong: [Function],
      ltrim: [Function],
      rtrim: [Function],
      trim: [Function],
      escape: [Function],
      unescape: [Function],
      stripLow: [Function],
      whitelist: [Function],
      blacklist: [Function],
      isWhitelisted: [Function],
      normalizeEmail: [Function],
      toString: [Function],
      default: [Circular *3],
      isImmutable: [Function (anonymous)],
      notNull: [Function (anonymous)],
      extend: [Function: extend],
      notEmpty: [Function: notEmpty],
      len: [Function: len],
      isUrl: [Function: isUrl],
      isIPv6: [Function: isIPv6],
      isIPv4: [Function: isIPv4],
      notIn: [Function: notIn],
      regex: [Function: regex],
      notRegex: [Function: notRegex],
      min: [Function: min],
      max: [Function: max],
      not: [Function: not],
      notContains: [Function: notContains],
      is: [Function: is],
      isNull: [Function],
      isDate: [Function (anonymous)]
    },
    Model: Model,
    DataTypes: {
      ABSTRACT: [Function],
      STRING: [Function],
      CHAR: [Function],
      TEXT: [Function],
      NUMBER: [Function],
      TINYINT: [Function],
      SMALLINT: [Function],
      MEDIUMINT: [Function],
      INTEGER: [Function],
      BIGINT: [Function],
      FLOAT: [Function],
      TIME: [Function],
      DATE: [Function],
      DATEONLY: [Function],
      BOOLEAN: [Function],
      NOW: [Function],
      BLOB: [Function],
      DECIMAL: [Function],
      NUMERIC: [Function],
      UUID: [Function],
      UUIDV1: [Function],
      UUIDV4: [Function],
      HSTORE: [Function],
      JSON: [Function],
      JSONB: [Function],
      VIRTUAL: [Function],
      ARRAY: [Function],
      ENUM: [Function],
      RANGE: [Function],
      REAL: [Function],
      'DOUBLE PRECISION': [Function],
      DOUBLE: [Function],
      GEOMETRY: [Function],
      GEOGRAPHY: [Function],
      CIDR: [Function],
      INET: [Function],
      MACADDR: [Function],
      CITEXT: [Function],
      TSVECTOR: [Function],
      postgres: [Object],
      mysql: [Object],
      mariadb: [Object],
      sqlite: [Object],
      mssql: [Object]
    },
    ABSTRACT: [class ABSTRACT] { types: {}, key: 'ABSTRACT' },
    STRING: [class STRING extends ABSTRACT] { types: [Object], key: 'STRING' },
    CHAR: [class CHAR extends STRING] { types: [Object], key: 'CHAR' },
    TEXT: [class TEXT extends ABSTRACT] { types: [Object], key: 'TEXT' },
    NUMBER: [class NUMBER extends ABSTRACT] { types: {}, key: 'NUMBER' },
    TINYINT: [class TINYINT extends INTEGER] { types: [Object], key: 'TINYINT' },
    SMALLINT: [class SMALLINT extends INTEGER] {
      types: [Object],
      key: 'SMALLINT'
    },
    MEDIUMINT: [class MEDIUMINT extends INTEGER] {
      types: [Object],
      key: 'MEDIUMINT'
    },
    INTEGER: [class INTEGER extends NUMBER] { types: [Object], key: 'INTEGER' },
    BIGINT: [class BIGINT extends INTEGER] { types: [Object], key: 'BIGINT' },
    FLOAT: [class FLOAT extends NUMBER] { types: [Object], key: 'FLOAT' },
    TIME: [class TIME extends ABSTRACT] { types: [Object], key: 'TIME' },
    DATE: [class DATE extends ABSTRACT] { types: [Object], key: 'DATE' },
    DATEONLY: [class DATEONLY extends ABSTRACT] {
      types: [Object],
      key: 'DATEONLY'
    },
    BOOLEAN: [class BOOLEAN extends ABSTRACT] {
      parse: [Function: _sanitize],
      types: [Object],
      key: 'BOOLEAN'
    },
    NOW: [class NOW extends ABSTRACT] { types: {}, key: 'NOW' },
    BLOB: [class BLOB extends ABSTRACT] { types: [Object], key: 'BLOB' },
    DECIMAL: [class DECIMAL extends NUMBER] { types: [Object], key: 'DECIMAL' },
    NUMERIC: [class DECIMAL extends NUMBER] { types: [Object], key: 'DECIMAL' },
    UUID: [class UUID extends ABSTRACT] { types: [Object], key: 'UUID' },
    UUIDV1: [class UUIDV1 extends ABSTRACT] { types: {}, key: 'UUIDV1' },
    UUIDV4: [class UUIDV4 extends ABSTRACT] { types: {}, key: 'UUIDV4' },
    HSTORE: [class HSTORE extends ABSTRACT] { types: [Object], key: 'HSTORE' },
    JSON: [class JSONTYPE extends ABSTRACT] { types: [Object], key: 'JSON' },
    JSONB: [class JSONB extends JSONTYPE] { types: [Object], key: 'JSONB' },
    VIRTUAL: [class VIRTUAL extends ABSTRACT] { types: {}, key: 'VIRTUAL' },
    ARRAY: [class ARRAY extends ABSTRACT] { types: {}, key: 'ARRAY' },
    ENUM: [class ENUM extends ABSTRACT] { types: [Object], key: 'ENUM' },
    RANGE: [class RANGE extends ABSTRACT] { types: [Object], key: 'RANGE' },
    REAL: [class REAL extends NUMBER] { types: [Object], key: 'REAL' },
    'DOUBLE PRECISION': [class DOUBLE extends NUMBER] {
      types: [Object],
      key: 'DOUBLE PRECISION'
    },
    DOUBLE: [class DOUBLE extends NUMBER] {
      types: [Object],
      key: 'DOUBLE PRECISION'
    },
    GEOMETRY: [class GEOMETRY extends ABSTRACT] {
      types: [Object],
      key: 'GEOMETRY'
    },
    GEOGRAPHY: [class GEOGRAPHY extends ABSTRACT] {
      types: [Object],
      key: 'GEOGRAPHY'
    },
    CIDR: [class CIDR extends ABSTRACT] { types: [Object], key: 'CIDR' },
    INET: [class INET extends ABSTRACT] { types: [Object], key: 'INET' },
    MACADDR: [class MACADDR extends ABSTRACT] { types: [Object], key: 'MACADDR' },
    CITEXT: [class CITEXT extends ABSTRACT] { types: [Object], key: 'CITEXT' },
    TSVECTOR: [class TSVECTOR extends ABSTRACT] {
      types: [Object],
      key: 'TSVECTOR'
    },
    postgres: {
      DECIMAL: [class DECIMAL extends DECIMAL],
      BLOB: [class BLOB extends BLOB],
      STRING: [class STRING extends STRING],
      CHAR: [class CHAR extends CHAR],
      TEXT: [class TEXT extends TEXT],
      CITEXT: [class CITEXT extends CITEXT],
      TINYINT: [class TINYINT extends TINYINT],
      SMALLINT: [class SMALLINT extends SMALLINT],
      INTEGER: [Function],
      BIGINT: [class BIGINT extends BIGINT],
      BOOLEAN: [Function],
      DATE: [class DATE extends DATE],
      DATEONLY: [class DATEONLY extends DATEONLY],
      REAL: [class REAL extends REAL],
      'DOUBLE PRECISION': [class DOUBLE extends DOUBLE],
      FLOAT: [class FLOAT extends FLOAT],
      GEOMETRY: [class GEOMETRY extends GEOMETRY],
      GEOGRAPHY: [class GEOGRAPHY extends GEOGRAPHY],
      HSTORE: [class HSTORE extends HSTORE],
      RANGE: [class RANGE extends RANGE],
      ENUM: [class ENUM extends ENUM]
    },
    mysql: {
      ENUM: [class ENUM extends ENUM],
      DATE: [class DATE extends DATE],
      DATEONLY: [class DATEONLY extends DATEONLY],
      UUID: [class UUID extends UUID],
      GEOMETRY: [class GEOMETRY extends GEOMETRY],
      DECIMAL: [class DECIMAL extends DECIMAL],
      JSON: [class JSONTYPE extends JSONTYPE]
    },
    mariadb: {
      ENUM: [class ENUM extends ENUM],
      DATE: [class DATE extends DATE],
      DATEONLY: [class DATEONLY extends DATEONLY],
      UUID: [class UUID extends UUID],
      GEOMETRY: [class GEOMETRY extends GEOMETRY],
      DECIMAL: [class DECIMAL extends DECIMAL],
      JSON: [class JSONTYPE extends JSONTYPE]
    },
    sqlite: {
      DATE: [class DATE extends DATE],
      DATEONLY: [class DATEONLY extends DATEONLY],
      STRING: [class STRING extends STRING],
      CHAR: [class CHAR extends CHAR],
      NUMBER: [class NUMBER extends NUMBER],
      FLOAT: [Function],
      REAL: [Function],
      'DOUBLE PRECISION': [Function],
      TINYINT: [class TINYINT extends TINYINT],
      SMALLINT: [class SMALLINT extends SMALLINT],
      MEDIUMINT: [class MEDIUMINT extends MEDIUMINT],
      INTEGER: [class INTEGER extends INTEGER],
      BIGINT: [class BIGINT extends BIGINT],
      TEXT: [class TEXT extends TEXT],
      ENUM: [class ENUM extends ENUM],
      JSON: [class JSONTYPE extends JSONTYPE],
      CITEXT: [class CITEXT extends CITEXT]
    },
    mssql: {
      BLOB: [class BLOB extends BLOB],
      BOOLEAN: [class BOOLEAN extends BOOLEAN],
      ENUM: [class ENUM extends ENUM],
      STRING: [class STRING extends STRING],
      UUID: [class UUID extends UUID],
      DATE: [class DATE extends DATE],
      DATEONLY: [class DATEONLY extends DATEONLY],
      NOW: [class NOW extends NOW],
      TINYINT: [class TINYINT extends TINYINT],
      SMALLINT: [class SMALLINT extends SMALLINT],
      INTEGER: [class INTEGER extends INTEGER],
      BIGINT: [class BIGINT extends BIGINT],
      REAL: [class REAL extends REAL],
      FLOAT: [class FLOAT extends FLOAT],
      TEXT: [class TEXT extends TEXT]
    },
    Deferrable: {
      INITIALLY_DEFERRED: [class INITIALLY_DEFERRED extends ABSTRACT],
      INITIALLY_IMMEDIATE: [class INITIALLY_IMMEDIATE extends ABSTRACT],
      NOT: [class NOT extends ABSTRACT],
      SET_DEFERRED: [class SET_DEFERRED extends ABSTRACT],
      SET_IMMEDIATE: [class SET_IMMEDIATE extends ABSTRACT]
    },
    Association: <ref *4> [class Association] {
      BelongsTo: [Function],
      HasOne: [class HasOne extends Association],
      HasMany: [Function],
      BelongsToMany: [Function],
      default: [Circular *4],
      Association: [Circular *4]
    },
    useInflection: [Function: useInflection],
    _setupHooks: [Function: _setupHooks],
    runHooks: [AsyncFunction: runHooks],
    addHook: [Function: addHook],
    removeHook: [Function: removeHook],
    hasHook: [Function: hasHook],
    hasHooks: [Function: hasHook],
    beforeValidate: [Function (anonymous)],
    afterValidate: [Function (anonymous)],
    validationFailed: [Function (anonymous)],
    beforeCreate: [Function (anonymous)],
    afterCreate: [Function (anonymous)],
    beforeDestroy: [Function (anonymous)],
    afterDestroy: [Function (anonymous)],
    beforeRestore: [Function (anonymous)],
    afterRestore: [Function (anonymous)],
    beforeUpdate: [Function (anonymous)],
    afterUpdate: [Function (anonymous)],
    beforeSave: [Function (anonymous)],
    afterSave: [Function (anonymous)],
    beforeUpsert: [Function (anonymous)],
    afterUpsert: [Function (anonymous)],
    beforeBulkCreate: [Function (anonymous)],
    afterBulkCreate: [Function (anonymous)],
    beforeBulkDestroy: [Function (anonymous)],
    afterBulkDestroy: [Function (anonymous)],
    beforeBulkRestore: [Function (anonymous)],
    afterBulkRestore: [Function (anonymous)],
    beforeBulkUpdate: [Function (anonymous)],
    afterBulkUpdate: [Function (anonymous)],
    beforeFind: [Function (anonymous)],
    beforeFindAfterExpandIncludeAll: [Function (anonymous)],
    beforeFindAfterOptions: [Function (anonymous)],
    afterFind: [Function (anonymous)],
    beforeCount: [Function (anonymous)],
    beforeDefine: [Function (anonymous)],
    afterDefine: [Function (anonymous)],
    beforeInit: [Function (anonymous)],
    afterInit: [Function (anonymous)],
    beforeAssociate: [Function (anonymous)],
    afterAssociate: [Function (anonymous)],
    beforeConnect: [Function (anonymous)],
    afterConnect: [Function (anonymous)],
    beforeDisconnect: [Function (anonymous)],
    afterDisconnect: [Function (anonymous)],
    beforeSync: [Function (anonymous)],
    afterSync: [Function (anonymous)],
    beforeBulkSync: [Function (anonymous)],
    afterBulkSync: [Function (anonymous)],
    beforeQuery: [Function (anonymous)],
    afterQuery: [Function (anonymous)],
    Error: [class BaseError extends Error],
    BaseError: [class BaseError extends Error],
    AggregateError: [class AggregateError extends BaseError],
    AsyncQueueError: [class AsyncQueueError extends BaseError],
    AssociationError: [class AssociationError extends BaseError],
    BulkRecordError: [class BulkRecordError extends BaseError],
    ConnectionError: [class ConnectionError extends BaseError],
    DatabaseError: [class DatabaseError extends BaseError],
    EagerLoadingError: [class EagerLoadingError extends BaseError],
    EmptyResultError: [class EmptyResultError extends BaseError],
    InstanceError: [class InstanceError extends BaseError],
    OptimisticLockError: [class OptimisticLockError extends BaseError],
    QueryError: [class QueryError extends BaseError],
    SequelizeScopeError: [class SequelizeScopeError extends BaseError],
    ValidationError: [class ValidationError extends BaseError] {
      ValidationErrorItem: [Function]
    },
    ValidationErrorItem: [class ValidationErrorItem] {
      Origins: [Object],
      TypeStringMap: [Object]
    },
    AccessDeniedError: [class AccessDeniedError extends ConnectionError],
    ConnectionAcquireTimeoutError: [class ConnectionAcquireTimeoutError extends ConnectionError],
    ConnectionRefusedError: [class ConnectionRefusedError extends ConnectionError],
    ConnectionTimedOutError: [class ConnectionTimedOutError extends ConnectionError],       
    HostNotFoundError: [class HostNotFoundError extends ConnectionError],
    HostNotReachableError: [class HostNotReachableError extends ConnectionError],
    InvalidConnectionError: [class InvalidConnectionError extends ConnectionError],
    ExclusionConstraintError: [class ExclusionConstraintError extends DatabaseError],       
    ForeignKeyConstraintError: [class ForeignKeyConstraintError extends DatabaseError],     
    TimeoutError: [class TimeoutError extends DatabaseError],
    UnknownConstraintError: [class UnknownConstraintError extends DatabaseError],
    UniqueConstraintError: [class UniqueConstraintError extends ValidationError],
    Sequelize: [Circular *5],
    default: [Circular *5]
  }
}

 

변수sequelize에 { } 치고 나서 console.log 찍어보기 

const express = require('express');
const app = express();
const {sequelize}=require('./models') //index생략가능

console.log(sequelize)

app.get('/',(req,res)=>{
    res.send('hello world');
})

app.listen(3000,()=>{
    console.log('server start 3000')
})
<ref *1> Sequelize {
  options: {          //option
    dialect: 'mysql',
    dialectModule: null,
    dialectModulePath: null,        
    host: '127.0.0.1',
    protocol: 'tcp',
    define: {},
    query: {},
    sync: {},
    timezone: '+00:00',
    clientMinMessages: 'warning',   
    standardConformingStrings: true,
    logging: [Function: log],
    omitNull: false,
    native: false,
    replication: false,
    ssl: undefined,
    pool: {},
    quoteIdentifiers: true,
    hooks: {},
    retry: { max: 5, match: [Array] },
    transactionType: 'DEFERRED',
    isolationLevel: null,
    databaseVersion: 0,
    typeValidation: false,
    benchmark: false,
    minifyAliases: false,
    logQueryParameters: false,
    username: 'root',
    password: 'd',
    database: 'joinn'
  },
  config: {              //config 존재
    database: 'joinn',
    username: 'root',
    password: 'd',
    host: '127.0.0.1',
    port: 3306,
    pool: {},
    protocol: 'tcp',
    native: false,
    ssl: undefined,
    replication: false,
    dialectModule: null,
    dialectModulePath: null,
    keepDefaultTimezone: undefined,
    dialectOptions: undefined
  },
  dialect: <ref *2> MysqlDialect {
    sequelize: [Circular *1],
    connectionManager: ConnectionManager {
      sequelize: [Circular *1],
      config: [Object],
      dialect: [Circular *2],
      versionPromise: null,
      dialectName: 'mysql',
      pool: [Pool],
      lib: [Object]
    },
    queryGenerator: MySQLQueryGenerator {
      sequelize: [Circular *1],
      options: [Object],
      dialect: 'mysql',
      _dialect: [Circular *2],
      OperatorMap: [Object],
      typeValidation: undefined
    },
    queryInterface: MySQLQueryInterface {
      sequelize: [Circular *1],
      queryGenerator: [MySQLQueryGenerator]
    }
  },
  queryInterface: MySQLQueryInterface {
    sequelize: [Circular *1],
    queryGenerator: MySQLQueryGenerator {
      sequelize: [Circular *1],
      options: [Object],
      dialect: 'mysql',
      _dialect: [MysqlDialect],
      OperatorMap: [Object],
      typeValidation: undefined
    }
  },
  models: {},
  modelManager: ModelManager { models: [], sequelize: [Circular *1] },
  connectionManager: <ref *3> ConnectionManager {
    sequelize: [Circular *1],                  //class 가 빠졌넹
    config: {
      database: 'joinn',
      username: 'root',
      password: 'd',
      host: '127.0.0.1',
      port: 3306,
      pool: [Object],
      protocol: 'tcp',
      native: false,
      ssl: undefined,
      replication: false,
      dialectModule: null,
      dialectModulePath: null,
      keepDefaultTimezone: undefined,
      dialectOptions: undefined
    },
    dialect: <ref *2> MysqlDialect {
      sequelize: [Circular *1],
      connectionManager: [Circular *3],
      queryGenerator: [MySQLQueryGenerator],
      queryInterface: [MySQLQueryInterface]
    },
    versionPromise: null,
    dialectName: 'mysql',
    pool: Pool {
      log: false,
      idleTimeoutMillis: 10000,
      acquireTimeoutMillis: 60000,
      reapIntervalMillis: 1000,
      maxUsesPerResource: Infinity,
      _factory: [Object],
      _count: 0,
      _draining: false,
      _pendingAcquires: [],
      _inUseObjects: [],
      _availableObjects: [],
      _removeIdleScheduled: false
    },
    lib: {
      createConnection: [Function (anonymous)],
      connect: [Function (anonymous)],
      Connection: [class Connection extends EventEmitter],
      createPool: [Function (anonymous)],
      createPoolCluster: [Function (anonymous)],
      createQuery: [Function: createQuery],
      Pool: [class Pool extends EventEmitter],
      createServer: [Function (anonymous)],
      PoolConnection: [Function],
      escape: [Function: escape],
      escapeId: [Function: escapeId],
      format: [Function: format],
      raw: [Function: raw],
      createConnectionPromise: [Getter],
      createPoolPromise: [Getter],
      createPoolClusterPromise: [Getter],
      Types: [Getter],
      Charsets: [Getter],
      CharsetToEncoding: [Getter],
      setMaxParserCache: [Function (anonymous)],
      clearParserCache: [Function (anonymous)]
    }
  }
}
server start 3000

 

 

 

-> { } 를 쓰게되면 require안에 있는 models안 index.js 파일 가져오면 db를 가져오는데 그 결과값을 소문자sequelize만 가져오기 위해 { } sequelize {sequelize} 만 가져오겠다. 함축어 

 

 

 

 

 

 

-----------------------------------------------------------------2교시---------------------------------------------------------

 

 

 

7. 사용해보기 

 

db접속 test코드 작성

 

const express = require('express');
const app = express();
const {sequelize}=require('./models') //index생략가능

sequelize.sync({force:false,}) //sequelize=객체 sync를 method로 사용해보기 -> console.log찍었던거에서 찾아보기
//sync 비동기 통신 사용할 때 sync()를 사용했었음. 얘 결과값 -> new Promise객체 
//force -> 접속했을 때 테이블이 존재하냐, 안하냐에 따라 table을 새로 만들거야? 를 세팅해주는 부분 
//force:false 생성하지 않음 / force:true 생성함 

app.get('/',(req,res)=>{
    res.send('hello world');
})

app.listen(3000,()=>{
    console.log('server start 3000')
})

sequelize.sync{{force:false}}) -> new Promise 객체 =>.then(), .catch() 사용가능 

 

const express = require('express');
const app = express();
const {sequelize}=require('./models') //index생략가능

 //sequelize=객체 sync를 method로 사용해보기 -> console.log찍었던거에서 찾아보기
//sync 비동기 통신 사용할 때 sync()를 사용했었음. 얘 결과값 -> new Promise객체 
//force -> 접속했을 때 테이블이 존재하냐, 안하냐에 따라 table을 새로 만들거야? 를 세팅해주는 부분 
//force:false 생성하지 않음 / force:true 생성함 
sequelize.sync({force:false,})
.then(()=>{
    console.log('db접속 성공')
})  
.catch(()=>{
    console.log('db접속 실패')
})
//여기서는 반환값을 만들어주지 않고 resolve가 호출되었을 떄 

app.get('/',(req,res)=>{
    res.send('hello world');
})

app.listen(3000,()=>{
    console.log('server start 3000')
})

-> console.log - node app.js 입력 

 

 -> config 비밀번호 잘못입력해서 오류가 떴었음

 

-> 다시해보니 잘 작동함 

 

 

 

 

 

orm 의 기능은 tables 생성까지 가능 

 

 

 

8. models폴더 안 user.js파일 만들기 - 책 320p 내용 작성 

 

sequelize db 접속까지 한 상태

sequelize  -  table생성, 수정, 삭제도 가능 

 

 

user.js 작성

const Sequelize=require('sequelize');  //sequelize가져오기 

module.exports=class User extends Sequelize.Model{  //class 던져주기 
    static init(sequelize){
        //User라는 class에서 정적으로 사용하는 , 쉽게 말하면constructor 
        //처음 생성할 때 요기가 실행된다~ 
        //User라는class가 객체 생성없이 바로 사용 가능하다~ 라는 뜻 / 모르겠다. 
        return super.init({
            name:{ //name varchar(20) NOT NULL UNIQUE
                type:Sequelize.STRING(20), //부모로부터  받아 Sequelize.STRING 이라고 적기 
                                            //== varchar(20) 
                allowNull:false,  // == not null 무적권 이름은 null값이 있으면 안된다. 
                unique:true,    // unique 사용하겠다 ~ 
            },
            age:{ // age라는 field를 만들거고  sql 구문 = age INT UNSIGNED NOT NULL 
                type:Sequelize.INTEGER.UNSIGNED, // 숫자만 사용할건데 양수만 사용할거야 + 값만 
                allowNull:false, // NOT NULL 
            },
            married:{  // married TINYINT(1) NOT NULL 
                type:Sequelize.BOOLEAN, // tinyint 한자리수 정수 숫자 받는 뜻
                allowNull:false, //not null
            },
            comment:{ /// comment TEXT NOT NULL 
                type:Sequelize.TEXT,
                allowNull:true,
            },
            created_at:{ // created_at DATETIME NOT NULL default NOW()
                type:Sequelize.DATE,
                allowNull:false,
                defaultValue:Sequelize.NOW,
            },
        },{
            sequelize,// 사용할 때 인자값 내용 넣는거 
            timestamps:false,
            underscored:false,
            modelName:'User', // express에서 JS 사용하기위한 이름 설정
            tableName:'users', // 실제 table 이름 요걸로 사용하겠다. 
            paranoid:false,
            charset:'utf8',  //
            collate:'utf8_general_ci', //or utf8mb4쓰기 
        });
    }
    static associate(db){} // 아직은 사용안함 
};

 

 

 

 

 

class test{
    constructor(){
        this.name="a"
    }
}

console.log(test);

class test{
    constructor(){
        this.name="a"
    }
}

console.log(new test);

 

class test{
    constructor(){
        this.name="a"
    }
    
    static init(){
        this.age='20'
        console.log('30')
    }
}

console.log(test);
console.log(new test);
test.init()        // 30 이 나옴 

 

 

 

 

-> undefined는 무시!

 

static 설명 = 객체를 변환하지 않고도 바로 사용 가능 

class test{
    constructor(){
        this.name="a"
    }
    
    init(){
        console.log('29')
    }

    static init(){          //객체로 생성하고나서 사용할 경우 x 
        this.age='20'                // class 생성하지않고도 바로 class method 안에 사용 가능 
        console.log('30')
    }
}

console.log(test);
console.log(new test);
test.init();

let a = new test();

a.init();

 

요 부분 이해가 잘 안가서 연습하기 ! 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

부모에 있는 method를 가져오는게 super 

부모에 있는 init이라는 method를 가져오려고 

 

super.init은 2가지의 객체를 받음 

return super.init ( { 필드 내용 } , { 테이블에 대한 설정값 } )

 

 

 

 

 

 

index.js 파일에서 user.js 사용하기 

 

index.js

'use strict';  //없어도 상관 없다.

const fs = require('fs');
const path = require('path');
const Sequelize = require('sequelize');  //Sequelize
const basename = path.basename(__filename);
const env = process.env.NODE_ENV || 'development'; //test할 때 development를 test로 바꿔 
const config = require(__dirname + '/../config/config.json')[env]; // env 위에 정의되어 있음. 우리는env 설정안했음. 지금 env = development 값 / config는 요걸 가져옴 
// config = config파일 안 development 의 객체 값이 된다. 
const User=require('./user');  //models/index.js에서 user.js를 사용하기 위해 가져옴 result= class 
//USer의 결과물은 CLASS 

const db = {};  //빈 객체로 선언 

let sequelize;  //sequelize
if (config.use_env_variable) { // 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);//접속정보를 담은 객체
} // new = 함수가 객체로 변한다 / 결과적으로 요 값이 객체로 변하겠구나~ 알 수 있음.  config 어디서 가져왓냐면 위에 8번줄
// development 객체 안의 내용을 내 db 내용과 같도록 정보 바꾸기 

/* 여기는 일단 주석처리!
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;
  });

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



db.User=User;  //db라는 객체에 user라는 property를 만들어서 User를 넣음 / app.js에서 User라는 calss를 가져올 수 있도록 
User.init(sequelize); // User라
//class User에서 바로 init 사용 (static으로 선언했기때문)
//sequelize = 접속 정보를 담은 객체 init의 첫번째 인자값으로 넣음 
//user.js에가서 확인해봐 

db.sequelize = sequelize;   //sequelize, Sequelize 두가지 속성 값을 db에 넣었다. 
db.Sequelize = Sequelize;

// db.associate(db);

module.exports = db; // db라는 변수를 결과적으로 넘기는구나 
//db라는 파일을 불러왔을 때 객체로 받는구나 알 수 있음.
//팁 : 얘는 결국 무엇을 넘기나 아랫줄에 module을 쳌! 그거에 대한 결과값이 무엇인가 무언가를 담아서 보냈는가 를 쳌 

user.js

 

const Sequelize=require('sequelize');  //sequelize가져오기 

module.exports=class User extends Sequelize.Model{  //class 던져주기 
    static init(sequelize){
        //User라는 class에서 정적으로 사용하는 , 쉽게 말하면constructor 
        //처음 생성할 때 요기가 실행된다~ 
        //User라는class가 객체 생성없이 바로 사용 가능하다~ 라는 뜻 / 모르겠다. 
        return super.init({
            name:{ //name varchar(20) NOT NULL UNIQUE
                type:Sequelize.STRING(20), //부모로부터  받아 Sequelize.STRING 이라고 적기 
                                            //== varchar(20) 
                allowNull:false,  // == not null 무적권 이름은 null값이 있으면 안된다. 
                unique:true,    // unique 사용하겠다 ~ 
            },
            age:{ // age라는 field를 만들거고  sql 구문 = age INT UNSIGNED NOT NULL 
                type:Sequelize.INTEGER.UNSIGNED, // 숫자만 사용할건데 양수만 사용할거야 + 값만 
                allowNull:false, // NOT NULL 
            },
            married:{  // married TINYINT(1) NOT NULL 
                type:Sequelize.BOOLEAN, // tinyint 한자리수 정수 숫자 받는 뜻
                allowNull:false, //not null
            },
            comment:{ /// comment TEXT NOT NULL 
                type:Sequelize.TEXT,
                allowNull:true,
            },
            created_at:{ // created_at DATETIME NOT NULL default NOW()
                type:Sequelize.DATE,
                allowNull:false,
                defaultValue:Sequelize.NOW,
            },
        },{
            sequelize,// 사용할 때 인자값 내용 넣는거 // 결국 config의 접속 정보를 받기위함 
            timestamps:false,
            underscored:false,
            modelName:'User', // express에서 JS 사용하기위한 이름 설정
            tableName:'users', // 실제 table 이름 요걸로 사용하겠다. 
            paranoid:false,
            charset:'utf8',  //
            collate:'utf8_general_ci', //or utf8mb4쓰기 
        });
    }
    static associate(db){} // 아직은 사용안함 
};

 

app.js

수정 force : false -> true

sequelize.sync({force:true,})

-> 

const express = require('express');
const app = express();
const {sequelize}=require('./models') //index생략가능

 //sequelize=객체 sync를 method로 사용해보기 -> console.log찍었던거에서 찾아보기
//sync 비동기 통신 사용할 때 sync()를 사용했었음. 얘 결과값 -> new Promise객체 
//force -> 접속했을 때 테이블이 존재하냐, 안하냐에 따라 table을 새로 만들거야? 를 세팅해주는 부분 
//force:false 생성하지 않음 / force:true 생성함 
sequelize.sync({force:true,}) //sequelize가 뭘 새로 만들겟다 모르겠음. 
.then(()=>{
    console.log('db접속 성공')
})  
.catch(()=>{
    console.log('db접속 실패')
})
//여기서는 반환값을 만들어주지 않고 resolve가 호출되었을 떄 

app.get('/',(req,res)=>{
    res.send('hello world');
})

app.listen(3000,()=>{
    console.log('server start 3000')
})

 

 

 

내용 잘 읽어보기

table을 생성하는 create문 만들어줌 

 

 

 

-----------------------------------------------------------------------------------------------------------------------------------

 

 

 

 

9. create 작성해보기 책 page 329 

 

 

table만들어놓은 상태라 요거 다시 false로 바꾸기 

sequelize.sync({force:false,}) 

 

 

app.js 추가 

app.get('/',(req,res)=>{
    User.create({
        name:'zero1',
        age:'24',
        married:false,
        comment:'자기소개1',
    })
    res.send('hello world');
})

 

mysql에서 잘 들어갔는지 확인 

 

??

 

 

-> get '/' 이어ㅣ서 localhost:3000 한번 들어갔다가 나와야 db가 나옴 

 

 

sequelize 장점 : 셋팅하는데 오래걸리지만 if(error)~ 뭔가 복잡한게 없음. 

 

 

셋팅(코드)이 길수록 사용하기 쉽고 

셋팅이 짧을 수록 사용하기 어렵다고 함..

 

 

 

mvc 패턴 중 model 에 대한 부분.

무조건 orm은 필요하다 라고 하는 파가 있음.

 

 

 

 

---------------------------------------------------------------------------------------------------------------------------------

 

 

app.js 

sequelize.sync({force:false,}) //sequelize가 뭘 새로 만들겟다 모르겠음. 
.then(()=>{
    console.log('db접속 성공')
})  
.catch(()=>{
    console.log('db접속 실패')
})

이 부분은 server접속 확인을 위한거라 삭제 ㄱㄱ

 

 

이제 select 해보기

const express = require('express');
const app = express();
const {sequelize}=require('./models') //index생략가능  //model의 index를 가져옴

const {User}=require('./models')



app.get('/',(req,res)=>{
    /* insert문
    User.create({   //User의 부모에 create를 가지고 있어서 사용 가능 
        name:'zero',
        age:24,
        married:false,
        comment:'자기소개1',
    })*/

    //Select 문
    console.log(User.findAll({}));



    res.send('hello world');
})

app.listen(3000,()=>{
    console.log('server start 3000')
})

-> server 키고 -> localhost:3000 하고 

console.log 결과 

결과 : promise 객체로 떨어짐. 

 

 

 

 

 

 

 

이번엔 async & await 적어서 console.log 해보기

const express = require('express');
const app = express();
const {sequelize}=require('./models') //index생략가능  //model의 index를 가져옴

const {User}=require('./models')



app.get('/', async (req,res)=>{ //요 익명함수를 async로 해놓고 
    /* insert문
    User.create({   //User의 부모에 create를 가지고 있어서 사용 가능 
        name:'zero',
        age:24,
        married:false,
        comment:'자기소개1',
    })*/

    //Select 문
    console.log(await User.findAll({}));



    res.send('hello world');
})

app.listen(3000,()=>{
    console.log('server start 3000')
})

 

 

 

 

이걸 변수로 담아보기 

 

const express = require('express');
const app = express();
const {sequelize}=require('./models') //index생략가능  //model의 index를 가져옴

const {User}=require('./models')



app.get('/', async (req,res)=>{ //요 익명함수를 async로 해놓고 
    /* insert문
    User.create({   //User의 부모에 create를 가지고 있어서 사용 가능 
        name:'zero',
        age:24,
        married:false,
        comment:'자기소개1',
    })*/

    //Select 문
    const userList=await User.findAll({});
    console.log(userList);
    
    res.send('hello world');
})

app.listen(3000,()=>{
    console.log('server start 3000')
})

결과물은 배열로 줌. 

User라는 객체에 dataValues가 있고 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

해당 결과의 배열 [0] 첫번째 객체의 name 값을 가져오기 

    console.log(userList[0].name);

 

 

 

User.findAll({}) -> 비동기이다. 를 알 수 있다. ( 결과치가 Promise 객체 값이기 때문) 

 

 

app.get('/', async (req,res)=>{ //요 익명함수를 async로 해놓고 
    /* insert문
    User.create({   //User의 부모에 create를 가지고 있어서 사용 가능 
        name:'zero',
        age:24,
        married:false,
        comment:'자기소개1',
    })*/

    //Select 문
    const userList=await User.findAll({});
    console.log(userList[0].name);                   //연습삼아 찍어봄
    
    res.send('hello world');
})

 

User.findAll({}) 은 Promise 객체로 반환한다 *** 

await 를 쓰려면 async 를 적어야함. User.findAll({}) 이 실해되기까지 기다리고 그 다음에 console.log가 실행되게 

 

 

 

 

name, married만 뽑아오기 

app.get('/', async (req,res)=>{ //요 익명함수를 async로 해놓고 
    /* insert문
    User.create({   //User의 부모에 create를 가지고 있어서 사용 가능 
        name:'zero',
        age:24,
        married:false,
        comment:'자기소개1',
    })*/

    //Select 문
    const userList=await User.findAll({
        attributes:['name','married']
    });
    
    console.log(userList);
    res.send('hello world');
})

 

 

이 외의 사용 스킬은 230-231p 책 보고 공부 

 

 

----------------------------------------------지금까지 Model 부분만 했음 --------------------------------------------------

View, Controller 

MVC 구조 할 수 있는걸 공부 

 

VIEW - nunjucks의 활용, nunjucks를 쓰면 MVC 패턴 중 View부분 

 

views 폴더, index.html 파일 추가 

nunjucks 추가 

const express = require('express');
const app = express();
const {sequelize}=require('./models') //index생략가능  //model의 index를 가져옴
const {User}=require('./models')
const nunjucks = require('nunjucks');

nunjucks.configure('views',{
    express:app,
})

app.set('view engine' , 'html');


app.get('/', async (req,res)=>{ //요 익명함수를 async로 해놓고 
    /* insert문
    User.create({   //User의 부모에 create를 가지고 있어서 사용 가능 
        name:'zero',
        age:24,
        married:false,
        comment:'자기소개1',
    })*/

    //Select 문
    const userList=await User.findAll({
        attributes:['name','married']
    });
    
    console.log(userList);
    res.send('hello world');
})

app.listen(3000,()=>{
    console.log('server start 3000')
})

 

 

 

 

 

 

 

controller data 조작 router를 통해 코드를 분류할 뿐 

 

routers 폴더 만들기, index.js 파일 추가 

app.js에

app.use('/',indexRouter); 추가 ,

 

index.js에 router 사용 위해 express, router 코드 작성

 

 

어떤 폴더에는 고 내용에 대한 작업만 router 관리 파일을 만들꺼야 

 

routers 폴더 안에 main 폴더 만들기 index.js 파일 만들기 

 

 

router - index.js

const express=require('express');
const router=express.Router();
const mainRouter=require('./main/index.js')

// router.use('/',(req,res)=>{})  // = > 예전에 했던 방법 

router.use('/',mainRouter);

module.exports=router; // router 보낼꺼야 저 멀리

router- main - index.js

const express=require('express');
const router = express.Router();

router.get('/', (req,res)=>{
    res.render('index.html')
});


module.exports=router;

app.js

const express = require('express');
const app = express();
const {sequelize}=require('./models') //index생략가능  //model의 index를 가져옴
const {User}=require('./models')
const nunjucks = require('nunjucks');
const indexRouter = require('./routers')

nunjucks.configure('views',{
    express:app,
})

app.set('view engine' , 'html');

app.use('/', indexRouter);

/*
app.get('/', async (req,res)=>{ //요 익명함수를 async로 해놓고 
    //insert문
    User.create({   //User의 부모에 create를 가지고 있어서 사용 가능 
        name:'zero',
        age:24,
        married:false,
        comment:'자기소개1',
    })

    //Select 문
    const userList=await User.findAll({
        attributes:['name','married']
    });
    
    console.log(userList);
    res.send('hello world');
})*/

app.listen(3000,()=>{
    console.log('server start 3000')
})

 

 

 

 

헷갈리는 파일들.................

 

 

 

 

 

 

 

여기까지 따라 쓰긴했는데 사실 잘 모르겠다

내일 쉬는 날이니까 열공해야겟다.. 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

이제 business logic controller 부분을 또 나눌꺼야

 

routers - main - index

const express=require('express');
const router = express.Router();
const controller = require('./main.controller')

router.get('/',);


module.exports=router;

 

 

 

 

main 폴더에 main.controller.js 파일 만들기

 

main.controller.js

let main = (req,res)=>{
    res.render('index.html');
}

exports.main=main; 
//   보낼 명 , 보낼 함수 

 

 

 

 

----------------> 여기까지 하면 db control 하는게 쉬워짐 

 

 

main.controller.js 

const {User} = require('../../models');

//비동기니깐 async await 쓰기 
let main = async (req,res)=>{
    let user = await User.findAll({})
    console.log(user)
    res.render('index.html');
}

exports.main=main; 
//   보낼 명 , 보낼 함수 

요렇게 적고 log 확인 

 

 

 

하나만 사용해서는 왜 파일만 여러개 만드나 불편함 

 

게시판 기준으로 파일 나누기 

 

 

 

routers-> index.js  추가 

const express=require('express');
const router=express.Router();
const mainRouter=require('./main/index');
const boardRouter=require('./board/index');



// router.use('/',(req,res)=>{})  // = > 예전에 했던 방법 

router.use('/',mainRouter);
router.use('/board', boardRouter)

module.exports=router; // router 보낼꺼야 저 멀리

 

router안에 board 폴더 - 그 안에 index.js 파일 만들기 

 

const express=require('express');
const router=express.Router();
const controller = require('./board.controller');


router.get('/list', controller.list);
router.get('/view', controller.view);
router.get('/write', controller.write);
router.get('/modify', controller.modify);


//routers-index에서 가져올 수 있게

module.exports = router; 


/board/view 

일때 실행되는 거 ! 

 

 

 

 

 

routers - board 폴더 안 새 파일 board.controller.js  만들기

let list = (req,res)=>{
    res.render('list.html')
}

let view = (req,res)=>{
    res.render('view.html')
}

let write = (req,res)=>{
    res.render('write.html')
}

let modify = (req,res)=>{
    res.render('modify.html')
}

module.exports={
    list:list,
    view:view,
    modify:modify,  //modify 라는 속성값을 modify 라는 method로 
    write:write
}

 

 

 

 

 

 

 

-> 이제 views 폴더 안에 list, ... 만들기 

 

 

 

전체적인 흐름 

 

 

 

 

 

routers-board-board.controller.js ㅇㅔ 이제 async, await 적용 

const {User} = require('../../models')
//요걸 가져오면 



let list = async (req,res)=>{
    //select 
    let UserList = await User.findAll({})
    res.render('list.html')
}

let view = (req,res)=>{
    //select
    let UserList = await User.findAll({})
    res.render('view.html')
}

//board/write POST 
let write = (req,res)=>{
    //insert
    let rst = await User.create({
        //....req 요청값에 나왔던 부분을 넣어주면 됨
    })
    res.render('write.html')
}

let modify = (req,res)=>{
    //update
    let rst = await User.update({
        //필드 : '바뀔내용'..
    },{
        where: { //필드:값}                   이런 nunjucks의 결과를 떤져주면됨
    })
    res.render('modify.html')
}

module.exports={
    list:list,
    view:view,
    modify:modify,  //modify 라는 속성값을 modify 라는 method로 
    write:write
}

 

 

 

 

 

 

 

 

 

 

 

Controllers - model에서 받은 걸 조작해서 -> VIew로 보냄 (Model & View를 연결하는 곳) 

 

 

Model  - 데이터를 받고 저장 (DB에 있던 내용, 내가 사용할 DB를 객체로 저장하는 곳) 

데이터를 저장한 객체 - 그 데이터만으로 모든걸 표현할 수 없다. 게시판의 paging etc.  ->controllers 가 필요한 로직을 추가해서 View로 보낸다. 

 

View - 화면에 뿌려주는 (실질적으로 Client가 보는 쪽) 

 

최소한의 코드들만 따로 뽑아서 business logic 만 처리할 수 있게 만든게 Controller

 

 

* 팁 뭔가 데이터가 잘못된거같애 -> model 쪽 췤

뭔가 화면이 이상해 -> view 췤

paging이 이상해 -> controller 췤 

 

 

내일 쉬는날 푹 쉬라고 숙제를 안내주셨다. 

이제 숙제같은 복습이 남았다..  

 

 

 

반응형