热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

LaravelEloquentORM对象关系映射(一)

EloquentORM(对象关系映射)ORM,即Object-RelationalMapping(对象关系映射)

Eloquent ORM(对象关系映射)
ORM,即 Object-Relational Mapping(对象关系映射),它的作用是在关系型数据库和业务实体对象之间作一个映射,这样,我们在操作具体的 业务对象时,就不需要再去和复杂的SQL语句打交道,只需简单的操作对象的属性和方法即可。

ORM 两种最常见的实现方式是 ActiveRecord 和 DataMapper,ActiveRecord 尤其流行,在很多框架中都能看到它的身影。两者的区别主要在于 ActiveRecord 中模型与数据表一一对应,而 DataMapper 中模型与数据表是完全分离的。

Laravel 中的 Eloquent ORM 使用的也是 ActiveRecord 实现方式,每一个 Eloquent 模型类对应着数据库中的一张表,我们通过调用模型类的相应方法实现对数据库的增删改查。

2、定义模型
2.1 创建模型

我们使用Artisan命令make:model生成模型类,模型类默认位于app目录下,我们也可以在创建时指定生成目录:

php artisan make:model Models/Post

这样就会在app目录下生成一个Models目录,并且在Models目录下生成一个Post模型类。Laravel 中所有模型类继承自Illuminate\Database\Eloquent\Model类。
2.2 指定表名

如果不手动指定,默认Post对应的数据表为posts,以此类推。也可以通过设置$table属性自定义表名:

public $table = 'posts';

2.3 指定主键

Eloquent默认数据表主键为id,当然也可以通过设置$primaryKey属性来自定义主键:

public $primaryKey = 'id';

2.4 时间戳设置

默认情况下,Eloquent模型类会自动管理时间戳列create_at和update_at(如果定义迁移时设置了这两列的话),如果要取消自动管理,可以设置$timestamps属性为false:

public $timestamps = false;

还有,如果你想要设置时间戳的格式,可以使用$dateFormat属性,该属性决定了日期时间以何种格式存入数据库,以及以何种格式显示:

//设置日期时间格式为Unix时间戳
protected $dateFormat = 'U';

3、查询数据
3.1 获取多个模型

我们可以使用Eloquent模型上的all方法获取所有模型实例
$posts = Post::all();
需要了解的是每一个Eloquent模型本身都是一个查询构建器,所有我们可以调用所有查询构建器上的方法,只不过第一个方法调用都要使用静态方法调用:

$posts &#61; Post::where(&#39;id&#39;,&#39;<&#39;,3)->orderBy(&#39;id&#39;,&#39;desc&#39;)->take(1)->get();
dd($posts);
3.2 获取单个模型

可以使用查询构建器方法获取单个模型实例&#xff1a;

$post &#61; Post::where(&#39;id&#39;,1)->first();
dd($post);

当然也可以通过Eloquent模型类提供的快捷方法find&#xff1a;

$post &#61; Post::find(1);

3.3 聚合函数查询

如果要对查询结果进行计数、统计、最大值/最小值、平均数等聚合运算&#xff0c;可以使用查询构建器上的对应方法&#xff0c;我们我们查询文章总数&#xff1a;

$count &#61; Post::where(&#39;id&#39;,&#39;>&#39;,0)->count();
echo $count;

输出结果为3&#xff0c;又或者我们想要获取文章最大阅读数&#xff1a;

$views &#61; Post::where(&#39;id&#39;,&#39;>&#39;,0)->max(&#39;views&#39;);
echo $views;

调用Eloquent模型类的save方法即可创建模型并插入数据到数据库&#xff1a;

1.2 使用create方法插入数据

除此之外还可以使用create方法插入数据&#xff0c;由于该方法中用到了批量赋值&#xff08;Mass Assignment&#xff09;&#xff0c;所以我们需要在模型类中设置$fillable属性或者$guarded属性&#xff0c;以表明哪些属性可以通过该方法设置&#xff0c;哪些不可以。

开始之前&#xff0c;我们先解释下什么是批量赋值&#xff0c;以及为什么要使用批量赋值。

批量赋值的英文名称是Mass Assignment&#xff0c;所谓的批量赋值是指当我们将一个数组发送到模型类用于创建新的模型实例的时候&#xff08;通常是表单请求数据&#xff09;&#xff0c;我们可以简单通过如下方式实现&#xff1a;

$post &#61; Post::create(Input::all());

而不是像使用save方法那样一个一个的设置属性值&#xff0c;如果模型属性很多的话&#xff0c;使用save简直是噩梦有木有。

