Gitlib Gitlib
首页
  • 分类
  • 标签
  • 归档
  • Golang开发实践万字总结
  • MySQL核心知识汇总
  • Redis实践总结
  • MQ实践万字总结
  • Docker数据持久化总结
  • Docker网络模式深度解读
  • 常用游戏反外挂技术总结
  • 读书笔记
  • 心情杂货
  • 行业杂谈
  • 友情链接
关于我
GitHub (opens new window)

Ravior

以梦为马,莫负韶华
首页
  • 分类
  • 标签
  • 归档
  • Golang开发实践万字总结
  • MySQL核心知识汇总
  • Redis实践总结
  • MQ实践万字总结
  • Docker数据持久化总结
  • Docker网络模式深度解读
  • 常用游戏反外挂技术总结
  • 读书笔记
  • 心情杂货
  • 行业杂谈
  • 友情链接
关于我
GitHub (opens new window)
  • PHP

    • PHP-FPM使用指南
    • PHP7新特性总结
    • PHP安全编程
    • PHP安全配置总结
    • PHP变量的值类型和引用类型
    • PHP标准规范PSR
    • PHP操作Zookeeper实践
    • PHP错误和异常处理机制详解
    • PHP的Session运行机制
    • PHP底层运行机制和原理
    • PHP反射模拟实现注解路由
    • PHP高级用法总结
    • PHP开发常用文档总结
    • PHP开发入门:Memcached扩展安装
    • PHP开发入门:PHP7安装部署
    • PHP开发入门:Redis扩展安装
    • PHP开发SPL总结
    • PHP框架常见URL模式
    • PHP扩展开发入门
    • PHP垃圾回收机制
    • PHP类的自动加载
    • PHP输入输出流
    • PHP微服务开发指南
    • PHP协程
    • PHP写时拷贝技术
    • PHP性能优化之Opcache
    • PHP依赖注入和控制反转
    • PHP运行模式(SAPI)
    • PHP中file_get_contents与curl区别
    • RPC的简单实现
    • Protobuf:高效数据结构化工具
    • P3P协议详解
    • Laravel之集合(Collection)总结
    • Laravel实践总结
    • Laravel之ORM总结
      • 时间戳
      • 数据库连接
      • 默认属性值
        • 检查属性修改
        • fillable/guarded属性
      • 复制模型
      • 访问器和修改器
        • 定义访问器
        • 修改器
        • 日期修改器
      • 属性转换
      • 不常用方法
        • insertUsing
        • rename
        • 原始表达式
      • 常见问题
        • firstOrCreate/firstOrNew区别
        • updateOrCreate/updateOrInsert区别
    • 中高级PHP实践总结
    • PHP Socket编程实战
  • Golang

  • Python

  • Javascript

  • 其他语言

  • 编程语言
  • PHP
Ravior
2019-01-04
目录

Laravel之ORM总结

# 时间戳

默认情况下,Eloquent期望created_at和updated_at已经存在于数据表中,如果你不想要这些Laravel自动管理的数据列,在模型类中设置$timestamps属性为false:

<?php
    
namespace App\Models;
    
use Illuminate\Database\Eloquent\Model;
    
