首页
归档
朋友
关于我
留言
Search
1
虚拟机无法ping不通百度,并无法访问浏览器
4,847 阅读
2
mysql使用or条件使索引失效
4,061 阅读
3
mysql如何在一对多查询时选取时间最近的一条记录
3,475 阅读
4
根据MySQL获取当天,昨天,本周,本月,上周,上月,本月的起始时间
2,927 阅读
5
熟悉mysql的共享锁、排它锁、悲观锁、乐观锁以及使用场景
1,766 阅读
PHP
面向对象
设计模式
知识汇总
常用函数
PHP框架知识
数据库
MySQL
服务器
Docker
虚拟机
Nginx
缓存相关
Redis
前端
中间件
RabbitMQ
网络编程
HTTP相关
Swoole
Workerman
工具软件
Git
Typecho
杂乱无章
面试指南
PHP相关
MySQL面试汇总
中间件相关
开发技巧 | 优化
登录
Search
标签搜索
php
mysql
代码片段
linux
Thinkphp
Redis
nginx
mysql优化
docker
面试指南
面向对象
git
Laravel框架
http协议
RabbitMQ
Redis性能优化
设计模式
linux命令
编译安装
PhpSpreadsheet
黎明强
累计撰写
70
篇文章
累计收到
59
条评论
首页
栏目
PHP
面向对象
设计模式
知识汇总
常用函数
PHP框架知识
数据库
MySQL
服务器
Docker
虚拟机
Nginx
缓存相关
Redis
前端
中间件
RabbitMQ
网络编程
HTTP相关
Swoole
Workerman
工具软件
Git
Typecho
杂乱无章
面试指南
PHP相关
MySQL面试汇总
中间件相关
开发技巧 | 优化
页面
归档
朋友
关于我
留言
搜索到
2
篇与
Laravel框架
的结果
2021-06-22
Laravel中的模型(Eloquent ORM)的使用
1. 模型的定义一. 默认设置框架可以使用 Eloquent ORM 进行数据库交互,也就是关系对象模型;在数据库入门阶段,我们已经创建了一个 User.php 模型,如下:php artisan make:model Http/Models/User //默认在 app 目录而调用的时候,我们也知道表名要遵循它默认规则,修改为复数,或 特定;class User extends Model { protected $table = 'user'; }系统假定你的主键为 id,如果你要修改默认主键,可以特定;class User extends Model { protected $primaryKey = 'xid'; //主键 } 系统假定你的主键 id 为自增性,意味着是主键会自动转换 int 类型;如果你希望不是非自增,非数值类型主键,可以设置 $incrementing 取消;public $incrementing = false; //非数字整型主键如果你主键不是一个整数,那么需要$keyType 设置为 string;protected $keyType = 'string'系统默认情况下会接管 created_at 和 updated_at 两个时间戳列;如果不想让系统干涉这两个列,可以设置 false 取消;public $timestamps = false; //取消写入时间戳如果你想自定义时间戳的格式,可以设置;protected $dateFormat = 'U';可以更改创建时间 created_at 和更新时间 updated_at 字段名;const CREATED_AT = 'create_time'; const UPDATED_AT = 'update_time';默认读取 database.php 配置的数据库连接,也可以在模型端局部更改protected $connection = 'mysql';二. 模型定义之前在查询构造器部分,把常用的数据库操作基本讲完,模型大体相同;比如,我们要查询所有数据,直接使用模型::all()即可;//查询所有记录 $users = User::get(); //或 all() return [$users];也可以像查询构造器一样,添加各种各样的条件,写法一样;//查询性别为男,价格大于 90,限制显示 2 条 $users = User::where([ ['gender', '=', '男'], ['price', '>', 95] ])->limit(2)->get();虽然安装了插件,但模型还是没有代码提示,可以通过安装插件解决;composer require barryvdh/laravel-ide-helper php artisan ide-helper:generate // – 为 Facades 生成注释 php artisan ide-helper:models //– 为数据模型生成注释 php artisan ide-helper:meta //– 生成 PhpStorm Meta file其它查询方法基本和查询构造器一样,如果有不一样,参考错误提示;这里列出官网给出示例的方法,对照实验(结合详细文档,重复较多);关于更多 Eloquent ORM 操作, 看手册 ( https://learnku.com/docs/laravel/8.x/eloquent/9406 )(1) .find(1) //通过主键查找 (2) .first() //查找第一个 (3) .firstWhere() //找到查询中的首个 (4) .find([1,2,3]) //通过数组查找 (5) .firstOr() //查找首个返回,支持闭包 (6) .firstOrFail() //找不到时返回异常 (7) .count()、max()等集合 //集合操作 //PS:还有很多在查询构造器中的方法,比如排序、分组子查询等等都可以使用(并未一一验证)。 2. 模型的增删改一. 增操作新增方法如下,注意:默认模型接管 created_at 和 updated_at;$users = new User(); $users->username = '辉夜'; $users->password = '123'; $users->email = 'huiye@163.com'; $users->details = '123'; $users->save();使用 create() 方法实现新增,但需要在模型端设置批量赋值的许可;User::create([ 'username' => '辉夜', 'password' => '123', 'email' => 'huiye@163.com', 'details' => '123', ]); //许可批量赋值,默认不可 protected $fillable = [ 'username', 'password', 'email', 'details' ]; //不许可的批量赋值,不可和$fillable 同时使用 //protected $guarded = ['uid']; //如果取消批量赋值限制,直接如下 protected $guarded = []; //PS:必须在模型中定义批量赋值的可填充字段,否则无法生效;防止用户不小心设置新值;二. 改(更新)操作更新,只要是查找到一条数据的情况下使用 save()就是更新$users = User::find(321); //先查出,返回对象 $users->username = '夜辉'; $users->save();使用 update() 方法实现批量更新;User::where('username', '夜辉') ->update([ 'username' => '辉夜' ]);三. 删操作使用 delete() 方法,可以删除数据;$users = User::find(332); $users->delete(); //批量删除 $users = User::where('username', '夜辉'); //名字带 夜辉都删除掉 $users->delete();如果你是通过主键 id 删除,那使用 destroy(id) 方法,免去查询操作;//通过主键删除 User::destroy(328);3. 批量赋值和软删除一. 批量赋值上一节增删改中,新增中我们发现需要进行批量赋值的许可;一般情况下,是为了防止提交过来的字段在部分场景中不需要或不能;所以,我们需要通过黑白名单机制进行过滤掉必要的字段;//通过提交过来的数据一次性新增 User::create(\Request::all());二. 软删除什么叫软删除?它相对于真实的删除,而并非真正的删除,只是隐藏了;首先,需要在数据库创建一个字段 deleted_at(默认),用于判断是否被软删除;默认设置这个字段为空(null),如果写入数据,成为非空状态,则说明被删除;开启软删除的功能,需要在模型端设置一下://开启软删除功能 use SoftDeletes;当开启了软删除功能,之前的删除操作,都会变成更新操作,给 deleted_at 赋值;//删除一 $users = User::find(82); $users->delete(); //删除二 User::destroy(81);而当我们开启了软删除的功能后,此时通过正常的数据获取列表,会自动隐藏//软删除的数据不可见 $users = User::get(); return [$users]; //单独获取被软删除的数据不行 $users = User::find(82); return [$users];3. 模型的作用域一. 本地作用域(scope)很多情况下,我们在数据查找时有一部分条件会被重复且大量使用;而这个条件,可能只是在这个模型对应的数据表使用,别的表并不使用;那么这种情况,可以使用本地作用域的方式,将常用的 SQL 封装起来;参数用法格式: scope + 自定义方法名比如:用户模块中,我们大量查询需要查询性别为男,且其它条件的 SQL;$users = User::where('gender', '男') ->where('price', '>', 90) ->get(); //PS:我们可以将性别为男这个片段,封装成一个单独的方法,然后统一在这个模型下调用;//AppHttpModels; //本地作用域,搜索自动添加为“男”的条件 //语法:scope 开头,后面名称尽可能包含语义 public function scopeGenderMale($query) { return $query->where('gender', '男');}//当然,如果赶紧单词太长,直接 gm()也行 $users = User::genderMale() ->where('price', '>', 90) ->get();6. **上面的方法比较死板,适合简单粗暴**,如果想要灵活多变,**支持传递参数**; //参数可以是 1 个或多个 $users = User::gender('女', -3) ->where('price', '>', 90) ->get(); //参数 2 和 3,接受控制器传递过来的 1,2 public function scopeGender($query, $value, $value2) { return $query->where('gender', $value)->where('status', $value2);} ### 二. 全局作用域 1. 全局作用域,顾名思义就是在任意地方都可以有效的封装条件; 2. 比如有个需求,不管在哪里操作,总是显示 status 为 1 的用户; 3. 首先在 app 目录下**创建一个用于全局作用域的目录**:`Scopes` ; 4. 创建一个用于设置 status 为 1 的全局作用域的类,它需要实现 `scope 接口` namespace AppScopes; //这里引用代码自动生成 use IlluminateDatabaseEloquentBuilder; use IlluminateDatabaseEloquentModel; use IlluminateDatabaseEloquentScope;class StatusScope implements Scope { public function apply(Builder $builder, Model $model) { // TODO: Implement apply() method. return $builder->where('status', 1); }}5. 此时,还不能实现全局,因为**需要在模型设置个开关**,让其富有灵活性; //启用全局作用域 protected static function booted() { parent::booted(); // TODO: Change the autogenerated stub static::addGlobalScope(new StatusScope());}//PS:而在控制器端,并不需要做任何设置,即可自动添加 status=1 的条件;6. 当然,如果这个全局只是针对某个模块,并不需要创建一个全局类,直接闭包即可; static::addGlobalScope('status', function (Builder $builder) { return $builder->where('status', 1);});//PS:注意 Builder 引入的文件和全局类引入的文件一致,如果引入别的同名类会错;7. 如果某个查询,并**不需要这个全局条件**,可以**单独移出掉**; //取消名称为 status 的全局 $users = User::withoutGlobalScope('status')->get();//取消全局类的条件 $users = User::withoutGlobalScope(StatusScope::class)->get();//PS:还有 withoutGlobalScopes([])方法,传递参数取消多个全局; --- ## 4. 模型的访问和修改器 ### 一. 访问器 1. 访问器:就是在**获取数据列表时,拦截属性并对属性进行修改的过程**; 2. 用法参数格式: `get`+ **字段名** + `Attribute` 3. 比如,我们在输出性别时,在性别左右加上括号,或给邮件转换为大写; //访问器,前固定 get,后固定 Attribute,Gender 是字段名 //参数$value 是源字段值,可修改返回 public function getGenderAttribute($value) { return '【'.$value.'】';}//PS:如果字段名是两个单词中间是下划线:user_name,那么方法名:getUserNameAttribute()4. 我们也可以创建一个虚拟字段,**用已有的数据字段进行整合**,不过要进行数据追加; > 单条数据加上虚拟字段 > **model层** class User extends Model { $protected $table = 'user'; //创建一个虚拟字段 public function getInfoAttribute() { return $this->username.'-'.$this->gender; }} **controller层** $info = User::find(19)->info; //->info dump($info);//打印 名字-性别 > 列表数据加上info虚拟字段 > **注意:**一定要把虚拟字段加到`$appends` **model层** class User extends Model { $protected $table = 'user'; //将虚拟字段追加到数据对象列表里去 protected $appends = ['info']; //创建一个虚拟字段 public function getInfoAttribute() { return $this->username.'-'.$this->gender; }} **controller层** $list = User::all()->toArray();  **注意2** :如果 gender **之前已经有访问器修改过**,上面的方法会**得到修改过的结果**; 5. 如果要使用**源字段进行创建虚拟字段**,需要使用下面这种:`$this->attributes[xxxx]` class User extends Model { $protected $table = 'user'; //将虚拟字段追加到数据对象列表里去 protected $appends = ['info']; //创建一个虚拟字段 public function getInfoAttribute() { return $this->attributes['username'].'-'.$this->attributes['gender']; }}  ### 二. 修改器 1. 修改器,相对于访问器,**是在写入的时候拦截,进行修改再写入**; 2. 用法格式: `set` + **字段名** + `Attribute` //修改器,写入数据时,将邮箱转换为大写 public function setEmailAttribute($value) { $this->attributes['email'] = strtoupper($value);}3. 可以添加默认的日期列,默认 created_at 和 updated_at; //设置可以自动写入日期的列 protected $dates = [ 'details' //详情字段-转换日期格式];4. 可以设置字段输出的类型,比如设置一个布尔型,输出时就是 true 和 false; //设置字段类型 protected $casts = [ 'details' => 'boolean' //详情字段转换布尔类型];5. 注意的是。模型用`create()`方法写入走修改器, 用`insert()`方法不走修改器。
2021年06月22日
974 阅读
0 评论
0 点赞
2021-06-22
Laravel框架中常用的构造器使用
1. 构造器的查询表达式一. select 查询select() 方法可以制定你想要的列,而不是所有列;//设置显示的列,设置列别名 $users = DB::table('users')->select('username as name', 'email')->get(); //对象形式 $users = DB::table('users')->select('username as name', 'email')->get()->toArray(); //数组形式addSelect() 方法,可以在你基础的查询构造器上再增加想要显示的字段;//给已经构建好的查询添加更多字段 $base = DB::table('users')->select('username as name', 'email'); $users = $base->addSelect('gender')->get();DB::raw()方法可以在 select()内部实现原生表达式,否则解析错误;//结合原生 SQL 实现复杂查询 $users = DB::table('users')->select(DB::raw('COUNT(*) AS id, gender')) ->groupBy('gender') ->get();也可以直接使用 selectRaw()方法实现内部原生;//或者直接使用 selectRaw()方法实现原生 $users = DB::table('users')->selectRaw('COUNT(*) AS count, gender') ->groupBy('gender') ->get();还可以通过 havingRaw() 方法实现更精准的分组筛选;//使用 havingRaw 方法实现分组筛选 $users = DB::table('users')->selectRaw('COUNT(*) AS count, gender') ->groupBy('gender') ->havingRaw('count>5') ->get();二. where 查询where()查询,即条件查询,完整形式需要字段表达式和值三个;//where 查询完整形式 $users = DB::table('users')->where('id', '=', 19)->get();大部分情况下,是等于用的比较多,就可以省略掉=号参数;//where 查询完整形式 $users = DB::table('users')->where('id', 19)->get();3.当然,还有>、<、>=、<=、<>、like 等操作符;$users = DB::table('users')->where('price', '>=', 95)->get(); $users = DB::table('users')->where('username', 'like', '%小%')->get();如果条件较多,可以用数组来分别添加条件,具体如下://如果条件都是等于,查看 SQL 语句用->toSql()替换->get() $users = DB::table('users')->where([ 'price' => 90, 'gender' => '男' ])->get(); //如果条件非等于 $users = DB::table('users')->where([ ['price', '>=', 90], ['gender', '=', '男'] ])->get();2. 构造器的where派生查询一. where派生查询orWhere() 方法,可以通过连缀实现两个或以上的 or 条件查询;//where() + orWhere 实现 or 条件查询 $users = DB::table('users') ->where('price', '>', 95) ->orWhere('gender', '女') ->toSql(); //结果 select * from `laravel_users` where `price` > ? or `gender` = ?"通过闭包,我们还可以构建更加复杂的 orWhere 查询;//orWhere()结合闭包查询 $users = DB::table('users') ->where('price', '>', '95') ->orWhere(function ($query) { $query->where('gender', '女') ->where('username', 'like', '%小%'); })->toSql(); //select * from `laravel_users` where `price` > ? or (`gender` = ? and `username` like ?)whereBetween()可以实现区间查询,比如价格在一个区间内的用户;//whereBetween 查询区间价格 60~90 之间 $users = DB::table('users')->whereBetween('price', [60, 90])->toSql(); //PS:这里还支持相关三种:whereNotBetween/orWhereBetween/orWhereNotBetween;whereIn()可以实现数组匹配查询,比如匹配出数组里指定的数据;//whereIn 查询数组里匹配的数值 $users = DB::table('users')->whereIn('id', [20,30,50])->toSql(); //PS:这里还支持相关三种:whereNotIn/orWhereIn/orWhereNotIn;whereNull() 可以查询字段为 Null 的记录;//whereNull 查询字段值为 Null 的记录 $users = DB::table('users')->whereNull('uid')->toSql(); //PS:这里还支持相关三种:whereNotNull/orWhereNull/orWhereNotNull;3. 构造器的排序分组 /子查询一. 排序分组使用 whereColumn() 方法 实现两个字段相等的查询结果 ;//判断两个相等的字段,同样支持 orWhereColumn() //支持符号'create_time','>', 'update_time' //支持符号支持数组多个字段格式['create_time','>', 'update_time'] $users = DB::table('users') ->whereColumn('create_time', 'update_time') ->get();使用 orderBy() 方法实现 desc 或 asc 排序功能。//支持 orderByRaw 和 orderByDesc 倒序方法 $users = DB::table('users') ->orderBy('id', 'desc') ->get();使用 latest() 方法设置时间倒序来排,默认时间字段是 created_at;//按照创建时间倒序排,默认字段 created_at $users = DB::table('users')->latest('create_time')->toSql();使用 inRandomOrder() 方法来随机排序,得到一个随机列表;//随机排序 $users = DB::table('users')->inRandomOrder()->get();使用 skip() 和 take() 限制结果集,或使用 offset() 和 limit();take= limit , skip = offset//从第 3 条开始,显示 3 条 $users = DB::table('users')->skip(2)->take(3)->toSql(); $users = DB::table('users')->offset(2)->limit(3)->get();使用 when() 方法可以设置条件选择,执行相应的 SQL 语句;//when 实现条件选择 $users = DB::table('users')->when(true, function ($query) { $query->where('id', 19); }, function ($query) { $query->where('username', '辉夜'); })->get();如果 MySQL 在 5.7+,有支持 JSON 数据的新特性;$users = DB::table('users')->where('list->id', 19)->first();二. 子查询使用 whereExists() 方法实现一个子查询结果,返回相应的主查询;//通过 books 表数据,查询到 users 表关联的所有用户 $users = DB::table('users')->whereExists(function ($query) { $query->selectRaw(1) ->from('books') ->whereRaw('laravel_books.user_id = laravel_users.id'); })->toSql(); //whereRaw 这句也可以替代为:whereColumn('books.user_id','users.id'); //PS:select 1 from,一般用于子查询的手段,目的是减少开销,提升效率,深入请搜索;也可以使用 where(字段,function())闭包,来实现一个子查询;//id=子查询返回的 user_id $users = DB::table('users')->where('id', function ($query) { $query->select('user_id') ->from('books') ->whereColumn('books.user_id','users.id'); })->toSql();4.构造器的 join一. join查询使用 join 实现内联接的多表查询,比如三张表进行 inner join 查询;$users = DB::table('users') ->join('books', 'users.id', '=', 'books.user_id') ->join('profiles', 'users.id', '=', 'profiles.user_id') ->select('users.id', 'users.username', 'users.email','books.title', 'profiles.hobby') ->get();也可以使用 leftjoin 左连接或 rightjoin 右连接实现多表查询;$users = DB::table('users') ->leftJoin('books', 'users.id', '=', 'books.user_id') ->rightjoin('profiles', 'users.id', '=', 'profiles.user_id') ->get();使用 crossjoin 交叉连接查询,会生成笛卡尔积,再用 distinct()取消重复;$users = DB::table('users') ->crossJoin('books') ->select('username', 'email') ->distinct() ->get();如果你想要实现闭包查询,和 where 类似,只不过要用 on 和 orOn 方法;$users = DB::table('users') ->join('books', function ($join) { //支持 orOn 连缀 $join->on('users.id', '=', 'books.user_id'); })->toSql(); //PS:on()方法后面如果想要再增加筛选条件,可以追加 where();使用 joinSub 实现子连接查询,将对应的内容合并在一起输出;//子连接查询 $query = DB::table('books')->selectRaw('user_id,title'); $users = DB::table('users')->joinSub($query,'books', function ($join) { $join->on('users.id', '=', 'books.user_id'); })->get();使用 union() 或 unionAll() 方法实现两个查询的合并操作;//union 取消重复,unionAll 不取消重复 $query = DB::table('users'); $users = DB::table('users') ->union($query) ->get();5. 构造器的增删改一. 增操作使用 insert() 方法可以新增一条或多条记录;//新增一条记录 DB::table('users')->insert([ 'username' => '李白', 'password' => '123456', 'email' => 'libai@163.com', 'details' => '123' ]); //新增多条记录 (二维数组) DB::table('users')->insert([ [...], [...] ]);使用 insertOrIgnore() 方法,可以忽略重复插入数据的错误;//忽略重复新增数据的错误 DB::table('users')->insertOrIgnore([ 'id' => 304, 'username' => '李白', 'password' => '123456', 'email' => 'libai@163.com', 'details' => '123' ]);使用 insertGetId() 方法,获取新增后的自增 ID;//获取新增后返回的 ID $id = DB::table('users')->insertGetId([ 'username' => '李白', 'password' => '123456', 'email' => 'libai@163.com', 'details' => '123' ]); //返回自增id return $id;二. 改(更新)操作使用 update() 方法,可以通过条件更新一条数据内容;//更新修改一条数据 DB::table('users') ->where('id', 304) ->update([ 'username' => '李红', 'email' => 'lihong@163.com' ]);使用 updateOrInsert() 方法,可以先进行查找修改,如不存在,则新增;//参数 1:修改的条件 //参数 2:修改的内容(新增的内容) DB::table('users')->updateOrInsert( ['id'=>307], ['username'=>'李黑', 'password'=>'654321', 'details'=>'123'] );对于 json 数据,新增和修改的方法和正常数据类似;//新增时,转换为 json 数据 'list' => json_encode(['id'=>19]) //修改时,使用 list->id 指定 DB::table('users')->where('id', 306) ->update([ 'list->id' => 20 ]);更新数据时,可以使用自增 increment() 和自减 decrement() 方法;//默认自增/自减为 1,可设置 DB::table('users')->where('id', 306)->increment('price'); DB::table('users')->where('id', 306)->increment('price', 2);三. 删操作使用 delete() 删除数据,一般来说要加上 where 条件,否则清空;//删除一条数据 DB::table('users')->delete(307); DB::table('users')->where('id', 307)->delete(); //清空 DB::table('users')->delete(); DB::table('users')->truncate();
2021年06月22日
408 阅读
0 评论
0 点赞