ThinkPHP01:数据库和模型 一、开启调试模式二、配置文件三、URL解析四、数据库五、模型1. 定义模型2. 使用模型① 查询记录② 新增记录③ 删除记录④ 更新记录 3. 字段设
.example.env
文件。把.example
删掉即可开启调试模式。.env
中设置APP_DEBUG = true
.env
用于本地开发测试;config用于部署上线。.env
优先于config
。部署上线时,.env
会被自动忽略。public function config() { echo "env配置:" . env("database.hostname"); echo "
"; echo "config配置:" . config("database.connections.Mysql.hostname");}
class Test { // 控制器默认操作, Http://localhost:8000/test public function index() { return "index"; } // http://localhost:8000/test/hello public function hello() { return "hello"; } // http://localhost:8000/test/hello1?value=world public function hello1($value = "") { return "hello, ". $value; }}
use think\facade\Db;class DataTest { public function index() { $dbs = Db::table('member')->select(); return JSON($dbs); }}
public function index2() { // 查询id为1 $dbs = Db::table('member')->where('id',1)->find(); // 查看sql语句 return Db::getLastSql(); return json($dbs);}
public function index3() { $data = [ "name" => "k", "age" => 12, "email" => "@@@" ]; return $this->memberTable->insert($data);}
use think\Model;class Member extends Model {}
use think\Model;class MemberModel extends Model {protected $name = 'member';}
use think\Model;class MemberModel extends Model {protected $pk = 'uid';}
use think\Model;class MemberModel extends Model {protected $table= 'member';}
use think\Model;class MemberModel extends Model {protected static function init(){parent::init();}}
控制器中引入模型
use \app\model\Member as MemberModel;
use \app\model\Member as MemberModel;class Member { public function index() { $member = MemberModel::select(); $member = MemberModel::find(1); return $member; }}
public function index() { $member = MemberModel::find(1); return $member;}
普通新增
public function insert() { // 新增方式1 $member = new MemberModel(); $member->name = "李白"; $member->age = 18; $member->email = "@"; $member->save(); // 新增方式2 $member = new MemberModel(); $member->save([ 'name' => "李黑", 'age' => 19, 'email' => "@" ]);}
验证新增,设置允许写入的字段
$member->allowField(['name', 'age'])->save([ 'name' => "李黑", 'age' => 19, 'email' => "@"]);
replace新增
$member->replace()->save();
新增成功后,获取自增的ID
$member->id;
批量新增
$member = new MemberModel();$dataAll = [ [ 'name' => "黑李", 'age' => 22, 'email' => "@" ], [ 'name' => "白李", 'age' => 24, 'email' => "@" ],];dump($member->saveAll($dataAll));
使用静态方法 create(新增数组, 允许写入的字段, 是否replace)
,创建要新增的数据。
$member = MemberModel::create([ 'name' => "白李", 'age' => 24, 'email' => "@"], ['name', 'age'], true);echo $member->id;
删除单个,默认根据主键删除。
public function delete() { // 成员方法删除 $member = MemberModel::find(1); $member->delete(); // 静态方法删除 MemberModel::destroy(2);}
批量删除
MemberModel::destroy([3, 4, 5]);
通过闭包删除
MemberModel::destroy(function ($query){$query->where("age", "<", 10);});
普通更新
public function update() { $member = MemberModel::find(8); $member->name = "李四"; $member->age = 120; $member->save();}
强制更新
$member->force()->save();
Db::raw()
执行SQL函数
$member->age = Db::raw("age + 1");
allowField()
限制更新的字段(限制不了raw)。
saveAll()
批量更新,只能根据主键更新,返回被修改的数据集。
静态方法update(数据数组, 限定记录, 限定字段)
MemberModel::update([ 'name' => "占山", 'age' => 15], ['id' => 10], ['name']);
模型的数据字段对应表字段,默认严格区分大小写。
class Member extends Model {// 是否严格区分大小写protected $strict = false;// 设置字段 protected $schema = [ "id" => 'int', 'name' => "string", "age" => "int", "email" => "string" ];}
$schema属性只对模型有效。如果需要Db类也有效,config/database.php 开启字段缓存。
'fields_cache' => true,
在模型中处理数据
class Member extends Model { public function getMemberName($id) { $data = $this->find($id); return $data->getAttr('name'); }}
一个获取器对应模型中的一个特殊方法,该方法是public,方法名格式固定getXxxAttr()
。
获取器的作用是对模型实例的数据做出自动处理。
class Member extends Model { // 获取器,获取数据时自动执行 public function getAgeAttr($value) { if ($value < 18) { return "未成年"; }else{ return "已成年"; } }}
如果定义了获取器,并且需要获取原始值,使用getData()
。
动态获取器withAttr()
public function index6() { $var = MemberModel::select()->withAttr("email", function ($value) { return strtoupper($value); }); return json($var);}
修改器的作用是在新增、修改数据时对数据进行格式化、过滤等处理,方法名格式固定setXxxAttr()
。
修改器只对模型操作有效,对Db类无效。
class Member extends Model { public function setEmailAttr($value) { return strtoupper($value); }}
在模型中封装一个查询或写入的方法,方便控制器调用。方法名格式scopeXxx
。
class Member extends Model { public function scopeAdult($query) { $query->where("age", ">=", 18) ->field("id, name, age") ->limit(3); }}
调用只需要后缀,查询范围只支持find和select。
use \app\model\Member as MemberModel;class Member { public function index7() { $select = MemberModel::adult()->select(); return json($select); }}
全局查询范围,任何查询都需要加上这个范围。
class Member extends Model {// 定义全局查询范围 protected $globalScope = ['status']; public function scopeStatus($query) { $query->where("status", 1); }}
hidden()
,显示某个字段 visible()
,添加获取器字段 append()
,对字段进行函数处理 withAttr()
。自动时间戳会自动写入create_time和update_time两个字段。默认值是int。
全局开启自动时间戳,在config/database.php中设置
'auto_timestamp' => true,
只想设置一个模型开启,在模型中设置
protected $autoWriteTimestamp = true;
自定义新增和修改的时间戳
protected $createTime = "create_at";protected $updateTime = "update_at";
不需要update_time
protected $updateTime = false;
只读字段只支持模型,不支持数据库方式。
只读字段在修改时无法被修改。
protected $readonly = ['name','email'];
动态设置只读字段。
$member->readonly(['name','email'])->save();
类型转换会调用属性里的获取器等操作。
设置类型转换可以在获取数据前将类型转换成需要的类型。
protected $type = ['name' => 'string','price' => 'float',"create_time" => "datetime:Y-m-d"];
当字段不再使用时,可以设置为废弃字段。
protected $disuse = ['status', 'uid'];
软删除不会物理删除记录,相当于全局查询范围。
在模型中设置软删除的功能。
use think\model\concern\SoftDelete;class Member extends Model { use SoftDelete; protected $deleteTime = "delete_time";}
取消屏蔽软删除
UserModel::withTrashed()->select();
显示被软删除的记录
UserModel::onlyTrashed()->select();
还原软删除 restore()
$user = UserModel::onlyTrashed()->find(300);$user->restore();
物理删除
UserModel::onlyTrashed()->find(298)->force()->delete();
关联模型是将表与表之间进行关联和具象化,更高效的操作数据。
主表关联附表(正向关联),hasOne(附表模型, 外键, 主键)
一对一关联,外键默认为主表名_id
。
class profile extends Model {}class Member extends Model { public function profile() { return $this->hasOne(Profile::class); }}
附表关联主表(反向关联),belongsTo()
class Profile extends Model { public function member() { return $this->belongsTo(Member::class, "user_id"); }}
调用模型
use app\model\Member as MemberModel;class Grade { public function index() { $member = MemberModel::find(1); return $member->profile->hobby; }}
关联方式
函数 | 说明 |
---|---|
hasOne | 一对一 |
belongsTo | 一对一 |
hasMany | 一对多 |
hasOneThrough | 远程一对一 |
hasManyThrough | 远程一对多 |
belongsToMany | 多对多 |
morphMany | 多态一对多 |
morphTo | 多态 |
正反向关联
说明 | 正向关联 | 反向关联 |
---|---|---|
一对一 | hasOne | belongsTo |
一对多 | hasMany | belongsTo |
多对多 | belongsToMany | belongsToMany |
远程一对多 | hasManyThrough | \ |
多态一对一 | morphOne | morphTo |
多态一对多 | morphMany | morphTo |
一对一关联修改
$member = MemberModel::find(1);$member ->profile->save(['hobby' => '吃饭']);
一对一关联新增
$member = MemberModel::find(1);$member ->profile()->save(['hobby' => '吃饭']);
正向关联反向操作
$member = MemberModel::hasWhere("prefile", ["id" => 2])->find();
has()
方法查询关联附表的主表内容。
MemberModel::has("profile", ">=", 2)->select();
together()
可以在删除主表内容时,同时删除附表关联的内容。
$member = MemberModel::with('profile')->find(2);$member->together(['profile'])->delete();
新增和一对一关联新增相同。
关联预载入可以减少查询次数提高性能,但不支持多次调用。
$list = MemberModel::with(['profile'])->select([19, 20, 21]);foreach ($list as $member) {dump($member->profile);}
如果主表关联多个附表。
$list = MemberModel::with(['profile', 'book'])->select([19, 20, 21]);foreach ($list as $member) {dump($member->profile.$member->book);}
延迟预载入
$list = MemberModel::select([19, 20, 21]);$list->load(['profile']);foreach ($list as $member) {dump($member->profile);}
统计主表在附表中有多少条记录,包括 withMax、withMin、withCount、withAvg等。
public function index3() { $list = MemberModel::withCount(['profile'])->select([1,2,3]); foreach ($list as $member) { echo $member->profile_count . '
'; }}
关联统计输出采用 关联方法_统计方法
。
hidden
和visible
控制隐藏和显示的字段,append
添加额外字段。
$list = MemberModel::withCount(['profile'])->select([1,2,3]);$list->hidden(['passWord', 'gender', 'profile.status']);
多对多中间表模型类 Pivot。
在模型类中设置多对多关联,belongsToMany(关联模型, 中间表, 外键, 关联键)
public function roles(){return $this->belongsToMany(Role::class, Access::class);}
使用
// 获取用户$member = MemberModel::find(2);// 获取用户权限$roles = $member->roles;
新增,需要通过用户表新增到中间表关联。
$member = MemberModel::find(2);$member->roles->save(Role::find(5));$member->roles->saveAll([1, 2, 3]);$member->roles->attach(5, ["detail" => "测试"]);
删除中间表数据
$member = MemberModel::find(2);$member->detach(5);
在数据库中写入JSON,使用数组方式。用json()
指定JSON字段。
public function insert(){$data = ["name" => "张三","list" => ["nikeName" => "zs", "gender" => "女"]];return Db::name("user")->json(["list"])->insert($data);}
查询数据,需要转换JSON,也需要设置json()
Db::name('user')->json(["list"])->find(15);
修改JSON字段
$data["list"] = ["nikeName" => "zs", "gender" => "女"];Db::name("user")->json(['list']->where('id', 1)->update($data);$data["list->gender"] = "男";Db::name("user")->json(["lsit"])->where('id', 1)->update($data);
在模型中设置JSON字段
protected $json = ["list"];
模型中通过JSON的数据查询
UserModel::where('list->name', "小红")->find();
更新数据
$user = UserModel::find(1);$user->list->name = "小黑";$user->save();
Db::event('事件名', '执行函数')
事件名 | 说明 |
---|---|
before_select | select查询前回调 |
before_find | find查询前回调 |
after_insert | insert操作成功后回调 |
after_update | update操作成功后回调 |
after_delete | dalete操作成功后回调 |
在控制器端,事件一般写在初始化方法里(继承于 BaseController)。
use app\BaseController;use think\facade\Db;class Member extends BaseController { public function initialize() { Db::event("before_select", function ($query) { echo "执行了批量查询"; }); Db::event("after_update", function ($query) { echo "修改被执行"; }); }}
class Member extends Model { protected static function onAfterRead($query){ echo "一条数据被查询"; } protected static function onBeforeUpdate(Model $model) { parent::onBeforeUpdate($model); // TODO: Change the autogenerated stub }}
来源地址:https://blog.csdn.net/realoser/article/details/129532478
--结束END--
本文标题: ThinkPHP01:数据库和模型
本文链接: https://lsjlt.com/news/391651.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0