ORM :对象关系映射(英语:Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),用于实现面向对象编程语言里不同类型系统的数据之间的转换。
O(面向对象) <-----> ORMapping <-----> R(面向关系)
在数据库层面, 尤其是关系型数据库. 是没有对象概念的.
有的只是表格, 和数据记录
想象一下, 如果你在某个视频网站, 为某个视频写了一条评论
接下来会发生什么呢?
我们要更改用户表的记录, 增加评论数
用SQL语句进行操作
update t_user set .......
可是我们平时都是面向对象编程的
从逻辑上讲
我们的代码应该是这样写的
video.cmmt_cnt++;
这样就够了吗? 当然不够
我们还需要增加评论表
还不止这些
如果这条评论被置顶了呢
如果这条评论对其他人不可见呢?
如果这条评论@了其他人呢
如果这条评论被人点赞了呢
只要稍微增加一点功能, 逻辑都会变得复杂很多
一个看似简单的添加评论, 其实背后并不简单
显然操作数据库, 跟实现业务逻辑采用的思维方式是不同的
一个是面向关系, 处理好每张表的变化, 以及表之间的关联
一个是面向对象思维, 将每一条记录看做一个对象去操作
在没有ORMapping之前, 程序员必须要自己搞定这二者复杂的关系转换
而有了ORMapping框架之后
程序员的代码, 大概就会变成这样
video.addComment(new Comment(......));
这样就够了, 面向对象的代码, 将自动转换成对应的SQL语句
更新所有关联的表格
sequelize
在nodejs中,有不少ORM模块,他们各有特点,这里的话我们选择一个ORM(sequelize)进行介绍。
1. 在mysql中创建要操作的数据库
2. 安装ORM模块:sequelize 与 mysql2
yarn add mysql2 sequelize -S
3. 开始写nodejs代码进行操作
const Sequelize = require("sequelize")
var DB = new Sequelize(
'w1902-1', // 数据库名
'root', // 用户名
'123456A', // 用户密码
//数据库配置对象
{
'dialect': 'mysql', // 数据库使用mysql
'host': 'localhost', // 数据库服务器ip
'port': 3306, // 数据库服务器端口
'define': {
// 字段以下划线(_)来分割(默认是驼峰命名风格)
'underscored': true,
'charset': 'utf8',
'collate': 'utf8_general_ci',
'freezeTableName': true,
'timestamps': true, //为模型添加 createdAt 和 updatedAt 两个时间戳字段
},
'pool': { //连接池
'maxConnections': 20,
'minConnections': 0,
'maxIdleTime': 10000 // 连接最大空置时间(毫秒),超时后将释放连接
},
}
);
module.exports = DB;
// 要定义模型和表之间的映射,请使用define方法。 随后Sequelize将自动添加createdAt和updatedAt属性。
// 因此,您将能够知道数据库条目何时进入数据库以及最后一次更新时。
var Sequelize = require('sequelize');
var DB = require('../DB');
var User = DB.define(
'user', //模型名
{
userId: {
field: 'user_id',
primaryKey: true,
type: Sequelize.BIGINT,
allowNull: false
},
userName: {
field: 'user_name',
type: Sequelize.STRING,
allowNull: false
},
}, {
// 如果为 true 则表的名称和 model 相同,即 user
// 为 false MySQL创建的表名称会是复数 users
// 如果指定的表名称本就是复数形式则不变
freezeTableName: false
}
);
// 创建表
// User.sync() 会创建表并且返回一个Promise对象
// 如果 force = true 则会把存在的表(如果users表已存在)先销毁再创建表
// 默认情况下 forse = false
User.sync({
force: false
});
// 添加新用户
module.exports = User;
完整代码
var User = require('./model/User');
//添加(创建)用户(直接添加)
function create() {
// 添加用户(直接添加)
User.create({
userId: 38,
userName: '老王2',
}).then(function(user) {
console.log('****************************');
console.log('添加结果为:', user._options.isNewRecord);
}).catch(function(err) {
console.log("出错了:", err);
});
}
// 添加(创建)用户 (先查询在添加)
function findOrCreate() {
// 添加用户:此方法会先查询,如果查询到有此条数据相同的就不会新增,返回created:false,得到查询结果
User.findOrCreate({
where: {
userId: 38,
userName: '老王9'
}
})
.spread((test, created) => {
if (created == false) {
//说明数据已存在,添加失败
console.log("-------------数据已存在,添加失败--------------");
var data = test.get({
plain: true
});
console.log("已存在的数据为:", data);
} else {
console.log("添加成功...");
}
}).catch(function(err) {
console.log("出错了:", err);
})
}
//查询单条数据(根据任意字段)
function find() {
User.findOne({
where: {
userId: 38
}
})
.then(function(user) {
console.log('****************************');
console.log("查询的数据为:", user.dataValues);
console.log('****************************');
console.log('user userName: ', user.userName);
console.log('user userName: ', user.userId);
});
}
//查询所有数据
function findAll() {
//查询所有数据
User.findAll()
.then(data => {
// 从结果集中取出所有数据
var users = [];
data.forEach(function(ele) {
users.push(ele.dataValues)
})
console.log("所有的数据为:", users)
})
}
//删除数据
function destroy() {
User.destroy({
where: {
userId: 38
}
})
.then(function(result) { //表示删除的数据的条数
console.log('共删除数据条数为:', result);
});
}
//修改数据
function update() {
User.update({
userName: "张三"
}, {
where: {
userId: 36
}
})
.then(function(result) {
console.log('共修改数据条数为:', result);
})
}
//调用相关方法
update()
感受一下, 有了ORMapping框架之后, 操作数据库有多简单