CRUD 操作

添加数据

添加一条数据

使用 add 方法可以添加一条数据,返回值为插入数据的 id。如:

  1. export default class extends think.controller.base {
  2. async addAction(){
  3. let model = this.model('user');
  4. let insertId = await model.add({name: 'xxx', pwd: 'yyy'});
  5. }
  6. }

有时候需要借助数据库的一些函数来添加数据,如:时间戳使用 mysql 的 CURRENT_TIMESTAMP 函数,这时可以借助 exp 表达式来完成。

  1. export default class extends think.controller.base {
  2. async addAction(){
  3. let model = this.model('user');
  4. let insertId = await model.add({
  5. name: 'test',
  6. time: ['exp', 'CURRENT_TIMESTAMP()']
  7. });
  8. }
  9. }

添加多条数据

使用 addMany 方法可以添加多条数据,如:

  1. export default class extends think.controller.base {
  2. async addAction(){
  3. let model = this.model('user');
  4. let insertId = await model.addMany([
  5. {name: 'xxx', pwd: 'yyy'},
  6. {name: 'xxx1', pwd: 'yyy1'}
  7. ]);
  8. }
  9. }

thenAdd

数据库设计时,我们经常需要把某个字段设为唯一,表示这个字段值不能重复。这样添加数据的时候只能先去查询下这个数据值是否存在,如果不存在才进行插入操作。

模型中提供了 thenAdd 方法简化这一操作。

  1. export default class extends think.controller.base {
  2. async addAction(){
  3. let model = this.model('user');
  4. //第一个参数为要添加的数据,第二个参数为添加的条件,根据第二个参数的条件查询无相关记录时才会添加
  5. let result = await model.thenAdd({name: 'xxx', pwd: 'yyy'}, {name: 'xxx'});
  6. // result returns {id: 1000, type: 'add'} or {id: 1000, type: 'exist'}
  7. }
  8. }

更新数据

update

更新数据使用 update 方法,返回值为影响的行数。如:

  1. export default class extends think.controlle.base {
  2. async updateAction(){
  3. let model = this.model('user');
  4. let affectedRows = await model.where({name: 'thinkjs'}).update({email: 'admin@thinkjs.org'});
  5. }
  6. }

默认情况下更新数据必须添加 where 条件,以防止误操作导致所有数据被错误的更新。如果确认是更新所有数据的需求,可以添加 1=1 的 where 条件进行,如:

  1. export default class extends think.controlle.base {
  2. async updateAction(){
  3. let model = this.model('user');
  4. let affectedRows = await model.where('1=1').update({email: 'admin@thinkjs.org'});
  5. }
  6. }

有时候更新值需要借助数据库的函数或者其他字段,这时候可以借助 exp 来完成。

  1. export default class extends think.controlle.base {
  2. async updateAction(){
  3. let model = this.model('user');
  4. let affectedRows = await model.where('1=1').update({
  5. email: 'admin@thinkjs.org',
  6. view_nums: ['exp', 'view_nums+1'],
  7. update_time: ['exp', 'CURRENT_TIMESTAMP()']
  8. });
  9. }
  10. }

increment

可以通过 increment 方法给符合条件的字段增加特定的值,如:

  1. export default class extends think.model.base {
  2. updateViewNums(id){
  3. return this.where({id: id}).increment('view_nums', 1); //将阅读数加 1
  4. }
  5. }

decrement

可以通过 decrement 方法给符合条件的字段减少特定的值,如:

  1. export default class extends think.model.base {
  2. updateViewNums(id){
  3. return this.where({id: id}).decrement('coins', 10); //将金币减 10
  4. }
  5. }

查询数据

模型中提供了多种方式来查询数据,如:查询单条数据,查询多条数据,读取字段值,读取最大值,读取总条数等。

查询单条数据

可以使用 find 方法查询单条数据,返回值为对象。如:

  1. export default class extends think.controller.base {
  2. async listAction(){
  3. let model = this.model('user');
  4. let data = await model.where({name: 'thinkjs'}).find();
  5. //data returns {name: 'thinkjs', email: 'admin@thinkjs.org', ...}
  6. }
  7. }

如果数据表没有对应的数据,那么返回值为空对象 {},可以通过 think.isEmpty 方法来判断返回值是否为空。

查询多条数据