但事物总是相对的&#xff0c;使用批量赋值是很方便&#xff0c;但同时也带来了安全隐患&#xff0c;很多时候模型类的某些属性值不是我们所期望通过批量赋值修改的&#xff0c;比如用户模型有个user_type属性&#xff0c;如果用户通过请求数据将其类型修改为管理员类型&#xff0c;这显然是不允许的&#xff0c;正是基于这一考虑&#xff0c;Eloquent模型类为我们提供了$fillable属性和$guarded属性&#xff0c;我们可以将其分别看作“白名单”和“黑名单”&#xff0c;定义在$fillable中的属性可以通过批量赋值进行赋值&#xff0c;而定义在$guarded中的属性在批量赋值时会被过滤掉。

那么如果我们确实想要修改定义在$guarded中的属性怎么办&#xff1f;答案是使用save方法。

此外需要注意的是$fillable和$guarded方法同时只能定义一个&#xff0c;原因嘛很简单&#xff0c;非黑即白&#xff0c;定义了一个另外一个也就确定了。

可见批量赋值不仅为我们创建模型提供了便利&#xff0c;还避免了安全隐患&#xff0c;提高了系统的安全性。

下面我们来演示一下批量赋值的使用。首先在Post模型中定义$guarded属性如下&#xff1a;

protected $guarded &#61; [&#39;views&#39;,&#39;user_id&#39;,&#39;updated_at&#39;,&#39;created_at&#39;];
然后在控制器中实现创建模型实例的逻辑&#xff1a;

$input &#61; [
    &#39;title&#39;&#61;>&#39;test 5&#39;,
    &#39;content&#39;&#61;>&#39;test content&#39;,
    &#39;cat_id&#39;&#61;>1,
    &#39;views&#39;&#61;>100,
    &#39;user_id&#39;&#61;>2
];
$post &#61; Post::create($input);
dd($post);

2、更新模型
2.1 使用save方法更新模型

save方法还可以用于更新模型&#xff0c;要更新模型数据&#xff0c;先要获取该模型实例&#xff0c;然后修改模型属性&#xff0c;再调用save方法保存即可&#xff1a;

$post &#61; Post::find(1);
$post->title &#61; &#39;test 1 title&#39;;
if($post->save()){
    echo &#39;更新文章成功&#xff01;&#39;;
}else{
    echo &#39;更新文章失败&#xff01;&#39;;
}

2.2 使用update方法更新数据

和create相对应的&#xff0c;Eloquent模型类还支持使用update方法更新数据&#xff0c;同样要用到批量赋值&#xff1a;

$input &#61; [
    &#39;title&#39;&#61;>&#39;test 6 title&#39;,
    &#39;content&#39;&#61;>&#39;test content 6&#39;,
    &#39;cat_id&#39;&#61;>1,
    &#39;views&#39;&#61;>200,
    &#39;user_id&#39;&#61;>1
];
$post &#61; Post::find(6);
if($post->update($input)){
    echo &#39;更新文章成功&#xff01;&#39;;
    dd($post);
}else{
    echo &#39;更新文章失败&#xff01;&#39;;
}

1、删除模型
1.1 使用delete删除模型

删除模型很简单&#xff0c;先获取要删除的模型实例&#xff0c;然后调用delete方法即可&#xff1a;

$post &#61; Post::find(5);
if($post->delete()){
    echo &#39;删除文章成功&#xff01;&#39;;
}else{
    echo &#39;删除文章失败&#xff01;&#39;;
}

该方法返回true或false。
1.2 使用destroy删除模型

当然如果已知要删除的模型id的话&#xff0c;可以用更简单的方法destroy直接删除&#xff1a;

$deleted &#61; Post::destroy(5);

你也可以一次传入多个模型id删除多个模型&#xff1a;

$deleted &#61; Post::destroy([1,2,3,4,5]);

调用destroy方法返回被删除的记录数。

1.3 使用查询构建器删除模型

既然前面提到Eloquent模型本身就是查询构建器&#xff0c;也可以使用查询构建器风格删除模型&#xff0c;比如我们要删除所有浏览数为0的文章&#xff0c;可以使用如下方式&#xff1a;

$deleted &#61; Models\Post::where(&#39;views&#39;, 0)->delete();

返回结果为被删除的文章数。
1、查询作用域

Eloquent还支持将一些常用的查询封装到模型方法中&#xff0c;方便调用&#xff0c;我们将其称之为“查询作用域”&#xff0c;实现查询作用域很简单&#xff0c;只需要在模型方法前加上scope前缀即可&#xff0c;比如我们经常需要获取浏览数最高的文章&#xff0c;就可以使用该机制实现——在Post中定义一个scopePopular方法&#xff1a;

