数据库和数据模型
laravel的多态关联--morphTo和morphMany
Laravel Eager Loading - load() Vs. with()
Laravel5.5+ 使用API Resources快速输出自定义JSON方法详解
One To One | User hasOne Phone | Phone belongsTo User | hasOne('model', 'own_id', 'id') |
One To Many | Post hasMany Comments | Comment belongsTo Post | |
Many to Many | User belongsToMany Role | Role belongsToMany User | |
has Many through | |||
O2M Polymorphic relation | |||
M2M Polymorphic relation |
load-with,attach-detach
数据关联模型: ***One To One: User hasOn Phone class User extends Model { function phone() { return $this->hasOne('App\Phone', 'owner_id', 'id'); //phones.own_id = users.id } } class Phone extends Model { function user() { return $this->belongsTo('App\User'); } } ***One To Many: Post HasMany Comments class Post extends Model { function comments() { return $this->hasMany('App\Comments'); } } class Comment extends Model { function post() { return $this->belongsTo('App\Post'); } } Many To One Many To Many. attach,detach,sync只对Many To Many 三个关联表: feed_topics, users, feed_topic_user_links class FeedTopic extends Model { public function users() : BelongsToMany { $table = (new FeedTopicUserLink)->getTable(); return $this ->belongsToMany(User::class, $table, 'topic_id', 'user_id') ->withPivot('index', Model::CREATED_AT, 'following_at', 'can_pub') ->using(FeedTopicUserLink::class); } }
调用vendor\laravel\framework\src\Illuminate\Database\Query的toSql方法: $query->toSql(); DB::connection()->enableQueryLog(); $count = DB::table('test') ->whereNull('deleted_at') ->where('id', '=', 3) ->where('Name', '=', '测试') ->count(); print_r(DB::getQueryLog());
设置model事件observer
$data = User::distinct()->offset(10)->limit(10)->get()->toArray(); DB::table('users')->first(); DB::table('users')->pluck('name'); //返回一个字符串 DB::table('users')->lists('name'); //返回字符串数组 DB::table('users')->lists('name', 'email'); //返回数组,email => name with关联表查询 $category = Category::with('goods')->find($categoryId); $category = Category::with(['goods' => function ($query) { $query->where('is_sale', true); }])->find($categoryId); Affair::query() ->when($request->has('offset'), static function (Builder $builder) use ($request) { return $builder->offset($request->query('offset', 0)) ->limit($request->query('limit', config('app.data_limit'))) ->get(); }, static function (Builder $builder) use ($request) { return $builder->paginate($request->query('limit', config('app.data_limit'))); }); class UserObserver { public function creating(User $user) {} public function created(User $user) {} public function updateing(User $user) {} public function updated(User $user) {} public function deleteing(User $user) {} public function deleted(User $user) {} public function retoring(User $user) {} public function restored(User $user) {} } class UserServiceProvider extends ServiceProvider { public function boot() { User::observer(UserObserver); } public function register() { } }
Model
连接多个数据库 config/database.php 'mysql_old' = [ 'driver' => 'mysql', 'host' => env('DB_HOST_OLD', '127.0.0.1'); 'post' => env('DB_POSR_OLD', '3306'); ]; $user = DB::connection('mysql_old')->select('select * from users'); DB::connection('mysql_old')->table('users')->insert() 数据库读写分离 'mysql' => [ 'driver' => 'mysql', 'read' => [ 'host' => env('DB_HOST_READ', '127.0.0.1'); ], 'write' => [ 'host' => env('DB_HOST_WRITE', '127.0.0.1'); ], ]; 手动执行SQL语句: DB门面执行原生语句 DB::statement('drop table user'); DB::statement('create table users(...) ...'); $users = DB::select('select * from users'); DB::insert('...'); DB::update('...'); DB::delete('...'); 多数据库: DB::connection('mysql_old')->select('...'); DB::connection('mysql_old')->insert('...'); $users = DB::table('users')->where('name', $name)->get(); $flag = DB::table('users')->insert([ 'name' => 'xiao', 'email' => 'a@163.com', 'passwd'=> bcrypt('secret'); ]); json查询 DB::table('users')->where('options->language', 'en')->get(); 两段提交: 手动执行事务 DB::beginTransaction(); DB::commit(); DB::rollback(); 数据库事务 DB::transaction(function() { DB::table('users')->update(['votes'=>1]); DB::table('posts')->delete(); }); try{ DB::transaction(function ()use($id,$data) { DB::table('supplier')-> where('id',$id) -> update($data); }); }catch(\Illuminate\Database\QueryException $ex){ return back() -> with(['info' => '抱歉,修改失败,请稍后重试!']); } return redirect('admin/buy/supplier') -> with(['info' => '修改成功']); DB::beginTransaction(); //事务开始 try { DB::insert(...); DB::insert(...); DB::insert(...); DB::commit(); } catch(\Illuminate\Database\QueryException $ex) { DB::rollback(); // something went wrong } 改变模型的缺省定义 class Article extends model { protected $connection = 'mysql_new'; protected $table = "article"; protected $primaryKey = 'post_id'; public $incrementing = false; protected $keyType = 'string'; public $timestamps = false; //表不包含create_at, update_at字段 protected $dateFormat = 'U'; //默认是Y-m-d H:i:s, 设置为unix时间戳 protected $guarded = ['user_id']; } $post = new Post($request->all()); $post->user_id = 0; //单独设置变量,guarded设置后 $post->save(); $post->fill($request->all()); //更新模型 $post->save(); 访问器 public function getDisplayNameAttribute() { return $this->nickname ? $this->nickname : $this->name; } 定义模型读属性 $user->display_name; 修改器 public function setCardNoAttribute($value) { $value = str_replace(' ', '', $value); $this->attribute['card_no'] = encrypt($value); } 定义模型写属性 $user->card_no = '12333343'; 全局作用域, 重载boot protected statis function boot() { parent::boot(); static::addGlobalScope('email_verified_at_scope', function(Builder $builder) { return $builder->whereNotNull('email_verified_at'); }); } 取消全局作用域: User::withoutGlobalScope(EmailVerifiedAtScope::class)->get(); # 指定类 User::withoutGlobalScope('email_verified_at_scope')->get(); # 匿名函数 User::withoutGlobalScopes()->get(); # 移除所有全局作用域 User::withoutGlobalScopes([FirstScope::class, SecondScope::class])->get(); # 移除多个类/匿名函数 局部作用域 public function scopePopular(Builder $query) { return $query->where('views', '>', '0')->orderBy('views','desc'); } public function scopeActive(Builder $query) { return $query->where('status', Post::ACTIVE); } 调用:$post = Post::active->popular->find(10); 动态作用域 public function scopeOfType(Builder $query, $tpe) { reutrn $query->where('type', $type); } 调用:$post = Post::active->ofType(Post::Article)->get(); 静态方法监听模型事件 订阅者监听模型事件 观察者监听模型事件 远程一对多 country - user -post
软删除
//1、第一种方法 Post::find(5)->delete(); //2、第二种方法(主键删除) Post::destroy(5) Post::destroy(1,2,3) //3、第三种方法 Post::where('views', 0)->delete(); 软删除 数据库中添加deleted_at字段 use Illuminate\Database\Eloquent\SoftDeletes; class Post extends Model { use SoftDeletes; } 包含软删除查询 Post::withTrashed()->find('1'); Post::withTrashed()->where('id','>',1)->get(); Post::withTrashed()->all(); 只包含软删除记录: Post::onlyTrashed()->where('id', 1)-get(); 软删除查询恢复 //恢复单个 Post::withTrashed()->find(1)->restore(); //恢复多个模型 Post::withTrashed()->where('id','>',1)->restore(); //恢复所有模型 Post::withTrashed()->restore(); 强制删除 //删除单个 Post::withTrashed()->find(1)->forceDelete(); //删除多个模型 Post::withTrashed()->where('id','>',1)->forceDelete(); //删除所有模型 Post::withTrashed()->forceDelete(); 关联模型 public function user() { return $this->belongsTo('App\User')->withTrashed(); }
select * from `feeds` inner join `feed_topic_links` on `feeds`.`id` = `feed_topic_links`.`feed_id` and `feed_topic_links`.`topic_id` = ? where `audit_status` = ? and `feeds`.`deleted_at` is null order by `id` desc $feeds = $model ->query() ->with(['topics', 'user']) ->when($topic = $request->query('topic'), function ($query) use ($topic) { $query->join('feed_topic_links', function ($query) use ($topic) { return $query->on('feeds.id', 'feed_topic_links.feed_id') ->where('feed_topic_links.topic_id', $topic); }); }) ->when($request->has('audit_status'), function ($query) use($request) { $status = $request->query('audit_status'); if ($status == 3) { return $query->onlyTrashed(); } return $query->where('audit_status', $status); }) ->orderBy('id', 'desc');
Laravel中RBAC的modle层(超简)
关于用户model层 /** * 用户有哪些角色 */ public function roles() { // 使用withPivot可以把关系表中的字段获取出来 return $this ->belongsToMany(\App\AdminRole::class, 'admin_role_user', 'user_id', 'role_id') ->withPivot(['user_id', 'role_id']); } /** * 用户是否有某个角色(某些角色) */ public function isInRoles($roles) { return !!$roles->intersect($this->roles)->count(); } /** * 用户是否有某个权限 */ public function hasPermission($permission) { return $this->isInRoles($permission->roles); } /** * 给用户分配角色 */ public function assignRole($role) { return $this->roles()->save($role); } /** * 取消用户的角色 */ public function deleteRole($role) { return $this->roles()->detach($role); } 关于角色层的model /** * 当前角色的所有权限 */ public function permissions() { return $this ->belongsToMany(\App\AdminPermission::class, 'admin_permission_role', 'role_id', 'permission_id') ->withPivot(['role_id', 'permission_id']); } /** * 给角色分配权限 */ public function grantPermission($permission) { return $this->permissions()->save($permission); } /** * 取消角色的权限 */ public function deletePermission($permission) { return $this->permissions()->detach($permission); } /** * 判断角色是否有权限 */ public function hasPermission($permission) { return $this->permissions->contains($permission); } 关于权限层的model /** * 当前权限属于哪个角色 */ public function roles() { return $this ->belongsToMany(\App\AdminRole::class, 'admin_permission_role', 'permission_id', 'role_id') ->withPivot(['role_id', 'permission']); }