mongoose模型扩展扩展

为什么要扩展mongoose模型?

我们对业务进行分层处理

  1. service(多模型操作) -> dao(单一模型操作) -> model(模型定义)

所以我们在dao层需要很多单一模型的数据库操作方法的封装,如果业务非常复杂,比如一个超级查询方法,然后又有各种具体业务定义方法,难道我们一个一个的都写在dao层么?

事实上dao只做暴露给service的方法,而具有一定业务约定的方法是可以放到model层上做的,如果我们dao层的很多底层方法可以下沉到model,这样就可以让它们的职责更加清晰。所以,我们里有mongoose的模型扩展来重新定义一下分层

  1. service(多模型操作) -> dao(单一模型操作) -> model(模型定义 + 扩展方法)

mongoose提供的模型模块有2种

  • statics:类上扩展
  • methods:对象上扩展

根据业务需求来确定,是通过类方法调用,还是通过实体对象上的方法来调用,然后我们根据对应业务,写mongoose相应的扩展即可。下面会分别讲解这2种扩展的差别:

方式1 statics:类上扩展

比如我们有这样一个需求,根据用户名查找用户,调用的时候是放到类上好,还是放在实例上好呢?

  1. UserSchema.statics.find_by_username = function(username, cb) {
  2. return this.findOne({
  3. username: username
  4. }, cb);
  5. };

调用

  1. User.find_by_username(openid, cb)

方式2 methods:对象上扩展

  1. UserSchema.methods.is_exist = function(cb) {
  2. var query;
  3. query = {
  4. username: this.username,
  5. password: this.password
  6. };
  7. return this.model('UserModel').findOne(query, cb);
  8. };

调用

  1. var user = new User({});
  2. user.is_exist(cb)

测试代码

具体测试代码见db/extend/test.js

  1. import test from 'ava';
  2. // 1、引入`mongoose connect`
  3. require('./connect');
  4. // 2、引入`User` Model
  5. const User = require('./user');
  6. // 3、定义`user` Entity
  7. const user = new User({
  8. username: 'i5ting',
  9. password: '0123456789',
  10. openid : 'xxxxxx1'
  11. });
  12. const user2 = new User({
  13. username: 'i5ting for is_exist',
  14. password: '0123456789',
  15. openid : 'xxxxxx2'
  16. });
  17. test('#find_by_username()', t => {
  18. user.save((err, u) => {
  19. t.ifError(err)
  20. User.find_by_username('i5ting', (err, user) => {
  21. t.not(err)
  22. t.not(user)
  23. t.is(user.username, 'i5ting');
  24. t.is(user.password, '0123456789');
  25. })
  26. });
  27. });
  28. test('#is_exist()', t => {
  29. user2.save((err, u) => {
  30. t.ifError(err)
  31. // console.log(user)
  32. var is_exist = u.is_exist();
  33. t.true(is_exist)
  34. });
  35. });
  36. test.after(t => {
  37. User.remove({}, (err, result) => {
  38. })
  39. })

执行测试

  1. $ cd db
  2. $ npm run extend
  3. > koa-db@1.0.0 extend /Users/sang/workspace/17koa/book-source/db
  4. > ava -v extend/test.js
  5. 数据库连接成功
  6. #find_by_username()
  7. 1 test passed