sequlize:方便操作数据库的工具
网站:入门 | Sequelize 中文文档 | Sequelize 中文网
1、Sequelize 是一个基于 promise 的 Node.js ORM, 目前支持 Postgres, MySQL, MariaDB, SQLite 以及 Microsoft SQL Server.
/** *
* 解释几个必要参数,以及日常使用频率较高的参数
* database:数据库的名称
* username:用来认证数据库连接的用户名
* password:用来认证数据库连接的密码
* host:数据库的host地址
* port:数据库服务的端口
* dialect:数据库语言,可以选mysql、postgres、sqlite等
* timezone:时区,将数据库时间转换成js的date时候会用到,默认是:‘+00:00’,我们一般设置成中国的时区,避免一些时间转换的麻烦
* logging:执行每次数据库操作,是否在在控制台输出原生sql的log
* pool:数据库连接池的设置,用的是默认配置
* freezeTableName:默认为false,是否需要固定表名,如果设置为true,js中定义表名会和数据库中创建的表名相同,如果为false,* * * Sequelize会按照他的规则生成一个表名
* timestamps:默认为true,默认情况下,Sequelize会为每个表创建2个字段,createdAt和updatedAt,设置为false则不会自动创建这2个字段
-
- */
2、下载模块:cnpm i sequelize --save
3、下载mysql数据库的驱动程序:cnpm i mysql2 --save
4、新建文件夹sql,新建文件config.js:
module.exports = {
sql: {
database: "cake",
username: "root",
password: "123456",
host: "localhost",
port: "3306"
}
}
5、在sql下再新建文件index.js:,链接数据库
const Sequelize = require('sequelize');
//引入配置项
const { sql } = require('./config')
//配置数据库链接
const seq = new Sequelize(sql.database, sql.username, sql.password, { //数据库名,用户名,密码
host: sql.host, // 网络地址
port: sql.port, //端口号
dialect: 'mysql', //映射的数据库类型
timezone: '+08:00', //数据库时区 北京时间
logging: false, //设置数据库连接日志打印
pool: { //连接池
max: 5, //设置数据库链接最大5条
min: 0, //设置数据库链接最小0条
idle: 10000 // 设置数据库链接超时时间 10s
},
define: {
freezeTableName: true, //禁止自动修改表名,默认为true
timestamps: false, //不需要添加 createdAt 和 updatedAt 两个时间戳字段,默认为true
}
});
// 连接数据库
seq.authenticate()
.then(() => {
console.log('========连接mysql数据库成功======');
})
.catch(err => {
console.error('======连接数据库失败======', err);
});
//暴露出去
module.exports = seq
6、新建文件夹model,新建文件shop.js,定义映射模型(映射数据库的表)
//解构定义数据类型对象
const { DataTypes } = require('sequelize');
//引入数据库链接文件
const Seq = require('../sql')
// 用户模型 --- 数据库中的shop表一一对应的映射关系
const Shop = Seq.define("shop", {
//定义表的键名
id: {
type: DataTypes.INTEGER,
primaryKey: true, // 是否为主键,要与数据库的表的主键对应,默认为false
autoIncrement: true , //是否自增,与数据库的表的主键对应,默认为false
},
// uid: {
// type: DataTypes.UUID, //唯一id值
// defaultValue: DataTypes.UUIDV4 // 或 DataTypes.UUIDV1 ,给一个默认的唯一id值
// },
src: {
type: DataTypes.STRING, // 类型字母必须要全部大小
allowNull: false // 允许为空吗
},
url: {
type: DataTypes.STRING, // 类型字母必须要全部大小
allowNull: false // 允许为空吗
},
title: {
type: DataTypes.STRING, // 类型字母必须要全部大小
allowNull: false // 允许为空吗
},
content: {
type: DataTypes.STRING, // 类型字母必须要全部大小
},
tag: {
type: DataTypes.STRING, // 类型字母必须要全部大小
},
price: {
type: DataTypes.INTEGER, // 类型字母必须要全部大小
allowNull: false // 允许为空吗
},
weight: {
type: DataTypes.STRING, // 类型字母必须要全部大小
},
pound: {
type: DataTypes.STRING, // 类型字母必须要全部大小
},
count: {
type: DataTypes.INTEGER, // 类型字母必须要全部大小
allowNull: false // 允许为空吗
},
zone: {
type: DataTypes.STRING, // 类型字母必须要全部大小
},
type: {
type: DataTypes.STRING, // 类型字母必须要全部大小
},
isshow: {
type: DataTypes.STRING, // 类型字母必须要全部大小
defaultValue: "true"
}
}, {
// 这是其他模型参数
// 强制表名称等于模型名称
freezeTableName: true,
})
// 执行 数据库表的同步
// ({ force: true })
// force值为true时,表示每次执行这个方法都会先将表给删除 ,再重新创建
Shop.sync()
.then(() => {
console.log('=======shop表同步成功=======');
})
.catch(err => {
console.error('=======shop表同步异常=======', err);
});
//暴露user表,在路由执行增加,删除,修改,查询
module.exports = Shop ;
7、封装数据库的增删改查功能,创建server文件夹,index.js文件
/****
-
obj:查询条件数组,
-
setObj:更新对象,
-
update返回[更新条数],更新失败为[0]
-
find返回数据对象, 查询不到为[]
-
add返回插入的对象数据
-
del返回删除的数量,删除失败为 0
*/
//增加
const add = (model, obj) => {
return new Promise((resolve, reject) => {
model.create(obj)
.then((data) => {
resolve(data.dataValues)
})
.catch(err => {
reject(err)
})
})
}
//查找数据
const find = (model, obj = {}) => {
return new Promise((resolve, reject) => {
model.findAll({
where: obj
})
.then((data) => {
resolve(data)
})
.catch(err => {
reject(err)
})
})
}
// 更新数据
const update = (model, setObj, obj) => {
return new Promise((resolve, reject) => {
model.update(setObj, {
where: obj
})
.then((data) => {
resolve(data)
})
.catch(err => {
reject(err)
})
})
}
//删除
const del = (model, obj) => {
return new Promise((resolve, reject) => {
model.destroy({
where: obj
})
.then((data) => {
resolve(data)
})
.catch(err => {
reject(err)
})
})
}
### //暴露出去
module.exports = {
add, find, update, del
}
8、操作表数据的增删改查
8.1、插入数据
插入数据是通过模型对象的create方法实现的。例如,我们要向“users”表中插入一条记录,可以使用以下代码:
await User.create({
username: 'test',
password: '123456'
});
8.2、查询数据
查询数据是Sequelize中最常见的操作之一,Sequelize提供了多种查询方法,包括findAll(查询所有符合条件的记录)、findOne(查询符合条件的第一条记录)、findByPk(根据主键查询一条记录)等。例如,我们要查询“users”表中所有记录,可以使用以下代码:
const users = await User.findAll();
console.log(users);
8.3、更新数据
更新数据是通过模型对象的update方法实现的。例如,我们要将“users”表中username为“test”的记录的密码修改为“654321”,可以使用以下代码:
await User.update({ password: '654321' }, {
where: {
username: 'test'
}
});
8.4、删除数据
删除数据是通过模型对象的destroy方法实现的。例如,我们要删除“users”表中username为“test”的记录,可以使用以下代码:
await User.destroy({
where: {
username: 'test'
}
});
9、模型类型
字符串
DataTypes.STRING // VARCHAR(255)
DataTypes.STRING(1234) // VARCHAR(1234)
DataTypes.STRING.BINARY // VARCHAR BINARY
DataTypes.TEXT // TEXT
DataTypes.TEXT('tiny') // TINYTEXT
DataTypes.CITEXT // CITEXT 仅 PostgreSQL 和 SQLite.
DataTypes.TSVECTOR // TSVECTOR 仅 PostgreSQL.
布尔
DataTypes.BOOLEAN // TINYINT(1)
数字
DataTypes.INTEGER // INTEGER
DataTypes.BIGINT // BIGINT
DataTypes.BIGINT(11) // BIGINT(11)
DataTypes.FLOAT // FLOAT
DataTypes.FLOAT(11) // FLOAT(11)
DataTypes.FLOAT(11, 10) // FLOAT(11,10)
DataTypes.REAL // REAL 仅 PostgreSQL.
DataTypes.REAL(11) // REAL(11) 仅 PostgreSQL.
DataTypes.REAL(11, 12) // REAL(11,12) 仅 PostgreSQL.
DataTypes.DOUBLE // DOUBLE
DataTypes.DOUBLE(11) // DOUBLE(11)
DataTypes.DOUBLE(11, 10) // DOUBLE(11,10)
DataTypes.DECIMAL // DECIMAL
DataTypes.DECIMAL(10, 2) // DECIMAL(10,2)
无符号和零填充整数 - 仅限于MySQL/MariaDB
在 MySQL 和 MariaDB 中,可以将数据类型INTEGER, BIGINT, FLOAT 和 DOUBLE 设置为无符号或零填充(或两者),如下所示:
DataTypes.INTEGER.UNSIGNED
DataTypes.INTEGER.ZEROFILL
DataTypes.INTEGER.UNSIGNED.ZEROFILL
// 你还可以指定大小,即INTEGER(10)而不是简单的INTEGER
// 同样适用于 BIGINT, FLOAT 和 DOUBLE
日期
DataTypes.DATE // DATETIME 适用于 mysql / sqlite, 带时区的TIMESTAMP 适用于 postgres
DataTypes.DATE(6) // DATETIME(6) 适用于 mysql 5.6.4+. 支持6位精度的小数秒
DataTypes.DATEONLY // 不带时间的 DATE
UUID
对于 UUID,使用 DataTypes.UUID. 对于 PostgreSQL 和 SQLite,它会是 UUID 数据类型;对于 MySQL,它则变成CHAR(36). Sequelize 可以自动为这些字段生成 UUID,只需使用 DataTypes.UUIDV1 或 DataTypes.UUIDV4 作为默认值即可:
{
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4 // 或 DataTypes.UUIDV1
}
10、数据库批量导入数据,以数组形式导入 model.bulkCreate(arr)
// 批量增加
const addAll = (model, arr) => {
return new Promise((resolve, reject) => {
model.bulkCreate(arr)
.then((data) => {
• resolve(data.dataValues)
})
.catch(err => {
• reject(err)
})
})
}
11、删除全部数据
//删除全部数据
const delAll = (model) => {
return new Promise((resolve, reject) => {
model.destroy({
where: {},
truncate: true
})
.then((data) => {
• resolve(data)
})
.catch(err => {
• reject(err)
})
})
}
12、sequelize怎么根据时间段查询
在 Sequelize 中,你可以使用 Op 对象来进行时间段查询。下面是一个示例,展示如何使用 Sequelize 查询一个指定时间段内的数据:
const { Op } = require('sequelize');
// 假设你有一个名为 `Event` 的模型
const Event = sequelize.define('Event', {
// ...
});
// 定义开始时间和结束时间
const startTime = new Date('2022-01-01');
const endTime = new Date('2022-01-31');
// 使用 `Op.between` 运算符进行时间段查询
const events = await Event.findAll({
where: {
createdAt: {
[Op.between]: [startTime, endTime]
}
}
});
console.log(events);
在上面的示例中,我们使用 Op.between 运算符来指定查询的时间段。Op.between 接受一个数组,数组的第一个元素是开始时间,第二个元素是结束时间。在查询中,我们使用 createdAt 字段作为时间字段,你可以根据你的模型来替换它。
请注意,Op.between 运算符是闭区间,即包括开始时间和结束时间。如果你想要排除开始时间或结束时间,你可以使用 Op.gt(大于)或 Op.lt(小于)运算符。
希望这可以帮助到你!如果你有任何其他问题,请随时问我。
13、将where的查询条件变成与的关系
要将where的查询条件变成与的关系,可以使用Sequelize中的[Op.and]操作符。下面是修改后的代码:
const { Op } = require('sequelize');
const data = await merchant_payout_bill.findAndCountAll({
where: {
store_num,
[Op.and]: [
{ submit_time: { [Op.between]: [startTime, endTime] } }
// 添加其他的查询条件
]
},
offset: (page_num - 1) * page_size,
limit: page_size
});
在where对象中,使用[Op.and]操作符将多个查询条件放在一个数组中,这样它们就会被视为与的关系。你可以根据需要添加其他的查询条件到数组中。
14、根据时间字段排序
要对上面的语句进行时间段排序,可以使用order参数来指定排序方式。以下是修改后的代码:
const data = await merchant_payout_bill.findAndCountAll({
where: {
store_num,
[Op.and]: [
{
submit_time: {
[Op.between]: [startTime, endTime]
}
}
]
},
offset: (page_num - 1) * page_size,
limit: page_size,
order: [['submit_time', 'ASC']] // 按照 submit_time 升序排序
});
在order参数中,我们使用了一个二维数组来指定排序字段和排序方式。上述代码中,我们将submit_time字段作为排序字段,并指定为升序排序(ASC)。如果要进行降序排序,可以将排序方式改为DESC。
请注意,上述代码中的排序方式是按照submit_time字段进行排序的。如果你想根据其他字段进行排序,请相应地修改order参数中的字段名。
批量插入索引更新问题
1、批量插入方法,有重复数据就指定更新某些字段的值,没有重复数据就新增
return SYSTEM_INVENTORY_BODY.bulkCreate(INVENTORYBODYS, {
updateOnDuplicate: ["INVENTORYNUM", "REMARK"]
})