## Laravel学习笔记汇总——Eloquent Model模型和数据库操作
// 生成模型
php artisan make:model Flight
// 生成模型的同时创建迁移文件
php artisan make:model Flight --migration
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Flight extends Model
{
//指定关联的数据表,默认是类名的复数flights
protected $table = 'my_flights';
//指定数据表中的主键,默认是id
protected $primaryKey = 'flight_id';
//指定数据表主键不自增,默认为true
protected $incrementing = false;
//指定数据表主键的类型,默认为integer
protected $keyType = 'string';
//指定数据表中没有时间戮字段created_at和updated_at,默认为true
public $timestamps = false;
//指定数据表的时间戮字段名,默认为created_at和updated_at
const CREATED_AT = 'creation_date';
const UPDATED_AT = 'updated_date';
//指定数据表中某一字段的默认值
protected $attributes = [
'delayed' => false,
];
}
use App\Models\Flight;
// 获取所有数据表中的记录
foreach (Flight::all() as $flight) {
echo $flight->name;
}
// 创建查询、排序、截取
$flights = Flight::where('active', 1)
->orderBy('name')
->take(10)
->get();
// fresh和refresh,前者会重新取数据返回一个新的模型实例,后者直接更新当前实例中的数据。
$flight = Flight::where('number', 'FR 900')->first();
$freshFlight = $flight->fresh();
$flight->number = 'FR 456';
$flight->refresh();
$flight->number; // "FR 900"
// get和all返回的是Illuminate\Database\Eloquent\Collection类型,
// 它的基类是Illuminate\Support\Collection,可以直接foreach遍历
// 操作模型集合的便捷方法:reject可以将不符合要求的从集合中排除
$flights = Flight::where('destination', 'Paris')->get();
$flights = $flights->reject(function ($flight) {
return $flight->cancelled;
});
Illuminate\Database\Eloquent\Collection可用方法有:
contains
diff
except
find
fresh
intersect
load
loadMissing
modelKeys
makeVisible
makeHidden
only
toQuery
unique
Illuminate\Support\Collection可用方法有:(待更新)
// 使用table得到数据表,get得到一个Collection
use Illuminate\Support\Facades\DB;
$users = DB::table('users')->get();
// 每一个Collection的元素都是一个stdClass类的实例
foreach ($users as $user) {
echo $user->name;
}
// 使用id得到一行记录, id=3
$user = DB::table('users')->find(3);
// 使用first得到一行记录
$user = DB::table('users')->where('name', 'John')->first();
// 使用value得到某一单独的数据值,即使前面是一个Collection,也只返回一个值
$email = DB::table('users')->where('name', 'John')->value('email');
// 使用pluck可以得到一个字段的所有值
$titles = DB::table('users')->pluck('title');
// 提供第二个参数提供作为键名
$titles = DB::table('users')->pluck('title', 'name');
// 截取部分的记录,并对每一条记录进行操作
$re = User::chunk(1, function($u){
echo $u;
//如果return false,将终止后继的遍历
//return false;
});
// 一边chunk,一边更新数据,需要使用chunkById
DB::table('users')->where('active', false)
->chunkById(100, function ($users) {
foreach ($users as $user) {
DB::table('users')
->where('id', $user->id)
->update(['active' => true]);
}
});
// 集合计算
$users = DB::table('users')->count();
$price = DB::table('orders')->max('price'); # min, avg, sum也适用
// 使用exists或doesntExist判断符合条件的记录是否存在,而不使用count来判断
if (DB::table('orders')->where('finalized', 1)->exists()) {
// ...
}
if (DB::table('orders')->where('finalized', 1)->doesntExist()) {
// ...
}
//选择某些字段
$users = DB::table('users')
->select('name', 'email as user_email')
->get();
// 查询得到独一无二无重复的记录
$users = DB::table('users')->distinct()->get();
// 在已有查询的基础上添加字段
$query = DB::table('users')->select('name');
$users = $query->addSelect('age')->get();
// 关联多个数据表,innerJoin
$users = DB::table('users')
->join('contacts', 'users.id', '=', 'contacts.user_id')
->join('orders', 'users.id', '=', 'orders.user_id')
->select('users.*', 'contacts.phone', 'orders.price')
->get();
// leftJoin, rightJoin, 和crossJoin
$users = DB::table('users')
->leftJoin('posts', 'users.id', '=', 'posts.user_id')
->get();
$users = DB::table('users')
->rightJoin('posts', 'users.id', '=', 'posts.user_id')
->get();
$sizes = DB::table('sizes')
->crossJoin('colors')
->get();
// join多个连接条件
DB::table('users')
->join('contacts', function ($join) {
$join->on('users.id', '=', 'contacts.user_id')->orOn(...);
})
->get();
// join带过滤条件
DB::table('users')
->join('contacts', function ($join) {
$join->on('users.id', '=', 'contacts.user_id')
->where('contacts.user_id', '>', 5);
})
->get();
// 数据表和一个子查询结果进行二次关联joinSub
$latestPosts = DB::table('posts')
->select('user_id', DB::raw('MAX(created_at) as last_post_created_at'))
->where('is_published', true)
->groupBy('user_id');
$users = DB::table('users')
->joinSub($latestPosts, 'latest_posts', function ($join) {
$join->on('users.id', '=', 'latest_posts.user_id');
})->get();
// 查询结果的union
$first = DB::table('users')
->whereNull('first_name');
$users = DB::table('users')
->whereNull('last_name')
->union($first)
->get();
// where语句
$users = DB::table('users')
->where('votes', '>=', 100) # ->where('votes', 100) 省略第二个参数,表示 =
->where('name', 'like', 'T%')
->get();
// 也可以传递一个数组作为条件
$users = DB::table('users')->where([
['status', '=', '1'],
['subscribed', '<>', '1'],
])->get();
// orWhere语句
$users = DB::table('users')
->where('votes', '>', 100)
->orWhere('name', 'John')
->get();
// 以下语句相当于:select * from users where votes > 100 or (name = 'Abigail' and votes > 50)
$users = DB::table('users')
->where('votes', '>', 100)
->orWhere(function($query) {
$query->where('name', 'Abigail')
->where('votes', '>', 50);
})
->get();
// 以下语句相当于:select * from users where name = 'John' and (votes > 100 or title = 'Admin')
$users = DB::table('users')
->where('name', '=', 'John')
->where(function ($query) {
$query->where('votes', '>', 100)
->orWhere('title', '=', 'Admin');
})
->get();
// whereBetween语句
$users = DB::table('users')
->whereBetween('votes', [1, 100]) # whereNotBetween
->get();
// whereIn语句
$users = DB::table('users')
->whereIn('id', [1, 2, 3]) # whereNotIn
->get();
// whereNull语句
$users = DB::table('users')
->whereNull('updated_at') # whereNotNull
->get();
// whereDate / whereMonth / whereDay / whereYear / whereTime 比较时间
$users = DB::table('users')
->whereDate('created_at', '2016-12-31')
->get();
// whereColumn / orWhereColumn 比较两列数据
$users = DB::table('users')
->whereColumn('first_name', 'last_name')
->get();
$users = DB::table('users')
->whereColumn('updated_at', '>', 'created_at')
->get();
$users = DB::table('users')
->whereColumn([
['first_name', '=', 'last_name'],
['updated_at', '>', 'created_at'],
])->get();
// 对数据表按字段排序
$users = DB::table('users')
->orderBy('name', 'desc')
->orderBy('email', 'asc')
->get();
//随机排序
$randomUser = DB::table('users')
->inRandomOrder()
->first();
// 最新发布的或最早发布的,对应到created_at字段
$user = DB::table('users')
->latest()
->first();
// 使用reorder清除已经存在的排序
$query = DB::table('users')->orderBy('name');
$unorderedUsers = $query->reorder()->get();
// 或重新按另一字段排序
$usersOrderedByEmail = $query->reorder('email', 'desc')->get();
// 分组和条件
$users = DB::table('users')
->groupBy('account_id') # 可以添加多个字段
->having('account_id', '>', 100)
->get();
// skip可跳过一定量的记录,take取出一定量的记录
$users = DB::table('users')->skip(10)->take(5)->get();
// 使用offset相当于skip,limit相当于take
$users = DB::table('users')
->offset(10)
->limit(5)
->get();
// 使用when,只有当$role存在合理值为true时,才执行where
$role = $request->input('role');
$users = DB::table('users')
->when($role, function ($query, $role) {
return $query->where('role_id', $role);
})
->get();
// 使用下面的语句,when有第三个参数,是第一个参数为false时的回调函数
$sortByVotes = $request->input('sort_by_votes');
$users = DB::table('users')
->when($sortByVotes, function ($query, $sortByVotes) {
return $query->orderBy('votes');
}, function ($query) {
return $query->orderBy('name');
})
->get();
// 插入一条数据
DB::table('users')->insert([
'email' => '[email protected]',
'votes' => 0
]);
// 插入多条数据
DB::table('users')->insert([
['email' => '[email protected]', 'votes' => 0],
['email' => '[email protected]', 'votes' => 0],
]);
// 播放数据后返回id
$id = DB::table('users')->insertGetId(
['email' => '[email protected]', 'votes' => 0]
);
// 直接更新 update
$affected = DB::table('users')
->where('id', 1)
->update(['votes' => 1]);
// updateOrInsert第一个参数是条件,第二个参数是更新的值
// (但如果其他未列出来的字段是必填怎么办?
DB::table('users')
->updateOrInsert(
['email' => '[email protected]', 'name' => 'John'],
['votes' => '2']
);
// 还有一个upsert既插入新的数据记录,又更新已有的数据记录
// 第二个参数是用于确定记录不重复的字段名(相当于联合主键)
// 第三个参数是应当插入或更新的值
DB::table('flights')->upsert([
['departure' => 'Oakland', 'destination' => 'San Diego', 'price' => 99],
['departure' => 'Chicago', 'destination' => 'New York', 'price' => 150]
], ['departure', 'destination'], ['price']);
// 使用increment或decrement快速增加或减小某一列的数字值
DB::table('users')->increment('votes');
DB::table('users')->increment('votes', 5);
DB::table('users')->decrement('votes');
DB::table('users')->decrement('votes', 5);
DB::table('users')->increment('votes', 1, ['name' => 'John']);
// 删除记录
DB::table('users')->delete();
DB::table('users')->where('votes', '>', 100)->delete();
// 删除所有记录,并重置id
DB::table('users')->truncate();
// 悲观锁
DB::table('users')
->where('votes', '>', 100)
->sharedLock() # 选中的记录在当前事务提交前将不可被他人更改
->get();
DB::table('users')
->where('votes', '>', 100)
->lockForUpdate() # 防止被他人更改或被设置另一个shred lock
->get();
// 需要调试时,可直接在后面使用dd或dump函数
DB::table('users')->where('votes', '>', 100)->dd();
DB::table('users')->where('votes', '>', 100)->dump();