Repository 开发
Repository 是数据访问层,封装所有 ORM 查询,是唯一与 Model 交互的层。所有 Repository 继承 core\base\Repository 基类。
基类功能
getModel 抽象方法
每个 Repository 必须实现 getModel() 方法,返回对应的 Model 实例:
php
namespace app\repository\system;
use app\model\system\Admin;
use core\base\Repository;
use think\Model;
class AdminRepository extends Repository
{
protected function getModel(): Model
{
return new Admin();
}
}基类在构造函数中调用 getModel() 并赋值给 $this->model,后续所有查询基于此实例。
内置 CRUD 方法
基类提供以下开箱即用的方法,覆盖常见数据操作:
查询方法
php
// 按主键查找
$admin = $this->adminRepository->find(1);
// 返回: ['id' => 1, 'username' => 'admin', ...] 或 null
// 按条件查找单条
$admin = $this->adminRepository->findWhere(['username' => 'admin']);
// 获取分页列表
$result = $this->adminRepository->getList(
where: ['status' => 1], // 查询条件
page: 1, // 页码
limit: 15, // 每页条数
order: 'id desc' // 排序
);
// 返回: { list: [...], pagination: { current_page, per_page, total, last_page } }
// 获取所有记录(不分页)
$list = $this->adminRepository->getAll(['status' => 1], 'created_at desc');
// 统计数量
$count = $this->adminRepository->count(['status' => 1]);
// 检查是否存在
$exists = $this->adminRepository->exists(['username' => 'admin']);
// 获取单个字段值
$email = $this->adminRepository->value(['id' => 1], 'email');
// 获取字段列表
$usernames = $this->adminRepository->column(['status' => 1], 'username');
$map = $this->adminRepository->column(['status' => 1], 'username', 'id');
// 返回: [1 => 'admin', 2 => 'editor', ...]写入方法
php
// 创建记录
$admin = $this->adminRepository->create([
'username' => 'newadmin',
'password' => 'hashed_password',
'email' => 'admin@example.com',
]);
// 返回创建后的完整数组
// 批量创建
$collection = $this->adminRepository->createAll([
['username' => 'admin1', ...],
['username' => 'admin2', ...],
]);
// 更新记录
$success = $this->adminRepository->update(1, ['nickname' => '新昵称']);
// 返回 bool
// 按条件更新
$affectedRows = $this->adminRepository->updateWhere(
['status' => 0],
['status' => 1]
);
// 删除记录(软删除)
$success = $this->adminRepository->delete(1);
// 按条件删除
$affectedRows = $this->adminRepository->deleteWhere(['status' => 0]);
// 字段自增/自减
$this->adminRepository->inc(['id' => 1], 'login_count');
$this->adminRepository->dec(['id' => 1], 'balance', 100);自定义查询方法
当内置方法无法满足需求时,在 Repository 中添加自定义方法:
关联查询
php
class AdminRepository extends Repository
{
protected function getModel(): Model
{
return new Admin();
}
/**
* 获取管理员列表(包含角色)
*/
public function getListWithRoles(array $where = [], int $page = 1, int $limit = 15): array
{
$query = $this->model->with(['roles'])->where($where);
$total = $query->count();
$list = $query->page($page, $limit)
->order('created_at desc')
->select()
->toArray();
return [
'list' => $list,
'pagination' => [
'current_page' => $page,
'per_page' => $limit,
'total' => $total,
'last_page' => ceil($total / $limit),
],
];
}
}条件查找
php
/**
* 根据用户名查找管理员(含密码字段)
*/
public function findByUsername(string $username): ?array
{
$result = $this->model->where('username', $username)->find();
if (!$result) {
return null;
}
// 登录需要访问密码字段,临时清空隐藏
$result->hidden([]);
return $result->toArray();
}
/**
* 检查用户名是否已存在(排除指定ID)
*/
public function existsUsername(string $username, int $excludeId = 0): bool
{
$query = $this->model->where('username', $username);
if ($excludeId > 0) {
$query->where('id', '<>', $excludeId);
}
return $query->count() > 0;
}复杂更新
php
/**
* 更新最后登录信息
*/
public function updateLastLogin(int $id, string $ip): bool
{
return $this->update($id, [
'last_login_ip' => $ip,
'last_login_time' => date('Y-m-d H:i:s'),
'login_count' => $this->model->where('id', $id)->value('login_count') + 1,
]);
}
/**
* 分配角色(多对多关联同步)
*/
public function assignRoles(int $adminId, array $roleIds): bool
{
$admin = $this->model->find($adminId);
if (!$admin) {
return false;
}
return $admin->roles()->sync($roleIds) !== false;
}返回值约定
- 查询方法统一返回数组(
toArray()),而非 Model 对象 - 单条查询找不到返回
null - 写入方法失败时抛出
BusinessException,不返回false - 分页查询返回
{ list, pagination }结构
注意事项
- Repository 是唯一与 Model 交互的层,Service 和 Controller 不直接使用 Model
- 所有异常由基类自动包装为
BusinessException - 自定义查询方法通过
$this->model访问 ORM,保持查询逻辑集中 - 分页返回格式与前端分页组件对接,包含
current_page、per_page、total、last_page