orm

Nodejs + Sequelize单表增删改查

特别声明:如果您喜欢小站的内容,可以点击 终身VIP¥188.00元 包年VIP¥88.00元 包季VIP¥28.00 包月VIP¥10.00元 进行全站阅读。 如果您对付费阅读有任何建议或想法,欢迎发送邮件至: 864479410@qq.com,或添加QQ:864479410(^_^)

引言

前面为了项目能更好的使用,也是做了非常多的铺垫,又是生成api文档,又是log4j日志。现在回到正题,Sequelize来操作我们的mysql数据库。

本小节分为:
(1)单条数据/多条数据新增
(2)单条修改/批量修改
(3)数据删除
(4)数据查询

单条数据/多条数据新增

(1)单条数据新增

继续在router/user.js上面写测试接口实现新增

/**
 * 
 * @api {get} /api/user/add 新增
 * @apiName 新增
 * @apiGroup 用户
 * @apiDescription 新增用户
 * @apiVersion  1.0.0
 * 
 * @apiParam {String} id='' 
 * @apiParam {Number} age='' 
 * @apiParam {Number} sex=1
 * 
 * @apiParamExample  {type} Request-Example:
 * {
 *     name: '',
 *     age: '',
 *     sex: 1
 * }
 * 
 * @apiSuccess {Number} code 200
 * @apiSuccess {Object} data 用户信息
 * @apiSuccessExample {type} Response-Example:
 * {
 *  code: 200,
 *  data: {
 *    name: '',
 *    age: '',
 *    sex: '',
 *    ...
 *  }
 * }
 * 
 */
router.get('/add', async (req, res) => {
  const params = req.body;

  let data = await userDB.create({
    name: params.name,
    age: params.age,
    sex: params.sex,
  })
  res.send({
    code: 200,
    data: data
  })
})

浏览器调用接口测试

数据库数据

(2)多条数据批量新增

/**
 * 
 * @api {get} /api/user/add-group 批量新增
 * @apiName 批量新增
 * @apiGroup 用户
 * @apiDescription 批量新增用户
 * @apiVersion  1.0.0
 * 
 * @apiSuccess {Number} code 200
 * @apiSuccess {Object} data 用户信息
 * @apiSuccessExample {type} Response-Example:
 * {
 *  code: 200,
 * }
 * 
 */
 router.get('/add-group', async (req, res) => {
  const params = req.body;
  let userList = [{
    name: 'dom',
    age: 28,
    sex: 1
  }, {
    name: 'jerry',
    age: 26,
    sex: 2
  }]
  let data = await userDB.bulkCreate(userList)
  res.send({
    code: 200,
    data: data
  })
})

由于get请求不好传入数组,我们也就在接口里面写死数据,接口测试一下:

完全OK,我们修改数据。

单条修改/批量修改

(1)、单条修改

/**
 * 
 * @api {get} /api/user/update 修改
 * @apiName 修改
 * @apiGroup 用户
 * @apiDescription 修改用户
 * @apiVersion  1.0.0
 * 
 * @apiParam {String} id='' 
 * @apiParam {String} name='' 
 * @apiParam {Number} sex='' 
 * @apiParam {Number} age='' 
 * 
 * @apiParamExample  {type} Request-Example:
 * {
 *     id: 1,
 *     sex: 20,
 * }
 * 
 * @apiSuccess {Number} code 200
 * @apiSuccess {Object} data 用户信息
 * @apiSuccessExample {type} Response-Example:
 * {
 *  code: 200,
 *  data: {
 *    name: '',
 *    age: '',
 *    sex: '',
 *    ...
 *  }
 * }
 * 
 */
 router.get('/update', async (req, res) => {
  const params = req.body;

  if(!params.id){
    utils.sendError(res, '用户ID不能为空')
    return
  }

  let upParams = {}
  if(params.name){
    upParams.name = params.name
  }
  if(params.age){
    upParams.age = params.age
  }
  if(params.sex){
    upParams.sex = params.sex
  }

  let data = await userDB.update(upParams, {
    where: {
      id: params.id
    }
  })
  res.send({
    code: 200,
    data: data
  })
})

接口的意思是,传入id,同时可以传入name,sex, age,根据id修改对应的name,sex, age数据,调用接口测试:


修改了用户id为1的sex=20,数据库已经改成功

好像忘记了点啥,sex怎么会是20了?改错了,改回去。

