ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
[TOC] # 更改 ~~~ $user=User::find(1); //取出主键等于1的记录 $user->user_name='jdxia'; $user->update(); //更新记录 $bool=Student::where('id','>',10)->update( ['age'=>41] ); ~~~ 用attributes ~~~ $post = Post::find(1); $raw = $post->getAttributes(); $post->setRawAttributes($raw); $post->save(); ~~~ ## 批量修改 ~~~ User::where('nickname', 'LIKE', '%man%')->update([ 'nickname' => 'Spider Man', ]); ~~~ > 这种方法不不会触发updating、updated、saving、saved事件 # 查询 这是在控制器写,注意命名空间 ~~~ //all 取出所有 $nm=Student::all(); //get 取出所有 $nm=Student::get(); //findOrFail 根据主键查询,查找到了返回结果,查不到就报错 $nm=Student::findorFail(3); //连贯操作 $nm=Student::where('id','>','2') ->orderBy('age','desc')->first(); //chunk $nm=Student::chunk(2,function($students){ print_r($students); }); //聚合函数 $nm=Student::where('id','>',2)->max('age'); //findMany 根据ID数组查找多行数据 $user = User::findMany([1,2,3,4]); foreach ($users as $user) echo $user->id; ~~~ 一些日期 ~~~ $archives = Post::selectRaw('year(created_at) year, monthname(created_at) month, count(*) published')->groupBy('year','month')->orderByRaw('min(created_at) desc')->get(); $posts = Post::latest(); if ($month = request('month')) { $posts->whereMonth('created_at',Carbon::parse($month)->month); } if ($year = request('year')) { $posts->whereYear('created_at',$year); } $posts = $posts->get(); ~~~ 这里使用了 Laravel 提供的 whereDate 系列方法,同时,月份用 Carbon 进行转换 ## take offset取几条数据 ~~~ //take 取10条数句 $users = User::where('nickname', '=', 'nike')->orderBy('created', 'DESC')->take(10)->get(); //从第20行开始 $users = User::where('nickname', '=', 'nike')->orderBy('created', 'DESC')->take(10)->offset(20)->get(); ~~~ **first 只取一条,并得到Model(非数据集)** 通过first可以将数据提取出首条并返回 `$user = User::where('id', '=', 1)->first();` 查询数据库有没有这条记录 ~~~ //检查用户名是否存在 $user_exists=$this->where('username','=',$username) ->exists(); ~~~ # ORM中添加,自定义时间戳及批量赋值 通过模型新增数据(涉及到自定义事件戳) 使用模型的create方法新增数据(涉及到批量赋值) ## 添加 ~~~ //使用模型新增数据 $student=new Student(); $student->name='sean'; $student->age=18; $bool=$student->save(); //返回布尔值 //上面会自动维护created_at和updated_at,不想用可以关掉 ~~~ 如果我们想存储时间戳呢?记住字段的类型不要搞错 在模型中写 ~~~ protected $table='stu'; //如果主键不是id,指定主键 protected $primarykey='id'; protected function getDateFormat() { return time(); } ~~~ 如果查询的时候想要时间戳怎么办 模型中写 ~~~ protected function asDateTime($val) { return $val; } ~~~ ## create新增数据 批量添加数据,要在模型中写 ~~~ //默认表示模型的复数 protected $table='stu'; //如果主键不是id,指定主键 protected $primarykey='id'; //指定允许批量赋值的字段 protected $fillable=['name','age']; //或者我们设置个这个guarded,就是不允许填充的字段为空数组[],这样就可以填充进去了,就不用写fillable了 protected $guarded=[]; ~~~ 这样就可以用create批量添加的方法 ~~~ $student=Student::create( ['name'=>'jdxia','age'=>18] ); ~~~ ~~~ //以属性查找用户,有就查找,没有就新增并取得新增的实例 $student=Student::firstOrCreate( ['name'=>'jdxia'] ); //firstOrNew() //以属性查找用户,有就查找,没有就显示实例,如需保存需自行调用save $student=Student::firstOrNew( ['name'=>'php'] ); $bool=$student->save(); ~~~ # 删除 通过模型删除 通过主键值删除 根据指定条件删除 ~~~ //通过模型删除数据 $stu=Student::find(12); $bool=$stu->delete(); //通过主键删除 //单个删除 $bool=Student::destroy(11); //多个删除 $bool=Student::destroy(9,10); $bool=Student::destroy([5,6]); //根据指定条件删除 $bool=Student::where('id','>',3)->delete(); ~~~ ## 批量删除 `User::where('nickname', 'LIKE', '%man%')->delete();` >这种方法不不会触发deleting、deleted事件 ## 软删除 SoftDeletes DB类会查出软删除 ~~~ //SQL 库中添加此字段 `deleted_at` timestamp NULL DEFAULT NULL, //Model 中添加 use Illuminate\Database\Eloquent\SoftDeletes; class User { use SoftDeletes; } ~~~ 此时,执行删除操作(delete destory)操作时,并非真正删除数据,只是在deleted_at字段中做了删除标记 此时通过find get where update等操作来获取数据时,会自动忽略这些软删除数据 ## 强制删除 如需要强制删除数据 ~~~ $user = User::find(1); $user->forceDelete(); ~~~ ## 查询结果附带软删除的数据 此时数据集中会附带这些已被软删除的数据,后续操作时,需要自己甄别 `User::withTrashed()->where('nickname', 'Leo')->get();` ## 只返回软删除数据 `User::onlyTrashed()->where('nickname', 'Leo')->get();` ## 恢复软删除数据 ~~~ $user = User::onlyTrashed()->find(12); $user->restore(); ~~~ # 销毁结果集 ~~~ $a=xx::where('id','=',12)->firstorFail(); $a->destory(); ~~~ # 递增和递减 平时这么写: ~~~ $article = Article::find($article_id); $article->read_count++; $article->save(); ~~~ 利用 increment 函数 ~~~ $article = Article::find($article_id); $article->increment('read_count'); ~~~ 当然可以传入数字,不只是只增减 1: ~~~ Article::find($article_id)->increment('read_count'); Article::find($article_id)->increment('read_count', 10); // +10 Product::find($produce_id)->decrement('stock'); // -1 ~~~ # WhereX 这里的 where 是前缀的作用,X表示的是我们的字段名,可以简化我们的查询写法,平时都是这么写的: ~~~ $users = User::where('approved', 1)->get(); ~~~ 简便的写法: ~~~ $users = User::whereApproved(1)->get(); ~~~ 具体实现主要利用 __call 方法。 public mixed __call ( string $name , array $arguments ) public static mixed __callStatic ( string $name , array $arguments ) 在对象中调用一个不可访问方法时,__call() 会被调用。 在静态上下文中调用一个不可访问方法时,__callStatic() 会被调用。 在 Query/Builder.php 中可以看出: ~~~ /** * Handle dynamic method calls into the method. * * @param string $method * @param array $parameters * @return mixed * * @throws \BadMethodCallException */ public function __call($method, $parameters) { if (static::hasMacro($method)) { return $this->macroCall($method, $parameters); } if (Str::startsWith($method, 'where')) { return $this->dynamicWhere($method, $parameters); } $className = static::class; throw new BadMethodCallException("Call to undefined method {$className}::{$method}()"); } ~~~ where 查询方法都会调用函数: ~~~ return $this->dynamicWhere($method, $parameters); ~~~ ~~~ /** * Handles dynamic "where" clauses to the query. * * @param string $method * @param string $parameters * @return $this */ public function dynamicWhere($method, $parameters) { $finder = substr($method, 5); $segments = preg_split( '/(And|Or)(?=[A-Z])/', $finder, -1, PREG_SPLIT_DELIM_CAPTURE ); // The connector variable will determine which connector will be used for the // query condition. We will change it as we come across new boolean values // in the dynamic method strings, which could contain a number of these. $connector = 'and'; $index = 0; foreach ($segments as $segment) { // If the segment is not a boolean connector, we can assume it is a column's name // and we will add it to the query as a new constraint as a where clause, then // we can keep iterating through the dynamic method string's segments again. if ($segment !== 'And' && $segment !== 'Or') { $this->addDynamic($segment, $connector, $parameters, $index); $index++; } // Otherwise, we will store the connector so we know how the next where clause we // find in the query should be connected to the previous ones, meaning we will // have the proper boolean connector to connect the next where clause found. else { $connector = $segment; } } return $this; } ~~~ 继续看 addDynamic 函数: ~~~ /** * Add a single dynamic where clause statement to the query. * * @param string $segment * @param string $connector * @param array $parameters * @param int $index * @return void */ protected function addDynamic($segment, $connector, $parameters, $index) { // Once we have parsed out the columns and formatted the boolean operators we // are ready to add it to this query as a where clause just like any other // clause on the query. Then we'll increment the parameter index values. $bool = strtolower($connector); $this->where(Str::snake($segment), '=', $parameters[$index], $bool); } ~~~ 最后回到了` $this->where(Str::snake($segment), '=', $parameters[$index], $bool); `常规的 where 语句上; 同时,这过程我们可以发现 whereX 方法,不仅可以传入一个字段,而且还可以传入多个字段,用「And」或者 「Or」连接,且字段首字母用大写「A~Z」。 # XorY methods 在平时有太多的写法都是,先查询,再判断是否存在,然后再决定是输出,还是创建。 如: ~~~ $user = User::where('email', $email)->first(); if (!$user) { User::create([ 'email' => $email ]); } ~~~ 一行代码解决: ~~~ $user = User::firstOrCreate(['email' => $email]); ~~~ firstOrCreate 方法将会使用指定的字段 => 值对,来尝试寻找数据库中的记录。如果在数据库中找不到,`5.3`以下版本会使用属性来添加一条记录,`5.3`及以上版本则将使用第一个参数中的属性以及可选的第二个参数中的属性插入记录 用法: ~~~php User::firstOrCreate(['name' => 'Lisi']); User::firstOrCreate(['name' => 'Lisi'], ['age' => 20]); // 5.3及以上版本支持 ~~~ # find() find() 函数通过主键获取数据,平时都是获取单数据,其实传入的参数还可以是「主键数组」,获取多 models。 ~~~ $users = User::find([1,2,3]); ~~~ 我们查看它的函数实现: ~~~ /** * Find a model by its primary key. * * @param mixed $id * @param array $columns * @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection|static[]|static|null */ public function find($id, $columns = ['*']) { if (is_array($id) || $id instanceof Arrayable) { return $this->findMany($id, $columns); } return $this->whereKey($id)->first($columns); } ~~~ 首先判断的是 id 是不是 array,如果是的话,则执行 findMany 函数: ~~~ /** * Find multiple models by their primary keys. * * @param \Illuminate\Contracts\Support\Arrayable|array $ids * @param array $columns * @return \Illuminate\Database\Eloquent\Collection */ public function findMany($ids, $columns = ['*']) { if (empty($ids)) { return $this->model->newCollection(); } return $this->whereKey($ids)->get($columns); } ~~~ 获取的结果是一个 Collection 类型。