# 模型架构
* * * * *
在看模型架构之前,需要将 ModelBase 类中的代码仔细阅读一遍,代码如下
~~~
<?php
// +---------------------------------------------------------------------+
// | OneBase | [ WE CAN DO IT JUST THINK ] |
// +---------------------------------------------------------------------+
// | Licensed | http://www.apache.org/licenses/LICENSE-2.0 ) |
// +---------------------------------------------------------------------+
// | Author | Bigotry <3162875@qq.com> |
// +---------------------------------------------------------------------+
// | Repository | https://gitee.com/Bigotry/OneBase |
// +---------------------------------------------------------------------+
namespace app\common\model;
use think\Model;
use think\Db;
/**
* 模型基类
*/
class ModelBase extends Model
{
// 查询对象
private static $ob_query = null;
/**
* 状态获取器
*/
public function getStatusTextAttr()
{
$status = [DATA_DELETE => '删除', DATA_DISABLE => '禁用', DATA_NORMAL => '启用'];
return $status[$this->data[DATA_STATUS_NAME]];
}
/**
* 设置数据
*/
final protected function setInfo($data = [], $where = [], $sequence = null)
{
$pk = $this->getPk();
$return_data = null;
if (empty($data[$pk])) {
$return_data = $this->allowField(true)->save($data, $where, $sequence);
} else {
is_object($data) && $data = $data->toArray();
!empty($data[TIME_CT_NAME]) && is_string($data[TIME_CT_NAME]) && $data[TIME_CT_NAME] = strtotime($data[TIME_CT_NAME]);
$default_where[$pk] = $data[$pk];
$return_data = $this->updateInfo(array_merge($default_where, $where), $data);
}
return $return_data;
}
/**
* 新增数据
*/
final protected function addInfo($data = [], $is_return_pk = true)
{
$data[TIME_CT_NAME] = TIME_NOW;
$return_data = $this->insert($data, false, $is_return_pk);
return $return_data;
}
/**
* 更新数据
*/
final protected function updateInfo($where = [], $data = [])
{
$data[TIME_UT_NAME] = TIME_NOW;
$return_data = $this->allowField(true)->where($where)->update($data);
return $return_data;
}
/**
* 统计数据
*/
final protected function stat($where = [], $stat_type = 'count', $field = 'id')
{
return $this->where($where)->$stat_type($field);
}
/**
* 设置数据列表
*/
final protected function setList($data_list = [], $replace = false)
{
$return_data = $this->saveAll($data_list, $replace);
return $return_data;
}
/**
* 设置某个字段值
*/
final protected function setFieldValue($where = [], $field = '', $value = '')
{
return $this->updateInfo($where, [$field => $value]);
}
/**
* 删除数据
*/
final protected function deleteInfo($where = [], $is_true = false)
{
if ($is_true) {
$return_data = $this->where($where)->delete();
} else {
$return_data = $this->setFieldValue($where, DATA_STATUS_NAME, DATA_DELETE);
}
return $return_data;
}
/**
* 获取某个列的数组
*/
final protected function getColumn($where = [], $field = '', $key = '')
{
return Db::name($this->name)->where($where)->column($field, $key);
}
/**
* 获取某个字段的值
*/
final protected function getValue($where = [], $field = '', $default = null, $force = false)
{
return Db::name($this->name)->where($where)->value($field, $default, $force);
}
/**
* 获取单条数据
*/
final protected function getInfo($where = [], $field = true, $join = null, $data = null)
{
empty($join) ? self::$ob_query = $this->where($where)->field($field) : self::$ob_query = $this->join($join)->where($where)->field($field);
return $this->getResultData(DATA_DISABLE, $data);
}
/**
* 获取列表数据
*/
final protected function getList($where = [], $field = true, $order = '', $paginate = 0, $join = [], $group = '', $limit = null, $data = null)
{
if(is_string($where)) : return $this->query($where); endif;
empty($join) && !isset($where[DATA_STATUS_NAME]) && $where[DATA_STATUS_NAME] = ['neq', DATA_DELETE];
self::$ob_query = $this->where($where)->order($order)->field($field);
!empty($join) && self::$ob_query = self::$ob_query->join($join);
!empty($group) && self::$ob_query = self::$ob_query->group($group);
!empty($limit) && self::$ob_query = self::$ob_query->limit($limit);
if (DATA_DISABLE === $paginate) : $paginate = DB_LIST_ROWS; endif;
return $this->getResultData($paginate, $data);
}
/**
* 获取结果数据
*/
final protected function getResultData($paginate = 0, $data = null)
{
$result_data = null;
$backtrace = debug_backtrace(false, 2);
array_shift($backtrace);
$function = $backtrace[0]['function'];
if($function == 'getList') {
$paginate != false && IS_POST && $paginate = input('list_rows', DB_LIST_ROWS);
$result_data = false !== $paginate ? self::$ob_query->paginate($paginate, false, ['query' => request()->param()]) : self::$ob_query->select($data);
} else {
$result_data = self::$ob_query->find($data);
}
self::$ob_query->removeOption();
return $result_data;
}
/**
* 原生查询
*/
final protected function query($sql = '')
{
return Db::query($sql);
}
/**
* 原生执行
*/
final protected function execute($sql = '')
{
return Db::execute($sql);
}
/**
* 重写获取器 兼容 模型|逻辑|验证|服务 层实例获取
*/
public function __get($name)
{
$layer = $this->getLayerPrefix($name);
if(false === $layer) : return parent::__get($name); endif;
$model = sr($name, $layer);
return LAYER_VALIDATE_NAME == $layer ? validate($model) : model($model, $layer);
}
/**
* 获取层前缀
*/
public function getLayerPrefix($name)
{
$layer = false;
$layer_array = [LAYER_MODEL_NAME, LAYER_LOGIC_NAME, LAYER_VALIDATE_NAME, LAYER_SERVICE_NAME];
foreach ($layer_array as $v)
{
if(str_prefix($name, $v)) : $layer = $v; break; endif;
}
return $layer;
}
}
~~~
namespace app\common\model 可以看到 ModelBase 是在common模块,意味着这个模型是其他模块的模型都要继承的。
class ModelBase extends Model 意味着这个类是一个Model的子类,还有一点 其实服务层和逻辑层都间接继承自ModelBase,因为系统中99%的数据库操作都需要经过这里。
这个状态获取器是TP5的特性,封装在此处是因为几乎所有的表中都需要一个数据状态字段,所以写在这里以后所有的查询就会自动将对应的文本显示出来。
下面都是一些数据操作相关的封装,$this是指当前引用的数据模型实例,此处封装的都是在OneBase开发中需要使用到的一些操作,在最后为了满足其他复杂未知的业务需求又添加了 query方法 与 execute 方法,对接的都是TP5的方法,当然也可以在中间进行一些自己特殊的处理。
若开发者的业务需求中数据库操作满足不了的情况下有两个选择:
1.使用 query 与 execute 来实现原生sql操作
2.在ModelBase中添加自己封装的通用数据库操作
下面的__get方法在依赖注入篇中已经介绍过了,此处就不作介绍。
另外作者建议尽量将系统中的数据库操作都集中再此处方便后期进行扩展及维护,尽量不要在控制器中直接使用此处的方法。
- 序言
- 基础
- 安装环境
- 安装演示
- 规范
- 目录
- 介绍
- 后台介绍
- 后台首页
- 会员管理
- 系统管理
- 系统设置与配置管理
- 菜单管理
- 系统回收站
- 服务管理
- 插件管理
- 文章管理
- 接口管理
- 优化维护
- SEO管理
- 数据库
- 文件清理
- 行为日志
- 执行记录
- 统计分析
- 接口介绍
- 接口文档
- 错误码设计
- Token介绍
- 前台介绍
- 架构
- 架构总览
- 生命周期
- 入口文件
- 模块设计
- 依赖注入
- 控制器架构
- 逻辑架构
- 验证架构
- 服务架构
- 模型架构
- 行为架构
- 插件架构
- 配置
- 配置介绍
- 配置加载
- 配置扩展
- 请求
- 请求信息
- 日志
- 后台行为日志
- 系统执行日志
- 框架日志
- 数据
- 数据库设计
- 数据字典
- 数据库操作
- 事务控制
- 混合操作
- 实战
- 控制器
- 逻辑与验证
- 视图与模型
- 插件研发
- 服务研发
- 接口研发
- 杂项
- 数据导入导出
- 二维码条形码
- 邮件发送
- 云存储服务
- 支付服务
- 短信服务
- 微信分享
- 生成海报
- 聊天室
- PJAX
- Demo
- Widget
- 附录
- 常量参考
- 配置参考
- 函数参考
- 进阶
- Redis
- 自动缓存
- 全自动缓存
- 索引
- 数据签名
- 全自动事务
- 队列