public function scopePopular($query)
{
    return $query->where(&#39;views&#39;,&#39;>&#61;&#39;,100);
}

对应的&#xff0c;我们在控制器中定义测试代码如下&#xff1a;

$posts &#61; Post::popular()->orderBy(&#39;views&#39;,&#39;desc&#39;)->get();
foreach ($posts as $post) {
    echo &#39;<&#39;.$post->title.&#39;> &#39;.$post->views.&#39;views
&#39;;
}
2、模型事件

Eloquent也支持模型事件——当模型被创建、更新或删除的时候触发相应事件&#xff0c;Eloquent目前支持八种事件类型&#xff1a;creating、created、updating、updated、saving、saved、deleting、deleted。

deleting和deleted很好理解&#xff0c;在删除模型时触发&#xff0c;deleting在删除操作前执行&#xff0c;deleted在删除完成后执行。

当创建模型时&#xff0c;依次执行saving、creating、created和saved&#xff0c;同理在更新模型时依次执行saving、updating、updated和saved。无论是使用批量赋值&#xff08;create/update&#xff09;还是直接调用save方法&#xff0c;都会触发对应事件&#xff08;前提是注册了相应的模型事件&#xff09;。

你可以在任何你喜欢的地方注册模型事件&#xff0c;这里我们选择在服务提供者AppServiceProvider的boot方法中注册&#xff1a;

Post::saving(function($post){
    echo &#39;saving event is fired
&#39;;
});

Post::creating(function($post){
    echo &#39;creating event is fired
&#39;;
});

Post::created(function($post){
    echo &#39;created event is fired
&#39;;
});

Post::saved(function($post){
    echo &#39;saved event is fired
&#39;;
});

转:https://www.cnblogs.com/ggkxg/p/7380086.html



推荐阅读
  • PDO MySQL
    PDOMySQL如果文章有成千上万篇,该怎样保存?数据保存有多种方式,比如单机文件、单机数据库(SQLite)、网络数据库(MySQL、MariaDB)等等。根据项目来选择,做We ... [详细]
  • 如何在php中将mysql查询结果赋值给变量
    本文介绍了在php中将mysql查询结果赋值给变量的方法,包括从mysql表中查询count(学号)并赋值给一个变量,以及如何将sql中查询单条结果赋值给php页面的一个变量。同时还讨论了php调用mysql查询结果到变量的方法,并提供了示例代码。 ... [详细]
  • 本文详细介绍了SQL日志收缩的方法,包括截断日志和删除不需要的旧日志记录。通过备份日志和使用DBCC SHRINKFILE命令可以实现日志的收缩。同时,还介绍了截断日志的原理和注意事项,包括不能截断事务日志的活动部分和MinLSN的确定方法。通过本文的方法,可以有效减小逻辑日志的大小,提高数据库的性能。 ... [详细]
  • Oracle Database 10g许可授予信息及高级功能详解
    本文介绍了Oracle Database 10g许可授予信息及其中的高级功能,包括数据库优化数据包、SQL访问指导、SQL优化指导、SQL优化集和重组对象。同时提供了详细说明,指导用户在Oracle Database 10g中如何使用这些功能。 ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
  • 猜字母游戏
    猜字母游戏猜字母游戏——设计数据结构猜字母游戏——设计程序结构猜字母游戏——实现字母生成方法猜字母游戏——实现字母检测方法猜字母游戏——实现主方法1猜字母游戏——设计数据结构1.1 ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • 前景:当UI一个查询条件为多项选择,或录入多个条件的时候,比如查询所有名称里面包含以下动态条件,需要模糊查询里面每一项时比如是这样一个数组条件:newstring[]{兴业银行, ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • Java String与StringBuffer的区别及其应用场景
    本文主要介绍了Java中String和StringBuffer的区别,String是不可变的,而StringBuffer是可变的。StringBuffer在进行字符串处理时不生成新的对象,内存使用上要优于String类。因此,在需要频繁对字符串进行修改的情况下,使用StringBuffer更加适合。同时,文章还介绍了String和StringBuffer的应用场景。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • 本文讨论了在数据库打开和关闭状态下,重新命名或移动数据文件和日志文件的情况。针对性能和维护原因,需要将数据库文件移动到不同的磁盘上或重新分配到新的磁盘上的情况,以及在操作系统级别移动或重命名数据文件但未在数据库层进行重命名导致报错的情况。通过三个方面进行讨论。 ... [详细]
  • Oracle10g备份导入的方法及注意事项
    本文介绍了使用Oracle10g进行备份导入的方法及相关注意事项,同时还介绍了2019年独角兽企业重金招聘Python工程师的标准。内容包括导出exp命令、删用户、创建数据库、授权等操作,以及导入imp命令的使用。详细介绍了导入时的参数设置,如full、ignore、buffer、commit、feedback等。转载来源于https://my.oschina.net/u/1767754/blog/377593。 ... [详细]
  • 我们有(据我所知)星型模式SQL数据库中的数据文件。该数据库有5个不同的文件,扩展名为 ... [详细]
  • 本文介绍了一个误删Oracle数据文件导致数据库无法打开的问题,并提供了解决方式。解决方式包括切换到mount状态、离线删除报错的数据文件等。 ... [详细]
author-avatar
nancy_liu_tj
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有