🎇🎇🎇С Новым годом🎇🎇🎇
2020 Крыса, ты самый красивый, Крыса ты самая сильная, Ты лучшая мышка, Крыса ты самая рыжая, Ты самая красивая мышка, благоприятный год крысы
вопросы и ответы
❓: Чему вы можете научиться?
🙋: Использование секвенсора-кли и основных операций секвенсора.
❓:Зачем использовать sequenceize-cli?
🙋: Точно так же, как вы используете Git/SVN для управления изменениями исходного кода, вы можете использовать миграции для отслеживания изменений в базе данных.
❓: Почему бы не разработать модель данных, а затем продемонстрировать ее?
🙋: Эта статья о процессе разработки с использованием sequenceize-cli и sequenceize.
❓: Откуда столько кодов?
🙋: Я разместил код каждого шага, если вы следите за процессом, вы можете быстро выполнить пример. Видеть значит верить, я считаю, что так лучше учиться.
❓: Почему нет точек знаний, таких как транзакции, области действия и типы данных?
🙋: Это вводное руководство, но после его изучения становится легче понять транзакции и области действия.
❓: Почему нет исходного кода?
🙋: Лучше один раз сделать, чем один раз посмотреть.
Готов к работе
1. Инициализировать проект
cd 工程目录
npm init -y
2. Установите модуль
npm i koa koa-body koa-router mysql2 sequelize sequelize-cli -S
3. Добавьте файл server.js
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...')
});
Быстрый старт
1. Создайте новый файл .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') //迁移文件
}
2. Инициализация
npx sequelize-cli init
3. Отредактируйте ./db/config.js
"development": {
"username": "username",
"password": "password",
"database": "school", //数据库名称
"host": "127.0.0.1",
"dialect": "mysql",
"timezone": "+08:00" //设置时区为'东八区'
}
4. Создайте базу данных
npx sequelize-cli db:create
5. СгенерироватьstudentФайлы модели и файлы миграции
npx sequelize-cli model:generate --name student --attributes student_name:string,student_age:integer,student_sex:boolean
6. Отредактируйте ./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 являются студенты. Это связано с тем, что sequenceize по умолчанию преобразует имя таблицы во множественное число. Здесь я изменю его на student, а все последующие имена таблиц или имена моделей будут использовать форму единственного числа.
7. Сгенерированное имяstudentтехническая спецификация
npx sequelize-cli db:migrate
8. Генерацияstudentначальный файл таблицы
npx sequelize-cli seed:generate --name init-student
9. Отредактируйте файл ./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, {});
}
};
10.studentданные инициализации таблицы
npx sequelize-cli db:seed:all
11. Отредактируйте .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;
};
12. Отредактируйте файл 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 } });
});
.....
13. Запустите службу и протестируйте ее с помощью Postman.
node server.js
подключение модели
hasMany (один ко многим)
В классе может быть несколько учеников, и отношения между классом и ученикамиодин ко многим. Чтобы завершить этот пример, мы сделаем следующее:
- Создайте таблицу классов с именем _class
- _class данные инициализации таблицы классов
- Таблица учеников добавляет столбец с именем class_id.
- Повторно инициализировать данные таблицы учащихся
- Запросить всех учащихся в классе
Давайте начнем!
1. Создайте модель **_class** и файл миграции.
npx sequelize-cli model:generate --name _class --attributes class_name:string
2. Измените ./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');
}
};
3. Создайте таблицу **_class**
npx sequelize-cli db:migrate
4. Создайте начальный файл таблицы **_class**
npx sequelize-cli seed:generate --name init-class
5. Отредактируйте ./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, {});
}
};
6._classданные инициализации таблицы
npx sequelize-cli db:seed --seed xxxxx-init-class.js
7. Создайте файл миграции, который изменяет таблицу studnet.
npx sequelize-cli migration:generate --name add-column-class_id-to-student.js
8. Отредактируйте ./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', {});
}
};
9. Изменитьstudentповерхность
npx sequelize-cli db:migrate
10. Регенерироватьstudentначальный файл таблицы
npx sequelize-cli seed:generate --name init-student-after-add-column-class_id
11. Отредактируйте файл ./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, {});
}
};
12. ОтменаstudentДанные уже в таблице
npx sequelize-cli db:seed:undo --seed xxxxx-init-student.js
13.stuentтаблица повторно инициализирует данные
npx sequelize-cli db:seed --seed xxxxx-init-student-after-add-column-class_id.js
14. Отредактируйте файл ./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;
};
15. Отредактируйте server.js
...
const Class = require('./db/models')._class;
//获取班级信息以及班级里的所有学生
router.get('/classes', async ctx => {
//获取所有班级以及学生信息
ctx.body = await Class.findAll({ include: [Student] });
});
...
принадлежит (один к одному)
Ученик может принадлежать только к одному классу, поэтому отношения между учеником и классомодин на один.
1. Измените файл ./db/models/student.js.
...
student.associate = function(models) {
student.belongsTo(models._class); //一对一
};
...
2. Измените интерфейс получения списка учеников в server.js.
...
//获取学生列表
router.get('/students', async ctx => {
ctx.body = await Student.findAll({ include: [Class] });
});
...
belongsTo VS hasOne
student.belongsTo(models._class), где студент называетсяисходная модель, _class называетсяцелевая модель.
Таблица Student содержит внешний ключ class_id таблицы _class, что означает, что внешний ключ находится висходная модельвыше, поэтому мы используемbelongsToдля создания ассоциации.
hasOneиbelongsToиспользуются для созданияодин на одинАссоциативный, правильный способ их использования — посмотреть, в какой модели находится внешний ключ.
- Принадлежит к внешнему ключу ассоциации в исходной модели
- Внешний ключ ассоциации hasOne для целевой модели
принадлежитToMany (многие ко многим)
В классе может быть несколько замещающих учителей, и замещающий учитель может брать уроки у нескольких классов. Отношения между классом и учителеммногие ко многимЧтобы завершить демонстрацию этой функциональности, мы сделаем следующее:
- создать имя
Давайте начнем!
1. СгенерироватьteacherФайлы модели и миграции
npx sequelize-cli model:generate --name teacher --attributes teacher_name:string
2. Измените ./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');
}
};
3. Сгенерироватьteacherповерхность
npx sequelize-cli db:migrate
4. Сгенерироватьteacherначальный файл таблицы
npx sequelize-cli seed:generate --name init-teacher
5. Отредактируйте ./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, {});
}
};
6.teacherданные инициализации таблицы
npx sequelize-cli db:seed --seed xxxxx-init-teacher.js
7. Генерацияteacher_classФайлы модели и миграции
npx sequelize-cli model:generate --name teacher_class --attributes teacher_id:integer,class_id:integer
8. Отредактируйте ./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');
}
};
9. Генерацияteacher_classповерхность
npx sequelize-cli db:migrate
10. Сгенерироватьteacher_classначальный файл таблицы
npx sequelize-cli seed:generate --name init-teacher_class
11. Отредактируйте ./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, {});
}
};
12.teacher_classданные инициализации таблицы
npx sequelize-cli db:seed --seed xxxxx-init-teacher_class.js
13. Отредактируйте ./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;
};
14. Отредактируйте ./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;
};
15. Отредактируйте server.js
const Teacher = require('./db/models').teacher;
//获取老师信息以及老师所带的班级
router.get('/teachers', async ctx => {
//获取所有班级以及学生信息
ctx.body = await Teacher.findAll({ include: [Class] });
})
Запрос
Базовый запрос
1. Вернуть указанный столбец
Student.findAll({
attributes: ['id', 'student_name']
});
// select id,student_name from student
2. Запрос с одним условием
Student.findAll({
where: {
id: 1
}
})
// select * from student where id = 1
3. И
//返回id为1,姓名是`孙悟空`的学生信息
Student.findAll({
where: {
id: 4,
student_name:'孙悟空'
}
})
// select * from student where id = 1 and student_name = '孙悟空'
4. ИЛИ
//返回年龄等于12或者22的学生信息
Student.findAll({
where: {
student_age: {
[Op.or]: [12, 22]
}
}
})
// select * from student where studnet_age = 12 or studnet_age = 22
5. Условный запрос - >,>=,
// 返回年龄大于等于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
6. В
// 返回年龄是16和18的学生信息
Student.findAll({
where: {
student_age: {
[Op.in]: [16,18]
}
}
})
// select * from student where studnet_age in (16,18)
7. НРАВИТСЯ
// 返回名称包含'孙'的学生信息
Student.findAll({
where: {
student_name: {
[Op.like]: '%孙%',
}
}
})
// select * from student where studnet_name like '%孙%'
Агрегатная функция
1. Получите средний возраст учащихся
Student.findAll({
attributes: [[sequelize.fn('AVG', sequelize.col('student_age')), 'avg']]
})
2. Получите общее количество студентов
Student.findAll({
attributes: [[sequelize.fn('COUNT', sequelize.col('id')), 'count']]
})
вложенный запрос
1. Соберите всех учеников в классе и отсортируйте их в порядке убывания по возрасту.
Class.findAll({
include: [{model: Student}],
where:{id:1},
order:[[Student,'student_age', 'DESC']]
});