原生查询
use Illuminate\Support\Facades\DB;
// 运行原生SQL,注意,不要使用字符串拼接,采用参数绑定的形式
// 原生SQL必须是完整的表名,带前缀的
$info = DB::select('select * from sxy_users where id = ?',[1]);
备注:时间字段无法自动写入,需手动创建
DB查询构造器
新增
use Illuminate\Support\Facades\DB;
// $data可以是一维数组和二维数据,二维数组表示批量插入
$data = [
'name'=>'shuxiaoyuan',
'age'=>18,
];
$info = DB::table('users')->insert($data);
//得到表的自增ID,如果有的话
$id = DB::table('users')->insertGetId($data);
删除
use Illuminate\Support\Facades\DB;
DB::table('users')->delete();
DB::table('users')->where('id', '>', 66)->delete();
//清空整张表,并且重置自增ID
DB::table('users')->truncate();
修改
use Illuminate\Support\Facades\DB;
$data = [
'name'=>'shuxiaoyuan',
'age'=>19,
];
$info = DB::table('users')->where('id',2)->update($data);
//自增和自减,第二个参数可选
DB::table('users')->increment('age');
DB::table('users')->increment('age', 5);
DB::table('users')->decrement('age');
DB::table('users')->decrement('age', 5);
查询
use Illuminate\Support\Facades\DB;
//获取单条数据
$info = DB::table('users')->where('email','xx@163.com')->first();
//获取主键ID获取数据
$info = DB::table('users')->find(1);
//获取多条数据
$info = DB::table('users')->where('name','shuxiaoyuan')->get();
// 各种where查询和聚合等,看 ORM 吧
Eloquent ORM操作数据库
可以设置的属性
<?php
/**
* 请提供简单说明
*
* User: 舒孝元
* Date: 2020/7/7 11:35
* Mail: sxy@shuxiaoyuan.com
* Website: https://www.shuxiaoyuan.com
*/
namespace App\Models;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class User extends Model {
/**
* 匿名全局作用域
*/
protected static function boot() {
parent::boot();
static::addGlobalScope('creation_date', function (Builder $builder) {
$builder->where('creation_date', '>', 1604555245);
});
}
// 软删,需要表中有对应字段:deleted_at
use SoftDeletes;
// 手动指定数据库连接,不指定即为默认
protected $connection = 'local_db';
// 手动指定表名,默认为大驼峰复数形式(UserInfo->user_infos)
protected $table = 't_users';
// 手动定义主键,默认为 id
protected $primaryKey = 'idd';
// 指示模型主键是否递增,默认为 int 自增型
public $incrementing = false;
// 自动递增ID的“类型”(主键不是一个整数,你需要将模型上受保护的 $keyType 属性设置为 string)
protected $keyType = 'string';
// 表明模型是否应该被打上时间戳,默认true,需要配合数据数据字段,默认是 created_at 和 updated_at
public $timestamps = true;
// 模型日期列的存储格式,默认为 Y-m-d H:i:s
// 采用PHP标准定义:https://www.php.net/manual/zh/function.date.php
protected $dateFormat = 'U'; //从 Unix 纪元(January 1 1970 00:00:00 GMT)开始至今的秒数
// 自定义时间戳字段名,默认为 created_at updated_at
const CREATED_AT = 'creation_date';
const UPDATED_AT = 'last_update';
/**
* 模型批量插入,需要开启以下两个中的一个,互斥
* $fillable // 可以被批量赋值的属性
* $guarded // 不能被批量赋值的属性
*
* @var array
*/
// 可以被批量赋值的属性
protected $fillable = [];
// 不能被批量赋值的属性
protected $guarded = [];// 空表示所有的都可赋值
// 查询时默认隐藏不显示的字段,黑名单
protected $hidden = ['password'];
// 查询时只显示指定的字段,白名单
protected $visible = [
'idd', 'name'
];
// 追加数据库中没有的字段,需要结合下面的修改器一起
protected $appends = ['you_sb'];
public function getYouSbAttribute() {
// 这个值你可以随便从其他地方获取
$this->attributes['you_sb'] = 'yes';
return $this->attributes['you_sb'];
}
// 为模型的某些属性定义默认值
protected $attributes = [
'remember_token' => '12345612456789',
];
/**
* 属性类型转换,可用的有如下所示
*
* integer、real、float、double、decimal:<digits>、string、
* boolean、object、array、collection、date、datetime、timestamp
* @var array
*/
protected $casts = [
'name' => 'decimal:2',
'creation_date' => 'date:Y-m-d',
'last_update' => 'datetime:Y-m-d H:i:s'
];
/**
* 定义一个访问器,定义语法: get字段名Attribute 字段名需要使用 驼峰式 命名
*
* 用法见 App\Http\Controllers\Test\IndexController::type12
*
* @param $value
* @return string
*/
public function getFirstNameAttribute($value) {
return ucfirst($value);
}
/**
* 定义一个修改器,定义语法:set字段名Attribute 字段名需要使用 驼峰式 命名
*
* 将 first_name 字段全部替换成小写,然后拼接一个字符串
*
* 用法见 App\Http\Controllers\Test\IndexController::type12
*
* @param $value
*/
public function setFirstNameAttribute($value) {
$this->attributes['first_name'] = strtolower($value) . '这是修改器加上的';
}
/**
* 查找或创建,firstOrCreate | firstOrNew
* 更新或创建,updateOrCreate
*
* @param $data
* @return mixed
*/
public static function addOne($data) {
$data = ['idd' => 's1604560200'];
return User::firstOrCreate($data);
}
}
增
// 使用 create 方法,需要在模型设置可批量更新
$data = [
'name'=>'shuxiaoyuan',
'age'=>18,
];
$info = User::create($data);
$id = $info->id;
// 使用 save 方法
$user = new User;
$user->name = 'yuanyuan';
$user->age = 18;
$user->save();
$id = $user->id;
// 存在则更新,不存在就创建
GamesData::updateOrCreate(['openId' => $data['openId']], $data);
删
// 根据主键删除
User::where()->delete();
User::destroy(1); // 软删
User::destroy([2,3]);
// 先查后删
$info = User::find(2);
$info->delete();
User::where('id',1)->delete();
// 软删,在模型中引入 SoftDeletes
use SoftDeletes;
// 查询被软删的模型
$temp = Article::onlyTrashed()->with('category')->paginate(15);
// 包含软删除模型
return Article::withTrashed()->where('id', $id)->with('category')->get();
// 恢复软删
return Article::where('id', $id)->restore();
// 物理删除,永久删除
return Article::where('id', $id)->forceDelete();
改
$data = [
'name'=>'shuxiaoyuan',
'age'=>18,
];
$info = User::where('id',7)->update($data);
// 使用 save 方法
$info = User::find(7);
$info->name = 'sss';
$info->age = 19;
$info->save();
自增自减
// 自增,第二个参数不填默认步长为 1
VerifyMaterialGroup::where('id', $id)->increment('number', $count);
VerifyMaterialGroup::where('id', $id)->decrement('number', $count);
查
// 通过主键查询
$info = User::find(1);
$info = User::find([1,2,4,6]);//数组形式,建议控制数量
// 查询一条数据
$info = User::where('name','shuxiaoyuan')->first();
// 只需要单个值
$info = User::where('name','shuxiaoyuan')->value('age');
// 获取包含单个列值的数组
// groupBy可以去重
$info = Staff::where('company_id', $id)->groupBy('department')->pluck('department');
// 查询所有数据时指定查询的字段
$info = User::all('id','name');
$info = User::all(['id','name']);
注:all方法是模型本身封装的一个静态方法,只能直接调用,前面不能调用where等方法。
// count max min avg sum 查询,没啥好说的,直接用就行
// 大数据处理,chunk 或 cursor 游标,具体使用看文档
DB::table('users')->orderBy('id')->chunk(100, function($users) {
// 处理结果集...
//可以return false来终止运行
return false;
});
// 分页查询
SubscribeUser::where('id', '>', 100)->paginate(100);
// 带条件
where('id','0');
where('id','>','100');
where('id','<>','121');
->orWhere('name', 'John')
// 模糊查询
->where('name', 'like', '%' . $name . '%')
//whereBetween 方法验证列值是否在给定值之间
->whereBetween('votes', [1, 100])->get();
//whereNotBetween 方法验证列值不在给定值之间
->whereNotBetween('votes', [1, 100])
//whereIn whereNotIn 方法验证给定列的值是否在给定数组中
->whereIn('id', [1, 2, 3])
->whereNotIn('id', [1, 2, 3])
//whereNull 方法验证给定列的值为 NULL
//whereNotNull 方法验证给定列的值不是 NULL
// whereDate 方法用于比较字段值和日期
->whereDate('created_at', '2018-11-11')
// whereMonth 方法用于比较字段值和一年中的指定月份
->whereMonth('created_at', '11')
// whereDay 方法用于比较字段值和一月中的指定日期
->whereDay('created_at', '11')
// whereYear 方法用于比较字段值和指定年
->whereYear('created_at', '2018')
// whereTime 方法用于比较字段值和指定时间
->whereTime('created_at', '=', '11:11')
//whereColumn 方法用于验证两个字段是否相等
->whereColumn('updated_at', 'created_at')
->whereColumn('updated_at', '>', 'created_at')
// 多条件数组通过 and 操作符进行链接
->whereColumn([
['first_name', '=', 'last_name'],
['updated_at', '>', 'created_at']
]
//inRandomOrder 方法可用于对查询结果集进行随机排序
->inRandomOrder()
//悲观锁
//可以避免被选择的行被修改直到事务提交
->sharedLock()
//避免选择行被其它共享锁修改或删除
->lockForUpdate()
// 查数据库最大主键
User::max('id')
分页查询修改数据
$data = Image::query()->where('user_id', 10)->paginate(10);
// 获取 item 并修改
$data->getCollection()->transform(function ($model) {
// 修改 expires_time 字段的显示
$model->expires_time = date('Y-m-d H:i:s');
// 添加字段
$model->name = 'shuxiaoyuan';
// 删除字段
unset($model->image_url);
return $model;
});
// 组建自己的 item
for ($i = 1; $i <= 10; $i++) {
$collect[] = [
'id' => $i,
'name' => Str::random(),
'time' => time(),
'url' => 'https://www.shuxiaoyuan.com'
];
}
// 直接替换整个 item
$data->setCollection(collect($collect));
return Tools::outSuccessInfo($data);
多条件查询(and,or嵌套查询)
# 原生 SQL
select
*
from
homework
where
(id between 1 and 10 or id between 50 and 70)
and complete = 1
and (title like 'a%' or title like 'b%');
# ORM 查询
$homeworks = Homework::where(function ($query) {
$query->whereBetween('id', [1, 10])
->orWhereBetween('id', [50, 70]);
})->where('complete', 1)
->where(function ($query) {
$query->where('title', 'like', 'a%')
->orWhere('title', 'like', 'b%');
})->get();
leftjoin 多条件匹配
# 方式就是使用闭包
leftjoin('db', function ($join) {···});
## && 使用 on
$data = DB::table('ikea_articles as a')
->leftJoin('ikea_likes as b', function ($join) {
$join->on('b.a_id', '=', 'a.id')
->on('b.openid', '=', 'a.openid');
})
## || 使用 orOn
$data = DB::table('ikea_articles as a')
->leftJoin('ikea_likes as b', function ($join) {
$join->on('b.a_id', '=', 'a.id')
->orOn('b.openid', '=', 'a.openid');
})
## 多条件查询
$data = DB::table('ikea_articles as a')
->leftJoin('ikea_likes as b', function ($join) use($openid) {
$join->on('b.a_id', '=', 'a.id')
->where('b.openid', '=', $openid);
})
with 实现动态添加 where 条件
$query->with([
'student' => function ($q) use ($student_id) {
$q->where('id', $student_id);
},
'class',
])
->select('id','name')
->where('id',$id)
->get();
when用法
//条件分支,如果 event_id 为真,则执行,否则执行
return BuyEventSuccessfuls::where('store_id', $store_id)
->when($event_id, function ($query) use ($event_id) {
return $query->where('event_id', $event_id);
}, function ($query) use ($eventIds) {
return $query->whereIn('event_id', $eventIds);
})->select('id', 'name', 'mobile', 'status')
->where('status', '=', "$status")
->paginate(20)
->toArray();
事务处理
注:transaction 方法接收一个可选参数作为第二个参数,用于定义死锁发生时事务的最大重试次数,如果尝试次数超出指定值,会抛出异常
手动开启和提交事务
// 手动开启事务
DB::beginTransaction();
// 提交事务
DB::commit();
// 回滚事务
DB::rollBack();
// 示例:
DB::beginTransaction();
try {
// 数据库处理,更新插入等
DB::commit(); // 提交事务
return Tools::outSuccess();
} catch (\Exception $exception) {
Log::error(__METHOD__ . __FUNCTION__, ['info' => $exception]);
DB::rollBack();
return Tools::outError(0, '保存失败,请稍后重试');
}
// 回滚事务
DB::rollBack();
例一:
//事务闭包函数传参,通过 use() 进行传参
$a = DB::transaction(function () use ($store, $login, $store_id) {
try {
DB::table('store')->where('serial_number', $store_id)->update($store);
DB::table('consume_login')->where('store_id', $store_id)->delete();
DB::table('consume_login')->insert($login);
DB::commit();//手动提交事务
return true;
} catch (\Exception $exception) {
DB::rollBack();//手动事务回滚
//$exception->getMessage(); //错误信息
return false;
}
});
//根据$a来判断是成功提交事务了还是回滚事务了
例二:
$a = DB::transaction(function () use ($request,$id) {
$data = $request->only('name', 'serial_number', 'addre', 'lng', 'lat', 'channel', 'type', 'area', 'city');
$consume_account = $request->json('accounts');
foreach ($consume_account as $k => $v) {
$consume_account[$k]['store_id'] = $data['serial_number'];
$consume_account[$k]['password'] = password_hash($consume_account[$k]['password'], PASSWORD_BCRYPT);
$consume_account[$k]['cookie_info'] = $v['username'] . ':' . $data['serial_number'] . ':' . time();
$consume_account[$k]['state'] = 0;
$consume_account[$k]['created_at'] = date('Y-m-d H:i:s');
$consume_account[$k]['updated_at'] = date('Y-m-d H:i:s');
}
try {
Store::where('id', $id)->update($data);
DB::table('consume_login')->insert($consume_account);
DB::commit();
return true;
} catch (\Exception $exception) {
DB::rollBack();
return false;
}
});
修改器
模型关联
远程一对一(多)
参数一: 最终
模型
参数二: 中间
模型
参数三: 中间
模型的字段,中间和本地的关联
参数四: 最终
模型的字段,一般是最终模型
的主键
,最终和中间的关联
参数五: 本地
模型的字段,一般是本地模型
的主键
,本地和中间的关联
参数六: 中间
模型的字段,中间和最终的关联