loopback 04

数据库相关

关系定义

定义关系之后的使用

relations: {
      "images": {
      "type": "hasMany",
      "model": "image",
      "polymorphic": "imageable"
    }
}

//
Item.create(itemData).then((item)=> { 
  item.image.create().then(){
  }
})

继承默认User表

  • 已经继承了username,password属性;
//一般表的结构
{
  "name": "other",
  "base": "PersistedModel",
  ....
}

//继承User表的结构
{
  "name": "user",
  "base": "User",
  ...
}

修改数据类型为指定数据库类型

"details": {
     "type": [
        "object"
      ],
      "postgresql": {
        "dataType": "text"
      }
}

使用mixins

  • 对于定义表中大部分都会定义的相同属性提取出来定义
  • server/model-config.js:
{
  ...
  "mixins": [
      "loopback/common/mixins",
      "loopback/server/mixins",
      "../common/mixins",
      "./mixins"
    ]
  ...
}
  • common/models/*.json
{
  ...
  "mixins": {"Timestamp": {"myOption": 1}},
  ...
}
  • common/mixins/timestamp.js
module.exports = function(Model, options) {
  // Model is the model class
  // options is an object containing the config properties from model definition
  Model.defineProperty('created', {type: Date, default: '$now'});
  Model.defineProperty('modified', {type: Date, default: '$now'});
}

使用正则表达式

Item.find({
  where: {
   or: [
     {
     a: {regexp: ...},      //{like: '%%'}
     b: {regexp: ...}
     }
   ]
  }
}).then(items=> callback(null, items)).catch(callback);

测试辅助

  • 定义测试时自动更新的数据库
  app.datasources.pg.autoupdate([
    'user',.....
  ]);

测试时使用:以chai为例

describe('Item Model definition', ()=> {
  let db = app.datasources.pg;
  let item = db.getModelDefinition('item');


  it('has the following properties', ()=> {
    expect(item.properties.content.type).to.eql(String);
    expect(item.properties.thumbsup.type).to.eql(Number);
    expect(item.properties.userId.type).to.eql(Number);
    .....
  });
});

测试前删除数据:

beforeEach(done=> {
    app.dataSources.pg.automigrate(['item','tag','image'], ()=> {
      Item.create(itemData).then((item)=> { 
        itemOne = item;
        itemId = item.id;
        done();
      })
    })
  });
.....
});

继承loopback自定义的数据库

{
  "name": "user",
  "base": "User",
...
}

debug运行

DEBUG=* npm start

数据库关系

BelongsTo

  • 一对多,一对一关系;
  • 对面是hasMany,hasOne

HasMany

  • 一对多关系:
  • 对面是belongsTo

HasOne

  • 一对一关系;
  • 对面是belongsTo

HasManyThrough

  • 多对多关系;
  • 第三方表是两个belongsTo

  • 自己与自己表多对多关系,需要新增keyThrough属性

HasAndBelongsToMany

  • 多对多关系, 在第三张表不保存id外其他属性时使用,简化版的HasManyThrough
  • 对面也是hasAndBelongsToMany

Polymorphic relations

loopback常用命令

  • slc loopback:model : 创建数据表
  • slc loopback:acl : 数据表权限设置

常用数据库操作

创建

  • PersistedModel.create(data, callback): 创建
  • PersistedModel.upsert(data, callback): 更新或插入
  • PersistedModel.findOrCreate([where], data, callback): 不存在创建,存在则返回
  • persistedModel.save([options], callback): 更新,如果没有id字段,则创建

更新

  • PersistedModel.updateAll([where], data, callback) 更新
  • persistedModel.updateAttribute(name, value, callback) 更新属性
  • persistedModel.updateAttributes(data, callback) 更新属性
  • PersistedModel.createUpdates(deltas, callback)
  • PersistedModel.bulkUpdate(updates, callback): 按数组更新;

销毁

  • PersistedModel.destroyAll([where], callback): 销毁
  • PersistedModel.destroyById(id, callback): 根据id销毁

debug检查

  • DEBUG=loopback:connector:postgresql npm start

使用loopback自带的数据验证;

使用loopback-console直接操作数据;

关于hook

  • before|afterRemote();
  • observe();
  • 例子
  • 获取其他数据表: loopback.getModel('xxx');

添加方法

  • 整个模型的方法
  Item.search = function(filter, keyword, callback) {
    filter = filter || {};
    let query = {regexp: `/${keyword}/i`};

    delete filter.where;

    if (keyword) {
      filter.where = {
        or: [
          {content: query, deleted: false, visible: true},
          {tagString: query, deleted: false, visible: true}
        ]
      };
    }

    Item.find(filter).then(items=> callback(null, items)).catch(callback);
  };
  • 单个模型实例的方法
  Activity.prototype.increaseViews = function(nums, callback) {
    callback(null, {views: this.views});
  };

  Activity.beforeRemote('prototype.increaseViews', (ctx, instance, next)=> {
    const nums = ctx.req.query.nums || 1;
    instance && instance.updateAttribute('views', instance.views + Number(nums))
      .then(()=> next()).catch(next);
  });
  • 设置权限(如果开启了的话)
  • 添加远程说明
  Item.remoteMethod('search', {
    description: '',
    accepts: [
      { arg: 'filter', type: 'object', http: {source: 'query|object'} },
    ],
    http: {verb: 'get|post|put...'},
    returns: { root: true, type: '' }
  });

去掉explore

  • 分别删除root/explore.js, components.config

数据筛选

  • 只返回特定的属性: { fields: {id: true, make: true, model: true} }, 例子
    • 注意id必须有,同时用include的话,相关的id也必须有;
  • include数据:
    • 单用的话可以是数组或字符串;
    • 扩展的话可以是数组或对象; 例子;
posted @ 2015-08-17 10:15  JinksPeng  阅读(958)  评论(0编辑  收藏  举报