(2)、批量修改

/**
 * 
 * @api {get} /api/user/update-group 批量修改
 * @apiName 批量修改
 * @apiGroup 用户
 * @apiDescription 批量修改用户
 * @apiVersion  1.0.0
 * 
 * @apiSuccess {Number} code 200
 * @apiSuccess {Object} data 用户信息
 * @apiSuccessExample {type} Response-Example:
 * {
 *  code: 200,
 * }
 * 
 */
 router.get('/update-group', async (req, res) => {
  const params = req.body;
  let userList = [{
    id: 1,
    age: 26,
    sex: 1
  }, {
    id: 2,
    age: 26,
    sex: 2
  }]
  let data = await userDB.bulkCreate(userList, {updateOnDuplicate:['age', 'sex']})
  res.send({
    code: 200,
    data: data
  })
})

细心的小伙伴,应该发现了,这里批量修改和批量新增用的是同一个方法,是的。不同的区别是多传了一个参数,updateOnDuplicate,意思是在插入的时候如果主键冲突就执行更新操作。更新字段就是后面的数组['age', 'sex']

我们调用接口,看下图:

打印的SQL:

INSERT INTO `user` (`id`,`age`,`sex`) VALUES (1,26,1),(2,26,2) ON DUPLICATE KEY UPDATE `age`=VALUES(`age`),`sex`=VALUES(`sex`);

数据删除

数据删除就非常简单了

/**
 * 
 * @api {get} /api/user/del 删除
 * @apiName 删除
 * @apiGroup 用户
 * @apiDescription 删除用户
 * @apiVersion  1.0.0
 * 
 * @apiParam {String} id='' 
 * 
 * @apiParamExample  {type} Request-Example:
 * {
 *     id: 1
 * }
 * 
 * @apiSuccess {Number} code 200
 * @apiSuccess {Object} message 提示信息
 * @apiSuccessExample {type} Response-Example:
 * {
 *  code: 200,
 *  message: '删除成功'
 * }
 * 
 */
 router.get('/del', async (req, res) => {
  const params = req.body;

  if(!params.id){
    utils.sendError(res, '用户ID不能为空')
    return
  }

  let data = await userDB.destroy({
    where: {
      id: params.id
    }
  })
  res.send({
    code: 200,
    data: data
  })
})

传入id,执行destroy方法即可。

当然,也可以批量删除,只需用简单修改一下即可

const { Op } = require("sequelize")
...
let data = await userDB.destroy({
  where: {
    id: {
      [Op.in]: [2,3,4,...]
    }
  }
})

这里的 Op 可以适用各种运算符,对应关系如下:

[Op.and]: {a: 5}           // 且 (a = 5)
[Op.or]: [{a: 5}, {a: 6}]  // (a = 5 或 a = 6)
[Op.gt]: 6,                // id > 6
[Op.gte]: 6,               // id >= 6
[Op.lt]: 10,               // id < 10
[Op.lte]: 10,              // id <= 10
[Op.ne]: 20,               // id != 20
[Op.eq]: 3,                // = 3
[Op.not]: true,            // 不是 TRUE
[Op.between]: [6, 10],     // 在 6 和 10 之间
[Op.notBetween]: [11, 15], // 不在 11 和 15 之间
[Op.in]: [1, 2],           // 在 [1, 2] 之中
[Op.notIn]: [1, 2],        // 不在 [1, 2] 之中
[Op.like]: '%hat',         // 包含 '%hat'
[Op.notLike]: '%hat'       // 不包含 '%hat'
[Op.iLike]: '%hat'         // 包含 '%hat' (不区分大小写)  (仅限 PG)
[Op.notILike]: '%hat'      // 不包含 '%hat'  (仅限 PG)
[Op.regexp]: '^[h|a|t]'    // 匹配正则表达式/~ '^[h|a|t]' (仅限 MySQL/PG)
[Op.notRegexp]: '^[h|a|t]' // 不匹配正则表达式/!~ '^[h|a|t]' (仅限 MySQL/PG)
[Op.iRegexp]: '^[h|a|t]'    // ~* '^[h|a|t]' (仅限 PG)
[Op.notIRegexp]: '^[h|a|t]' // !~* '^[h|a|t]' (仅限 PG)
[Op.like]: { [Op.any]: ['cat', 'hat']} // 包含任何数组['cat', 'hat'] - 同样适用于 iLike 和 notLike
[Op.overlap]: [1, 2]       // && [1, 2] (PG数组重叠运算符)
[Op.contains]: [1, 2]      // @> [1, 2] (PG数组包含运算符)
[Op.contained]: [1, 2]     // <@ [1, 2] (PG数组包含于运算符)
[Op.any]: [2,3]            // 任何数组[2, 3]::INTEGER (仅限PG)
[Op.col]: 'user.organization_id' // = 'user'.'organization_id', 使用数据库语言特定的列标识符, 本例使用 PG