可以使用 select 方法查询多条数据,返回值为数据。如:

  1. export default class extends think.controller.base {
  2. async listAction(){
  3. let model = this.model('user');
  4. let data = await model.limit(2).select();
  5. //data returns [{name: 'thinkjs', email: 'admin@thinkjs.org'}, ...]
  6. }
  7. }

如果数据表中没有对应的数据,那么返回值为空数组 [],可以通过 think.isEmpty 方法来判断返回值是否为空。

分页查询数据

页面中经常遇到按分页来展现某些数据,这种情况下就需要先查询总的条数,然后在查询当前分页下的数据。查询完数据后还要计算有多少页。模型中提供了 countSelect 方法来方便这一操作,会自动进行总条数的查询。

  1. export default class extends think.controller.base {
  2. async listAction(){
  3. let model = this.model('user');
  4. let data = await model.page(this.get('page'), 10).countSelect();
  5. }
  6. }

返回值格式如下:

  1. {
  2. numsPerPage: 10, //每页显示的条数
  3. currentPage: 1, //当前页
  4. count: 100, //总条数
  5. totalPages: 10, //总页数
  6. data: [{ //当前页下的数据列表
  7. name: 'thinkjs',
  8. email: 'admin@thinkjs.org'
  9. }, ...]
  10. }

如果传递的当前页数超过了页数范围,可以通过传递参数进行修正。true 为修正到第一页, false 为修正到最后一页,即: countSelect(true)countSelect(false)

如果总条数无法直接查询,可以将总条数作为参数传递进去,如: countSelect(1000),表示总条数有1000条。

count

可以通过 count 方法查询符合条件的总条数,如:

  1. export default class extends think.model.base {
  2. getMin(){
  3. //查询 status 为 publish 的总条数
  4. return this.where({status: 'publish'}).count();
  5. }
  6. }

sum

可以通过 sum 方法查询符合条件的字段总和,如:

  1. export default class extends think.model.base {
  2. getMin(){
  3. //查询 status 为 publish 字段 view_nums 的总和
  4. return this.where({status: 'publish'}).sum('view_nums');
  5. }
  6. }

max

可以通过 max 方法查询符合条件的最大值,如:

  1. export default class extends think.model.base {
  2. getMin(){
  3. //查询 status 为 publish,字段 comments 的最大值
  4. return this.where({status: 'publish'}).max('comments');
  5. }
  6. }

min

可以通过 min 方法查询符合条件的最小值,如:

  1. export default class extends think.model.base {
  2. getMin(){
  3. //查询 status 为 publish,字段 comments 的最小值
  4. return this.where({status: 'publish'}).min('comments');
  5. }
  6. }

查询缓存

为了性能优化,项目中经常要对一些从数据库中查询的数据进行缓存。如果手工将查询的数据进行缓存,势必比较麻烦,模型中直接提供了 cache 方法来设置查询缓存。如:

  1. export default class extends think.model.base {
  2. getList(){
  3. //设定缓存 key 和缓存时间
  4. return this.cache('get_list', 3600).where({id: {'>': 100}}).select();
  5. }
  6. }

上面的代码为对查询结果进行缓存,如果已经有了缓存,直接从缓存里读取,没有的话才从数据库里查询。缓存保存的 key 为 get_list,缓存时间为一个小时。

也可以不指定缓存 key,这样会自动根据 SQL 语句生成一个缓存 key。如:

  1. export default class extends think.model.base {
  2. getList(){
  3. //只设定缓存时间
  4. return this.cache(3600).where({id: {'>': 100}}).select();
  5. }
  6. }
缓存配置

缓存配置为模型配置中的 cache 字段( 配置文件在 src/common/config/db.js),如:

  1. export default {
  2. cache: {
  3. on: true,
  4. type: '',
  5. timeout: 3600
  6. }
  7. }
  • on 数据库缓存配置的总开关,关闭后即使程序中调用 cache 方法也无效。
  • type 缓存配置类型,默认为内存,支持的缓存类型请见 Adapter -> Cache
  • timeout 默认缓存时间。

    删除数据

可以使用 delete 方法来删除数据,返回值为影响的行数。如:

  1. export default class extends think.controller.base {
  2. async deleteAction(){
  3. let model = this.model('user');
  4. let affectedRows = await model.where({id: ['>', 100]}).delete();
  5. }
  6. }

模型中更多的操作方式请见相关的 API -> model

原文: https://thinkjs.org/zh-cn/doc/2.2/model_crud.html