class Flight extends Model
{
    /**
     * 表明模型是否应该被打上时间戳
     *
     * @var bool
     */
    public $timestamps = false;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

如果你需要自定义时间戳格式,设置模型中的$dateFormat属性。该属性决定日期被如何存储到数据库中,以及模型被序列化为数组或JSON时日期的格式:

<?php
    
namespace App\Models;
    
use Illuminate\Database\Eloquent\Model;
    
class Flight extends Model
{
    /**
     * 模型日期列的存储格式
     *
     * @var string
     */
    protected $dateFormat = 'U';
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

如果你需要自定义用于存储时间戳的字段名称,可以在模型中设置CREATED_AT和UPDATED_AT常量:

<?php
    
class Flight extends Model
{
    const CREATED_AT = 'creation_date';
    const UPDATED_AT = 'last_update';
}
1
2
3
4
5
6
7

# 数据库连接

默认情况下,所有的Eloquent模型使用应用配置中的默认数据库连接,如果你想要为模型指定不同的连接,可以通过$connection属性来设置:

<?php
    
namespace App\Models;
    
use Illuminate\Database\Eloquent\Model;
    
class Flight extends Model
{
    /**
     * The connection name for the model.
     *
     * @var string
     */
    protected $connection = 'connection-name';
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 默认属性值

如果你想要定义某些模型属性的默认值,可以在模型上定义$attributes属性:

<?php
    
namespace App\Models;
    
use Illuminate\Database\Eloquent\Model;
    
class Flight extends Model
{
    /**
     * The model's default values for attributes.
     *
     * @var array
     */
    protected $attributes = [
        'delayed' => false,
    ];
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 检查属性修改

Eloquent 提供了isDirty、isClean和wasChanged方法来检查模型的内部状态并判断它的属性如何从初始加载状态发生改变。

isDirty方法会判断模型从加载之后是否有任何属性发生改变,你可以传递特定属性名进行判断,isClean方法和isDirty方法作用相反,也支持传入可选的属性参数:

$user = User::create([
    'first_name' => 'Taylor',
    'last_name' => 'Otwell',
    'title' => 'Developer',
]);

$user->title = 'Painter';

$user->isDirty(); // true
$user->isDirty('title'); // true
$user->isDirty('first_name'); // false

$user->isClean(); // false
$user->isClean('title'); // false
$user->isClean('first_name'); // true

$user->save();

$user->isDirty(); // false
$user->isClean(); // true
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

wasChanged 方法用于判断在当前请求生命周期内模型最后一次保存后是否有任何属性发生改变,你可以传递属性名来查看特定属性是否改变过:

$user = User::create([
    'first_name' => 'Taylor',
    'last_name' => 'Otwell',
    'title' => 'Developer',
]);

$user->title = 'Painter';
$user->save();

$user->wasChanged(); // true
$user->wasChanged('title'); // true
$user->wasChanged('first_name'); // false
1
2
3
4
5
6
7
8
9
10
11
12

# fillable/guarded属性

可以使用create方法保存一个新的模型, 该方法返回被插入的模型实例。但是,在此之前,你需要指定模型的fillable或guarded属性,因为所有Eloquent模型都通过批量赋值(Mass Assignment)进行保护,这两个属性分别用于定义哪些模型字段允许批量赋值以及哪些模型字段是受保护的,不能显式进行批量赋值。

# 复制模型

可以通过replicate方法创建一个模型实例的未保存副本,这在多个模型实例共享相同属性值时非常有用:

$shipping = App\Models\Address::create([
    'type' => 'shipping',
    'line_1' => '123 Example Street',
    'city' => 'Victorville',
    'state' => 'CA',
    'postcode' => '90001',
]);

$billing = $shipping->replicate()->fill([
    'type' => 'billing'
]);

$billing->save();
1
2
3
4
5
6
7
8
9
10
11
12
13

# 访问器和修改器

访问器和修改器允许你在获取模型属性或设置其值时格式化 Eloquent 属性。例如,你可能想要使用 Laravel 加密器对存储在数据库中的数据进行加密,并且在 Eloquent 模型中访问时自动进行解密。

# 定义访问器

要定义一个访问器,需要在模型中创建一个 getFooAttribute 方法,其中 Foo 是你想要访问的字段名(使用驼峰式命名规则)。

<?php
    
namespace App\Models;
    
use Illuminate\Database\Eloquent\Model;
    
class User extends Model
{
    /**
     * 获取用户的名字
     *
     * @param  string  $value
     * @return string
     */
    public function getFirstNameAttribute($value)
    {
        return ucfirst($value);
    }
}

// first_name 字段的原生值被传递给访问器,然后返回处理过的值。要访问该值只需要简单访问 first_name 即可
$user = App\Models\User::find(1);
$firstName = $user->first_name;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# 修改器

定义一个修改器,需要在模型中定义 setFooAttribute 方法,其中 Foo 是你想要访问的字段(使用驼峰式命名规则).

<?php
    
namespace App\Models;
    
use Illuminate\Database\Eloquent\Model;
    
class User extends Model
{
    /**
     * 设置用户的名字
     *
     * @param  string  $value
     * @return string
     */
    public function setFirstNameAttribute($value)
    {
        $this->attributes['first_name'] = strtolower($value);
    }
}


$user = App\Models\User::find(1);
$user->first_name = 'Sally'; // setFirstNameAttribute 方法会被调用,传入参数为 Sally,修改器会对其调用 strtolower 函数并将处理后的值设置为内部属性的值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 日期修改器

默认情况下,Eloquent 将会转化created_at和updated_at列的值为Carbon实例。默认情况下,时间戳的格式是 'Y-m-d H:i:s',如果你需要自定义时间戳格式,在模型中设置 $dateFormat 属性,该属性决定日期属性存储在数据库以及序列化为数组或 JSON 时的格式。

<?php
    
namespace App\Models;
    
use Illuminate\Database\Eloquent\Model;
    
class Flight extends Model
{
    /**
     * 模型日期的存储格式
     *
     * @var string
     */
    protected $dateFormat = 'U';
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 属性转换

模型中的$casts属性为属性字段转换到通用数据类型提供了便利方法 。$casts属性是数组格式,其键是要被转换的属性名称,其值时你想要转换的类型。目前支持的转换类型包括:integer, real, float, double, decimal:<digits>, string, boolean, object,array,collection,date,datetime和 timestamp, 转化为decimal时,必须定义数字的位数(decimal:2)。

<?php
    
namespace App\Models;
    
use Illuminate\Database\Eloquent\Model;
    
class User extends Model
{
    /**
     * 应该被转化为原生类型的属性
     *
     * @var array
     */
    protected $casts = [
        'is_admin' => 'boolean',   // 转换 is_admin 属性,将其由 integer 值(0或1)转换为 boolean 值
    ];
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

注:值为 null 的属性不会被转化,此外,不要定义和关联关系同名的转化(或者属性)

# 不常用方法

# insertUsing

self::db($partition)->insertUsing(
    ['date', 'player_id', 'rank', 'updated_at'],
    self::db($partition)->where('date', 0)->selectRaw("$date, player_id, `rank`, updated_at"),
);
1
2
3
4

# rename

Schema::rename($formalTable, $formalTable . '_past_' . date('ymdHi'));
Schema::rename($tmpTable, $formalTable);
1
2

# 原始表达式

有时你需要在查询中使用原始表达式,例如实现** COUNT(0) AS count**,这就需要用到raw方法。

use Hyperf\DbConnection\Db;

$res = Db::table('user')->select('gender', Db::raw('COUNT(0) AS `count`'))->groupBy('gender')->get();
1
2
3

# 常见问题

# firstOrCreate/firstOrNew区别