运用范围,增删改查都可以,后面我们也会有很多地方用到,这里就提前列出。

数据查询

其实在第一节,里面我们已经看到了查询方法findAll(),其实还有findOne()findAndCountAll(),它们都有各自的用意。

findOne

findOne获取单条数据,如果多条满足条件,默认返回第一条

let data = await userDB.findOne()

let data = await userDB.findOne({
  where: {
    id: params.id
  }
})

返回与参数id相等的数据,没有返回null

findAll

findAll返回所有满足条件的数据,常用于不需要分页的数据接口

let data = await userDB.findAll({
  where: {
    sex: params.sex
  }
})

findAndCountAll

findAll返回所有满足条件的数据和总条数,常用于需要分页的数据接口

/**
 * 
 * @api {get} /api/user/list 列表
 * @apiName 列表
 * @apiGroup 用户
 * @apiDescription 用户列表
 * @apiVersion  1.0.0
 * 
 * @apiParam {String} sex='' 
 * @apiParam {String} pageNo='' 
 * @apiParam {String} pageSize='' 
 * 
 * @apiParamExample  {type} Request-Example:
 * {
 *     pageNo: 1,
 *     pageSize: 10,
 * }
 * 
 * @apiSuccess {Number} code 200
 * @apiSuccess {Array} resultList 数据集合
 * @apiSuccess {Object} paging 分页信息
 * @apiSuccessExample {type} Response-Example:
 * {
 *  code: 200,
 *  resultList: [],
 *  paging: {
 *    pageNo: 1,
 *    pageSize: 10,
 *    totalCount: 12,
 *    totalPage: 2
 *  }
 * }
 * 
 */
 router.get('/list', async (req, res) => {
  const params = req.body;

  let {pageNo=1, pageSize=10} = params
  let offset = (pageNo - 1) * pageSize

  let where = {}
  if(params.sex){
    where.sex = params.sex
  }
  let {rows, count} = await userDB.findAndCountAll({
    offset: offset,
    limit: pageSize,
    where: where
  })

  res.send({
    code: 200,
    resultList: rows,
    paging: {
      pageNo: pageNo,
      pageSize: pageSize,
      totalCount: count,
      totalPage: Math.ceil(count / pageSize)
    }
  })
})

新写一个接口,分页查询user

为了分页,我增加了一些数据,现在有11条,为什么下标变为了12?

因为我们先删除了id=4的数据了

调用接口,返回了第一页数据,这时我们是没有传参数的,代码里面有默认值,默认pageNo=1pageSize=10

控制台打印了2条sql,也就是说findAndCountAll方法,其实是分解为两步了

SELECT count(*) AS `count` FROM `user` AS `user`;
SELECT `id`, `name`, `age`, `sex`, `create_time`, `update_time` FROM `user` AS `user` LIMIT 0, 10;

再次调用接口,我们传入参数pageNo=2,返回的就是第二页数据了。

然后我们再试试传入pageNopageSizesex三个参数,返回结果也ok。

把数据sex=1的数据分为了2页,共5条数据。

小结

增删改查,最基本的操作我们都学习了,相信大家都所有收获,再来回顾一下,用到的方法:

1、create()新增一条数据,并返回新增的数据;

2、blukCreate()

(1)默认批量新增数据,返回新增的数据
(2)传入updateOnDuplicate参数,为在插入的时候如果主键冲突就执行更新操作,返回更新或新增的数据

3、update()根据条件更新数据;

4、destroy()根据条件删除数据;

5、findOne()返回满足条件的第一条数据

6、findAll()返回满足条件的所有数据

7、findAndCountAll()返回满足条件的所有数据和总条数,用于分页

(0)

本文由 Web秀 作者:Javan 发表,转载请注明来源!

热评文章

发表评论

邮箱地址不会被公开。 必填项已用*标注