lumen_rule_model.md 4.89 KB

LUMEN+API Model规范

1. Model规范

  • 使用Model实现数据业务处理,包括数据表和数据关联表的增删改查。

  • 对于各个表的Model, 继承自定义的BaseModel类,而不是Model类

  • 如果表和表之间有一定的关系,1vs1, 1vsN,那在Model中使用hasOne,belongsTo进行映射,通过这样的映射,可以对Model对象实现很清晰的操作逻辑:

  class GroupModel extends BaseModel {

     /**
      * @return GroupModel
      */
     public function getInstanceByGroupCode($code) {
        return $this->where('group_code',$code)->first();
     }

     public function weixinGroupInfo() {
         return $this->hasOne(WeixinGroupInfo::class,'group_id','group_id');
     }

     /**
      * @return WeixinGroupInfo
      */
     public function myWeixinGroupInfo() { 
       return $this->weixinGroupInfo()->first(); 
     }

    public funciton groupSites() {
        return $this->hasMany(GroupSite::class,'group_id','group_id');
    }

    /**
     * @return Collection
     */
    public function myGroupSites() {
        return $this->groupSites->get();
    }

    public function getMyGroupName() {
       return isset($this->group_name) ? $this->group_name : null;
    }
  }

  $groupInstance = (new GroupModel())->getInstanceByGroupCode('Foo');
  $groupWeixinInfoInstance = $groupInstance->myWeixinGroupInfo();
  $groupSites = $groupInstance->myGroupSites()->filter( function($site) {/**/ });


  • Model必须实现数据表的增删改操作,不能让这些操作暴露在Controller或者Service中
  class UserModel extends BasicModel 
  {
      public function insertUser(array $userInfo) { /**/ }
      public function updateUser(array $userInfo) { /**/ }
        /* 如有必要,更新字段的操作颗粒度可以降底到每一项 */
      public function updateUserLoginName ($userId,$userName) {/**/}
      public function deleteUserById($userId) {/**/}
  }
  • Model层函数的返回,都要写明注释(尤其是参数和返回值类型),以便Controller调用时,可以智能感知和减少错误发生的机率。
  /**
   * 增加一个新的用户,成功的情况下,返回用户对象
   * @param array userInfo 
   *  ['userName','userSex','userDesc']
   * @result App\Models\User
   */
  public function insertUser(array $userInfo) {
     $this->arrValidation($userInfo, [
        'userName' => 'required|string|min:6'
     ]);
     $newUser = new User();
     $newUser->user_name = userInfo['userName'];
     $newUser->user_sex  = isset($userInof['userSex']) ? $userInfo['userSex'] : GlobalSystem::MALE;
     $newUser->user_desc = isset($userInof['userDesc']) ? $userInfo['userDesc'] : '';

     $newUser->save();

     return $newUser;
  }
  • 不要使用scope类型的函数。

  • 在函数上区分并辩明属于Model的方法和属于Instance的方法。

所谓Model方法,是指new一个Model实例即可调用的方法,对于操作库,可以使用Model方法

所谓Instance方法,是指对应的数据表中的一个实例,例如,通过User::find(1)即可获得一个Instance方法。

Instance方法一般用来获得属性,实现实例的业务逻辑,操作与此实例关联的其它数据模型的实例。

一般来说,在Instance方法上,加一个My修饰词进行表示。

  public function insertUser(array $userInfo);  // Model方法
  public function getMyUserName() { return $this->user_name; } // Instance方法
  public function checkMyRoles() { /**/ }
  • 在Model层所实现的业务逻辑上,要把业务边界分清楚,比如对于Group/Site这样的业务来说,Group可以代理Site的一些操作,但是具体涉及到Site数据操作,需要交给Site模型进行。
  class Group extends BaseModel
  {
     /* 假设groupInfo中涵盖了site的信息 */
     public function receiveGroupInfoEvent($groupInfo) {
        $this->updateGroup($groupInfo);
        if(isset($groupInfo['sites'])) {
           $this->updateGroupSites($groupInfo['sites']);
        }
     }

     public function updateGroup($groupInfo) {
         // do group update
     }

     public function updateGroupSites($siteList) {
         foreach($siteList as $siteInfo)
           (new Site())->updateSite($siteInfo);
     }
  }
  • BaseModel的一些基本操作

| 索引 | 函数方法 | 备注 | | ---- | ----------------------- | ---------------------------------------- | | 1 | getInstanceById | Model方法,根据关键字获得Instance对象 | | 2 | getMyId | Instance方法,获得主ID | | 3 | getTable | Model方法,获得数据表名称 | | 4 | toSql | Model方法,查询时可以将其转换为SQL语句 | | 5 | getQueryByConditions | Model方法,基础的条件查询,一些场合下可以代替where语句 | | 6 | checkValidItem | Model方法,查询符合条件的数据有多少项 | | 7 | updateItemsByPrimaryId | Model方法,根据ID更新数据表项 | | 8 | updateItemsByConditions | Model方法,根据条件更新数据表项 | | 9 | checkObjectIdExist | Instance方法,检查调用实例是否Instance对象,如果不是,则抛出异常 |

?