学习笔记20251225
用户登录流程
控制器、服务、DAO模型之间的数据流图
flowchart TD
A[客户端请求] --> B(API控制器<br>LoginController->login)
B --> C{控制器<br>进行参数验证}
C -->|成功| D[登录服务<br>LoginService->login]
C -->|失败| E[返回错误JSON]
D --> F[用户DAO<br>userDao->getOne]
F --> G{服务进行<br>查询结果判断}
G -->|用户存在| H[生成Token]
G -->|用户不存在| E
H --> I[返回成功JSON<br>附带Token]
E --> J((响应端))
I --> J
数据访问对象(DAO)
封装数据访问操作,提供统一接口。
基类的设计
<?php
// app/common/dao/BaseDao.php
namespace app\common\dao;
use think\Model;
/**
* 基础数据访问对象 - 抽象类
*/
abstract class BaseDao
{
// 核心:子类必须返回对应的模型实例
abstract protected function getModel(): Model;
// 1. 查单条 (根据ID)
public function getById($id, $field = '*')
{
return $this->getModel()->field($field)->find($id);
}
// 2. 查单条 (根据条件)
public function getOne(array $where, $field = '*')
{
return $this->getModel()->where($where)->field($field)->find();
}
// 3. 查列表
public function getList(array $where = [], $field = '*', $order = 'id DESC', $limit = 0)
{
$query = $this->getModel()->where($where)->field($field)->order($order);
if ($limit) $query->limit($limit);
return $query->select();
}
// 4. 新增
public function create(array $data)
{
return $this->getModel()->insertGetId($data);
}
// 5. 更新 (根据ID)
public function updateById($id, array $data)
{
return $this->getModel()->where('id', $id)->update($data);
}
// 6. 删除 (根据ID)
public function deleteById($id)
{
return $this->getModel()->where('id', $id)->delete();
}
/**
* 魔术方法:转发到模型查询构造器,处理复杂查询
* @param string $method
* @param array $args
* @return mixed
*/
public function __call(string $method, array $args)
{
// 将未定义的方法调用转发到底层模型,保留ThinkPHP链式操作的全部能力
return call_user_func_array([$this->getModel(), $method], $args);
}
}
用户DAO的实现
<?php
// app/common/dao/user/UserDao.php
namespace app\common\dao\user;
use app\common\dao\BaseDao;
use app\common\model\user\User;
class UserDao extends BaseDao
{
// 唯一必须实现的方法:告诉BaseDao操作哪个表
protected function getModel(): User
{
// 简单返回模型类即可
return new User();
// 或使用容器:return app(User::class);
}
// 可选:扩展自己的特殊查询方法
public function getByPhone($phone)
{
return $this->getModel()->where('phone', $phone)->find();
}
}
拓展:抽象类的特点
| 特点 | 说明 |
|---|---|
| 不能直接实例化 | 最重要的特性。你不能用 new AbstractClass() 创建对象。它存在的意义就是被继承。 |
| 可以包含抽象方法 | 使用 abstract 关键字声明(如 abstract public function save();)。只有方法签名,没有方法体(花括号 {} 部分)。子类必须实现这些方法。 |
| 可以包含具体方法 | 可以像普通类一样,拥有已经实现了的属性和方法。子类可以直接继承和使用这些具体实现。 |
| 通过继承实现 | 子类使用 extends 关键字继承抽象类。一个子类只能继承一个抽象类(单继承)。 |
作者:需要成长的小哥
出处:https://www.cnblogs.com/myDreamRealization/
如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!
如果希望更容易地发现我的新博客,记得在左下角点个“关注我”哦。(如有错误之处,还请指正!)
出处:https://www.cnblogs.com/myDreamRealization/
如果觉得这篇文章对你有小小的帮助的话,记得在右下角点个“推荐”哦,博主在此感谢!
如果希望更容易地发现我的新博客,记得在左下角点个“关注我”哦。(如有错误之处,还请指正!)

浙公网安备 33010602011771号