  • firstOrCreate和firstOrNew都可以用来创建模型。firstOrCreate方法先尝试通过给定列/值对在数据库中查找记录,如果没有找到的话则通过给定属性创建一个新的记录。
  • firstOrNew方法和firstOrCreate方法一样先尝试在数据库中查找匹配的记录,如果没有找到,则返回一个新的模型实例。需要注意的是,通过firstOrNew方法返回的模型实例并没有持久化到数据库中,你还需要调用save方法手动持久化。

# updateOrCreate/updateOrInsert区别

  • updateOrCreate() 和 updateOrInsert() 两个方法都是用来保存数据的时候方便操作“存在即更新,反之则创建
  • updateOrCreate() 方法使用的是 Eloquent ORM 操作的数据库(支持自动添加创建和更新时间),updateOrInsert()方法使用的是查询构造器(不可以自动添加创建和更新时间)
  • updateOrCreate()返回值是 \Illuminate\Database\Eloquent\Model, updateOrInsert 返回的是bool
#PHP#Laravel
上次更新: 2022/12/01, 11:09:34
Laravel实践总结
中高级PHP实践总结

← Laravel实践总结 中高级PHP实践总结→

最近更新
01
常用游戏反外挂技术总结
11-27
02
Golang开发实践万字总结
11-11
03
Redis万字总结
10-30
更多文章>
Theme by Vdoing | Copyright © 2011-2022 Ravior | 粤ICP备17060229号-3 | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式