ORM(Object Relational Mapping,对象关系映射
),是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术,通过描述对象和数据库之间映射的元数据,把程序中的对象自动持久化到关系数据库中。它的作用是在关系型数据库和对象之间作一个映射,这样,我们在具体的操作数据库的时候,就不需要再去和复杂的SQL语句打交道,只要像平时操作对象一样操作它就可以了 。
持久(Persistence)化,即把数据(如内存中的对象)保存到可永久保存
的存储设备中(如磁盘)。持久化的主要应用是将内存中的数据存储在关系型的数据库中,当然也可以存储在磁盘文件中、XML数据文件中等等。
ORM就是把业务实体中的对象与关系数据库中的关系数据关联起来。
类<—>表
属性<—>列
对象<—>行
对象-关系映射(ORM)系统一般以中间件
的形式存在。
ORM技术特点:
1、提高了开发效率。ORM可以自动对Entity对象与数据库中的Table进行字段与属性的映射,所以我们实际可能已经不需要一个专用的、庞大的数据访问层,即开发者不用在面向对象和关系型数据库之间进行来回的切换。
2、ORM提供了对数据库的映射,不用sql直接编码,能够像操作对象一样从数据库获取数据。
我们在info数据库中有一个表db_employee,数据如下:
Node中通过Sequelize模块来实现ORM映射。
Sequelize模块是基于promise的关系型数据库ORM框架
,这个库完全采用JavaScript开发并且能够用在Node.JS环境中,易于使用,支持多SQL方言(dialect),。它当前支持MySQL、MariaDB、SQLite、PostgreSQL、Sql Server 数据库。
特点:
①强大的模型定义,支持虚拟类型。
②支持完善的数据验证,减轻前后端的验证压力。
③Sequelize的查询非常全面和灵活
①安装MySQL2:npm install mysql2
②安装Sequelize:npm i sequelize
首先我们创建express项目,然后安装上述模块,再新建文件夹db,db里新建配置文件夹config,模型文件夹model,在db里创建mydb.js,对sequelize模块进行配置:
//导入sequelize模块
const Sequelize = require('sequelize');
//配置数据库连接对象(默认带有数据库连接池):数据库名、用户名、密码、配置对象
const sequelize = new Sequelize('info','root','iampwd',{
host: 'localhost',
port: 3306,
dialect: 'mysql', //数据库类型
//数据库连接池
pool:{
max: 5,//连接池中最大连接数量
min: 0,//连接池中最小连接数量
idle: 10000 //若某个线程10秒没有使用,就释放
},
debug: true //显示调试信息
})
module.exports = sequelize;
模型是Sequelize的本质,模型是表示数据库中一个表的抽象
,在Sequelize中,它是一个扩展Model的类,通常一个表对应一个模型。
该模型告诉Sequelize它所表示的实体的一些信息,例如数据库中表的名称以及它拥有哪些列(以及它们的数据类型)。
Sequelize中的模型有一个名字。这个名称不必与它在数据库中表示的表的名称相同。通常,模型具有单数名称(如User),而表具有复数名称(如Users)。
在Sequelize中,模型可以用两种等价的方式定义,我们今天主要学习第一种方法定义模型
sequelize.define(modelName, attributes, options)
在model文件夹下创建employeeModel.js文件:
const Sequelize = require('sequelize');
//导入配置文件
const db = require('../config/mydb');
const Employee = db.define('db_employee',{
id:{ //属性名可以和列名相同,也可以不同
type: Sequelize.INTEGER, //属性的数据类型,对应的是列的数据类型
primaryKey: true, //表示该属性对应的是表的主键列
autoIncrement: true, //设置为自增
field: 'empid' //映射列名
},
name: {
type: Sequelize.STRING(30),
allowNull: false, //表示不允许为空
field: 'empname'
},
gender: {
type: Sequelize.STRING(4),
allowNull: false
},
birthday: {
type: Sequelize.DATE,
allowNull: false
},
phone: {
type: Sequelize.STRING(13),
allowNull: false
},
address: {
type: Sequelize.STRING(100),
allowNull: false
}
},{
freezeTableName: true, //映射表名的设置:true表示使用用户给定的表名,false表示MySQL自动生成表名(为类名后加s)
timestamps: false //是否自动生成时间戳列(createAt列、updateAt列),false表示不生成
});
module.exports = Employee;
注意定义模型时:
(1)类名和表名的映射:可以同名
(2)类的属性和表的列的映射:
A、属性名和列名相同:不需要指定列名,自动将属性名映射为列名
B、属性名和列名不相同:要在映射时通过fields来指定列名
在路由文件夹routes下创建ormtest.js文件,创建路由器,进行各种操作。
在入口文件app.js中导入路由文件并注册路由。
const express = require('express');
const EmployeeModel = require('../db/model/employeeModel');
const router = express.Router();
/*
查询所有:http://localhost:3000/emp/all
*/
router.get('/all',(req, res) => {
EmployeeModel.findAll({
raw: false //不显示时间戳列
}).then((results)=>{
res.send(results);
})
})
module.exports = router;
const express = require('express');
const EmployeeModel = require('../db/model/employeeModel');
const router = express.Router();
/*
删除记录:http://localhost:3000/emp/remove
*/
router.delete('/remove',(req, res) => {
let eid = req.body.empid
EmployeeModel.destroy({
where: { //相当于sql语句中的where子句
id: eid
}
}).then((result)=>{
res.send({
code: result,
msg: '删除成功'
})
}).catch((err)=>{
console.log(err)
res.send({
code: 1000,
msg: '删除失败'
})
})
})
module.exports = router;
const express = require('express');
const EmployeeModel = require('../db/model/employeeModel');
const router = express.Router();
/*
插入数据:http://localhost:3000/emp/insert
*/
router.post('/insert',(req, res) => {
//1.获取参数
let eid = req.body.emp_id;
let ename = req.body.emp_name;
let egender = req.body.emp_gender;
let ebirthday = req.body.emp_birthday;
let ephone = req.body.emp_phone;
let eaddress = req.body.emp_address
//2.调用create方法插入数据
EmployeeModel.create({
id:eid,
name: ename,
gender: egender,
birthday: ebirthday,
phone: ephone,
address: eaddress
}).then((result)=>{
res.send({
code: result,
msg: '插入成功'
})
}).catch(err=>{
console.log(err)
res.send({
code: 1000,
msg: '插入失败'
})
})
})
module.exports = router;
const express = require('express');
const EmployeeModel = require('../db/model/employeeModel');
const router = express.Router();
/*
更新记录:http://localhost:3000/emp/update
*/
router.put('/update',(req, res) => {
let eid = req.body.emp_id;
let ename = req.body.emp_name;
let ebirthday = req.body.emp_birthday;
let eaddress = req.body.emp_address;
//先使用findOne找到需要更新的记录
EmployeeModel.findOne({
where: {
id: eid
}
}).then((emp)=>{ //emp为通过id找到的记录
emp.update({ //调用update完成更新
name: ename,
birthday: ebirthday,
address: eaddress
}).then((result)=>{
res.send({
code: result,
msg: '更新成功'
})
}).catch(err=>{
console.log(err)
res.send({
code: 1000,
msg: '更新失败'
})
})
}).catch(err=>{
console.log(err)
res.send({
code: 1000,
msg: '查无此人'
})
})
})
module.exports = router;