2020 鼠你最帥, 鼠你最強, 鼠你最棒, 鼠你最紅, 鼠你最美, 鼠年吉祥node
❓:你能學到什麼?
🙋:sequelize-cli的使用以及sequelize的基礎操做。mysql
❓:爲何要使用sequelize-cli?
🙋:就像你使用Git/SVN來管理源代碼的更改同樣,你可使用遷移來跟蹤數據庫的更改。git
❓:爲何不將數據模型設計好再演示?
🙋:本文講的是使用sequelize-cli和sequelize開發的過程。github
❓:怎麼會有這麼多的代碼?
🙋:每一步的代碼我都貼了出來,只要按照流程作就能快速的完成一個示例。眼見爲實,我相信這樣學習的效果更好。sql
❓:怎麼沒有事務、做用域、數據類型等知識點?
🙋:這篇是入門教程,不過學會了這篇,事務、做用域理解起來更容易。數據庫
❓:爲何沒有源代碼?
🙋:作一遍必定比看一遍的效果好。npm
一、初始化項目json
cd 工程目錄
npm init -y
複製代碼
二、安裝模塊bash
npm i koa koa-body koa-router mysql2 sequelize sequelize-cli -S
複製代碼
三、添加server.js文件app
const Koa = require('koa');
const router = require('koa-router')();
const koaBody = require('koa-body');
const app = new Koa();
app.use(koaBody());
app.use(router.routes())
.use(router.allowedMethods('*'));
app.listen(3000, () => {
console.log('server is listening on 3000...')
});
複製代碼
一、新建.sequelizerc文件
const path = require('path');
module.exports = {
'config': path.resolve('config', 'config.json'), //數據庫鏈接配置文件
'models-path': path.resolve('db', 'models'), //模型文件
'seeders-path': path.resolve('db', 'seeders'), //種子文件
'migrations-path': path.resolve('db', 'migrations') //遷移文件
}
複製代碼
二、初始化
npx sequelize-cli init
複製代碼
三、編輯./db/config.js
"development": {
"username": "username",
"password": "password",
"database": "school", //數據庫名稱
"host": "127.0.0.1",
"dialect": "mysql",
"timezone": "+08:00" //設置時區爲'東八區'
}
複製代碼
四、建立數據庫
npx sequelize-cli db:create
複製代碼
五、生成student模型文件以及遷移文件
npx sequelize-cli model:generate --name student --attributes student_name:string,student_age:integer,student_sex:boolean
複製代碼
六、編輯./db/migrations/xxxxx-create-student.js
'use strict';
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.createTable('student', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
student_name: {
type: Sequelize.STRING(10),
allowNull:false
},
student_age: {
type: Sequelize.INTEGER,
allowNull:false
},
student_sex: {
type: Sequelize.BOOLEAN,
allowNull:false
}
});
},
down: (queryInterface, Sequelize) => {
return queryInterface.dropTable('student');
}
};
複製代碼
打開xxxxx-create-student.你會發現createTable方法的第一個參數爲students,這是因爲sequelize會默認將表名稱轉換爲複數形式,這裏我將其修改成student,後面全部表名或模型名稱都會使用單數形式。
七、生成名稱爲student的數據表
npx sequelize-cli db:migrate
複製代碼
八、生成student表種子文件
npx sequelize-cli seed:generate --name init-student
複製代碼
九、編輯./db/seeders/xxxxx-init-student.js文件
'use strict';
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.bulkInsert('student', [{
student_name: '孫悟空',
student_age: 20,
student_sex: 1
},{
student_name: '白骨精',
student_age: 18,
student_sex: 0
},{
student_name: '豬八戒',
student_age: 16,
student_sex: 1
}])
},
down: (queryInterface, Sequelize) => {
return queryInterface.bulkDelete('student', null, {});
}
};
複製代碼
十、student表初始化數據
npx sequelize-cli db:seed:all
複製代碼
十一、編輯.db/models/student.js
'use strict';
module.exports = (sequelize, DataTypes) => {
const student = sequelize.define('student', {
student_name: DataTypes.STRING,
student_age: DataTypes.INTEGER,
student_sex: DataTypes.BOOLEAN,
class_id:DataTypes.INTEGER
}, {
timestamps: false,//不自動添加時間字段(updatedAt,createdAt)
freezeTableName: true,// 使用模型名稱的單數形式
underscored: true //列名添加下劃線
});
student.associate = function(models) {};
return student;
};
複製代碼
十二、編輯server.js文件
.....
const Student = require('./db/models').student;
//添加學生信息
router.post('/student', async ctx => {
ctx.body = await Student.create(ctx.request.body);
});
//更新學生信息
router.put('/student', async ctx => {
const { id } = ctx.request.body;
ctx.body = await Student.update(ctx.request.body, { where: { id } });
});
//獲取學生列表
router.get('/students', async ctx => {
ctx.body = await Student.findAll();
});
//根據id刪除學生信息
router.delete('/student/:id', async ctx => {
const { id } = ctx.params;
ctx.body = await Student.destroy({ where: { id } });
});
.....
複製代碼
1三、啓動服務並使用Postman測試
node server.js
複製代碼
一個班級裏面能夠有多個學生,班級與學生的關係就是一對多。爲了完成這個例子咱們會作如下幾件事情:
讓咱們開始吧!
一、生成**_class**模型以及遷移文件
npx sequelize-cli model:generate --name _class --attributes class_name:string
複製代碼
二、修改./db/migrations/xxxxx-create-class.js
'use strict';
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.createTable('_class', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
class_name: {
type: Sequelize.STRING(10),
allowNull:false
}
});
},
down: (queryInterface, Sequelize) => {
return queryInterface.dropTable('_class');
}
};
複製代碼
三、生成**_class**表
npx sequelize-cli db:migrate
複製代碼
四、生成**_class**表種子文件
npx sequelize-cli seed:generate --name init-class
複製代碼
五、編輯./db/seeders/xxxxx-init-class.js
'use strict';
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.bulkInsert('_class', [{
class_name: '一班'
}, {
class_name: '二班'
}, {
class_name: '三班'
}]);
},
down: (queryInterface, Sequelize) => {
return queryInterface.bulkDelete('_class', null, {});
}
};
複製代碼
六、_class表初始化數據
npx sequelize-cli db:seed --seed xxxxx-init-class.js
複製代碼
七、生成修改studnet表的遷移文件
npx sequelize-cli migration:generate --name add-column-class_id-to-student.js
複製代碼
八、編輯./db/migrations/xxxxx-add-column-class_id-to-student.js
'use strict';
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.addColumn('student', 'class_id', {
type: Sequelize.INTEGER,
allowNull:false
})
},
down: (queryInterface, Sequelize) => {
queryInterface.removeColumn('student', 'class_id', {});
}
};
複製代碼
九、修改student表
npx sequelize-cli db:migrate
複製代碼
十、從新生成student表種子文件
npx sequelize-cli seed:generate --name init-student-after-add-column-class_id
複製代碼
十一、編輯./db/seeders/xxxxx-init-student-after-add-column-class_id.js文件
'use strict';
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.bulkInsert('student', [{
student_name: '孫悟空',
student_age: 20,
student_sex: 1,
class_id: 1
}, {
student_name: '白骨精',
student_age: 18,
student_sex: 0,
class_id: 1
}, {
student_name: '豬八戒',
student_age: 16,
student_sex: 1,
class_id: 2
}, {
student_name: '唐僧',
student_age: 22,
student_sex: 1,
class_id: 1
}, {
student_name: '沙和尚',
student_age: 25,
student_sex: 1,
class_id: 1
}, {
student_name: '紅孩兒',
student_age: 13,
student_sex: 1,
class_id: 2
}, {
student_name: '黑熊怪',
student_age: 26,
student_sex: 1,
class_id: 2
}, {
student_name: '太白金星',
student_age: 66,
student_sex: 1,
class_id: 3
}, {
student_name: '嫦娥',
student_age: 18,
student_sex: 0,
class_id: 3
}])
},
down: (queryInterface, Sequelize) => {
return queryInterface.bulkDelete('student', null, {});
}
};
複製代碼
十二、撤銷student表中已有的數據
npx sequelize-cli db:seed:undo --seed xxxxx-init-student.js
複製代碼
1三、stuent表從新初始化數據
npx sequelize-cli db:seed --seed xxxxx-init-student-after-add-column-class_id.js
複製代碼
1四、編輯./db/models/_class.js文件
'use strict';
module.exports = (sequelize, DataTypes) => {
const _class = sequelize.define('_class', {
class_name: DataTypes.STRING
}, {
timestamps: false,
freezeTableName: true,
underscored: true
});
_class.associate = function (models) {
_class.hasMany(models.student);
};
return _class;
};
複製代碼
1五、編輯server.js
...
const Class = require('./db/models')._class;
//獲取班級信息以及班級裏的全部學生
router.get('/classes', async ctx => {
//獲取全部班級以及學生信息
ctx.body = await Class.findAll({ include: [Student] });
});
...
複製代碼
一個學生只能屬於一個班級,因此學生和班級的關係是一對一。
一、修改./db/models/student.js文件
...
student.associate = function(models) {
student.belongsTo(models._class); //一對一
};
...
複製代碼
二、修改server.js中獲取學生列表的接口
...
//獲取學生列表
router.get('/students', async ctx => {
ctx.body = await Student.findAll({ include: [Class] });
});
...
複製代碼
student.belongsTo(models._class)這裏student叫作源模型,_class叫作目標模型。
student表中包含了_class表的外鍵class_id,也就是說外鍵在源模型上面因此咱們使用belongsTo來建立關聯。
hasOne和belongsTo都是用來建立一對一關聯的,正確使用它們的方法就是看外鍵在哪一個模型中。
一個班級能夠有多名代課老師,一名代課老師能夠帶多個班級的課程。班級與老師的關係是多對多 爲了完成此功能的演示,咱們將作如下工做:
讓咱們開始吧!
一、生成teacher模型以及遷移文件
npx sequelize-cli model:generate --name teacher --attributes teacher_name:string
複製代碼
二、修改./db/migrations/xxxxx-teacher-class.js
'use strict';
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.createTable('teacher', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
teacher_name: {
type: Sequelize.STRING(10),
allowNull: false
}
});
},
down: (queryInterface, Sequelize) => {
return queryInterface.dropTable('teacher');
}
};
複製代碼
三、生成teacher表
npx sequelize-cli db:migrate
複製代碼
四、生成teacher表種子文件
npx sequelize-cli seed:generate --name init-teacher
複製代碼
五、編輯./db/seeders/xxxxx-init-teacher.js
'use strict';
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.bulkInsert('teacher', [{
teacher_name: '李老師'
}, {
teacher_name: '張老師'
}]);
},
down: (queryInterface, Sequelize) => {
return queryInterface.bulkDelete('teacher', null, {});
}
};
複製代碼
六、teacher表初始化數據
npx sequelize-cli db:seed --seed xxxxx-init-teacher.js
複製代碼
七、生成teacher_class模型以及遷移文件
npx sequelize-cli model:generate --name teacher_class --attributes teacher_id:integer,class_id:integer
複製代碼
八、編輯./db/migrations/xxxxx-create-teacher-class.js
'use strict';
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.createTable('teacher_class', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
teacher_id: {
type: Sequelize.INTEGER,
allowNull: false,
},
class_id: {
type: Sequelize.INTEGER,
allowNull: false,
}
});
},
down: (queryInterface, Sequelize) => {
return queryInterface.dropTable('teacher_class');
}
};
複製代碼
九、生成teacher_class表
npx sequelize-cli db:migrate
複製代碼
十、生成teacher_class表種子文件
npx sequelize-cli seed:generate --name init-teacher_class
複製代碼
十一、編輯./db/seeders/xxxxx-init-teacher_class.js
'use strict';
/* 李老師帶的班級爲一班和二班。張老師帶的班級爲三班 */
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.bulkInsert('teacher_class', [{
class_id: 1,
teacher_id: 1
}, {
class_id: 2,
teacher_id: 1
}, {
class_id: 3,
teacher_id: 2
}]);
},
down: (queryInterface, Sequelize) => {
return queryInterface.bulkDelete('teacher_class', null, {});
}
};
複製代碼
十二、teacher_class表初始化數據
npx sequelize-cli db:seed --seed xxxxx-init-teacher_class.js
複製代碼
1三、編輯./db/models/teacher.js
'use strict';
module.exports = (sequelize, DataTypes) => {
const teacher = sequelize.define('teacher', {
teacher_name: DataTypes.STRING
}, {
timestamps: false,
freezeTableName: true,
underscored: true
});
teacher.associate = function (models) {
teacher.belongsToMany(models._class, {
through: models.teacher_class,
foreignKey: 'teacher_id',
});
};
return teacher;
};
複製代碼
1四、編輯./db/models/_class.js
'use strict';
module.exports = (sequelize, DataTypes) => {
const _class = sequelize.define('_class', {
class_name: DataTypes.STRING
}, {
timestamps: false,
freezeTableName: true,
underscored: true
});
_class.associate = function (models) {
_class.hasMany(models.student);
_class.belongsToMany(models.teacher, {
through: models.teacher_class,
foreignKey: 'class_id',
});
};
return _class;
};
複製代碼
1五、編輯server.js
const Teacher = require('./db/models').teacher;
//獲取老師信息以及老師所帶的班級
router.get('/teachers', async ctx => {
//獲取全部班級以及學生信息
ctx.body = await Teacher.findAll({ include: [Class] });
})
複製代碼
一、返回指定列
Student.findAll({
attributes: ['id', 'student_name']
});
// select id,student_name from student
複製代碼
二、單條件查詢
Student.findAll({
where: {
id: 1
}
})
// select * from student where id = 1
複製代碼
三、AND
//返回id爲1,姓名是`孫悟空`的學生信息
Student.findAll({
where: {
id: 4,
student_name:'孫悟空'
}
})
// select * from student where id = 1 and student_name = '孫悟空'
複製代碼
四、OR
//返回年齡等於12或者22的學生信息
Student.findAll({
where: {
student_age: {
[Op.or]: [12, 22]
}
}
})
// select * from student where studnet_age = 12 or studnet_age = 22
複製代碼
五、條件查詢- >,>=,<,<=,=
// 返回年齡大於等於20的學生
Student.findAll({
where: {
student_age: {
[Op.gte]: 20
}
}
})
// select * from student where studnet_age >= 20
複製代碼
[Op.gt]: 6 //大於6
[Op.gte]: 6 //大於等於6
[Op.lt]: 10 //小於10
[Op.lte]: 10 //小於等於10
[Op.ne]: 20 //不等於20
[Op.eq]: 3 //等於3
複製代碼
六、IN
// 返回年齡是16和18的學生信息
Student.findAll({
where: {
student_age: {
[Op.in]: [16,18]
}
}
})
// select * from student where studnet_age in (16,18)
複製代碼
七、LIKE
// 返回名稱包含'孫'的學生信息
Student.findAll({
where: {
student_name: {
[Op.like]: '%孫%',
}
}
})
// select * from student where studnet_name like '%孫%'
複製代碼
一、獲取學生的平均年齡
Student.findAll({
attributes: [[sequelize.fn('AVG', sequelize.col('student_age')), 'avg']]
})
複製代碼
二、獲取學生總數
Student.findAll({
attributes: [[sequelize.fn('COUNT', sequelize.col('id')), 'count']]
})
複製代碼
一、獲取一班全部的學生並根據年齡降序排列
Class.findAll({
include: [{model: Student}],
where:{id:1},
order:[[Student,'student_age', 'DESC']]
});
複製代碼