快速入门 | 数据库操作 | Laravel 6 中文文档


本站和网页 https://xueyuanjun.com/post/19968 的作者无关,不对其内容负责。快照谨为网络故障时之索引,不代表被搜索网站的即时页面。

快速入门 | 数据库操作 | Laravel 6 中文文档
Laravel 学院
文档
Laravel 8.x 中文文档
Laravel 7.x 中文文档
Laravel 6.x 中文文档
Laravel 5.8 中文文档
Laravel 5.7 中文文档
Laravel 5.6 中文文档
Laravel 5.5 中文文档
Laravel 5.4 中文文档
Laravel 5.3 中文文档
Laravel 5.2 中文文档
Laravel 5.1 中文文档
Lumen 中文文档
全栈教程
PHP 全栈工程师指南
PHP 入门到实战
Laravel 入门到精通
Vue.js 入门到实战
玩转 PhpStorm 教程
Laravel 博客入门项目
Laravel 微信小程序项目
Laravel 前后端分离项目
Swoole 入门到实战
Eloquent 性能优化实战
Redis 高性能实战系列
Laravel 新版本特性
PHP 新特性与最佳实践
Golang
Go 入门教程
Go Web 编程
Gin 使用教程
微服务开发
内功修炼
数据结构与算法
网络协议
微服务从入门到实践
高性能 MySQL 实战
高性能 Redis 实战
Laravel 消息队列实战
Laravel 从学徒到工匠
PHP 设计模式系列
名企面试指南
资源库
Laravel 资源大全
Laravel 开源项目
Laravel 扩展包
Laravel 资源下载
更多
博客 & 新闻
问答 & 讨论
Leetcode 题解
学院君读书笔记系列
关于 Laravel 学院
Laravel 互助学习群
Golang 互助学习群
更多
Laravel 中文文档
Laravel 全栈教程
Laravel 学习路径
Go 入门教程
程序员内功修炼
博客
问答
搜索
注册
登录
Info
Content
章节导航
Laravel 6 中文文档
目录索引
序言
3篇文章
新版特性
升级指南
贡献指南
快速入门
5篇文章
安装配置
目录结构
重量级开发环境:Homestead
轻量级开发环境:Valet
部署应用到服务器
核心架构
5篇文章
一次 Laravel 请求的生命周期
服务容器
服务提供者
门面
契约
基础组件
12篇文章
路由
中间件
CSRF 保护
控制器
HTTP 请求
HTTP 响应
视图
URL 生成
Session
表单验证
异常处理
日志
前端开发
4篇文章
Blade 模板引擎
本地化
快速入门:JavaScript & CSS 脚手架
使用进阶:通过 Laravel Mix 编译前端资源
安全系列
7篇文章
登录认证
API 认证
授权
邮箱验证
加密
哈希
重置密码
进阶系列
12篇文章
Artisan 控制台
广播
缓存
集合
事件
文件存储
辅助函数
邮件
通知
扩展包开发
队列
任务调度
数据库操作
6篇文章
快速入门
查询构建器
分页
迁移
数据填充
Redis
Eloquent模型
6篇文章
快速入门
关联关系
集合
API 资源类
访问器和修改器
序列化
测试系列
6篇文章
快速入门
HTTP 测试
浏览器测试
控制台测试
数据库测试
模拟
官方扩展包
7篇文章
订阅支付解决方案:Laravel Cashier
远程操作解决方案:Laravel Envoy
队列系统解决方案:Laravel Horizon
API 认证解决方案:Laravel Passport
全文搜索解决方案:Laravel Scout
第三方登录解决方案:Laravel Socialite
本地开发调试解决方案:Laravel Telescope
图书
Laravel 6 中文文档
数据库操作
快速入门
快速入门
由 学院君 创建于3年前, 最后更新于 3年前
版本号 #1
14737 views
0 likes
0 collects
简介
Laravel 让连接不同数据库以及对数据库进行增删改查操作变得非常简单,不论使用原生 SQL、还是查询构建器,还是 Eloquent ORM。目前,Laravel 支持四种类型的数据库系统:
MySQL
Postgres
SQLite
SQL Server
配置
应用的数据库配置位于 config/database.php(但是数据库用户及密码等敏感信息位于 .env 文件,如果你还不知道 .env 是何方神圣,那么你可能需要到这里补补课:https://laravelacademy.org/post/19912.html#toc-5)。在该文件中你可以定义所有的数据库连接,并指定哪个连接是默认连接。该文件中提供了所有支持数据库系统的配置示例。
默认情况下,Laravel 使用 MySQL 作为数据库引擎,并且示例配置已经为 Laravel Homestead 环境做好了设置(意思是说,如果你是用 Homestead 作为开发环境的话,就可以实现零配置使用),当然,你也可以按照需要为本地的数据库修改该配置(在 .env 中修改数据库配置):
SQLite 配置
在项目根目录下使用 touch database/database.sqlite 命令创建好新的 SQLite 数据库之后,就可以使用数据库绝对路径配置环境变量指向这个新创建的数据库:
DB_CONNECTION=sqlite
DB_DATABASE=/absolute/path/to/database.sqlite
要启用 SQLite 连接的外键约束,需要添加 foreign_key_constraints 选项到配置文件 config/database.php:
'sqlite' => [
// ...
'foreign_key_constraints' => true,
],
注:正如其名字所标识的,SQLite 是一个轻量级的、遵守 ACID 标准的关系型数据库,它包含在一个相对小的 C 程序库中。与许多其它数据库管理系统不同,SQLite 不是一个客户端/服务器结构的数据库引擎,而是被集成在用户程序中。作为嵌入式数据库,是应用程序(如网页浏览器)在本地/客户端存储数据的常见选择。更多关于 SQLite 的信息请查看其官网:http://www.sqlite.org/index.html
使用 URL 进行配置
通常,数据库连接都是使用多个配置值来完成配置,比如 host、database、username、password 等等,每个配置值在 .env 中都有对应的环境变量。这意味着当我们在生产服务器配置数据库连接信息时,需要管理多个环境变量。
有些数据库管理服务提供商如 Heroku 会提供包含所有数据库连接信息的单个「URL」字符串,比如下面这样:
mysql://root:password@127.0.0.1/forge?charset=UTF-8
这些 URL 通常遵循如下标准格式:
driver://username:password@host:port/database?options
为了方便,Laravel 也提供了对这种以 URL 作为数据库连接配置信息的支持。如果 url(对应的环境变量是 DATABASE_URL) 配置项存在,则会被用于解析数据库连接和认证信息。
读写分离
有时候你希望使用一个数据库连接做查询,另一个数据库连接做插入、更新和删除,Laravel 中实现这种读写分离非常简单,不管你用的是原生 SQL,还是查询构建器,还是 Eloquent ORM,只要配置正确,合适的连接总是会被使用。
想要知道如何配置读/写连接,可以参考下面这个例子:
'mysql' => [
'read' => [
'host' => '192.168.1.1'
],
'write' => [
'host' => '192.168.1.2'
],
'sticky' => true,
'driver' => 'mysql',
'database' => 'database',
'username' => 'root',
'password' => '',
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
],
注意我们在配置数组中新增了三个键:read、write 和 sticky,read 和 write 这两个键对应值都有一个包含单个键“host”的数组,而其所映射的 IP 值分别就是读连接和写连接,读/写连接的其它数据库配置项都共用 mysql 的主数组配置。
如果我们想要覆盖主数组中的配置,只需要将相应配置项放到 read 和 write 数组中即可。在本例中,192.168.1.1 将被用作「读」连接,而 192.168.1.2 将被用作「写」连接。两个数据库连接的凭证(用户名/密码)、前缀、字符集以及其它配置将会共享 mysql 数组中的设置,同理,如果不一样的话,分别在 read 或 write 数组中单独配置即可。
对于大部分应用来说都是读多写少,所以面对这种情况,如何配置多个读连接,一个写连接?可以这么做:
'mysql' => [
'driver' => 'mysql',
'read' => [
'host' => [
'192.168.1.1',
'192.168.1.2'
],
'write' => [
'host' => '192.168.1.3'
],
//
Laravel 在读数据时会从提供的 IP 中随机选一个进行连接。实现原理感兴趣的同学可以查看 Illuminate\Database\Connectors\ConnectionFactory 底层源码。
注:目前读写分离仅支持单个写连接。
sticky 项
sticky 项是一个可选的配置值,可用于在当前请求生命周期内允许立即读取写入数据库的记录。如果 sticky 选项被启用并且一个"写"操作在当前生命周期内发生,则后续所有"读"操作都会使用这个"写"连接(前提是同一个请求生命周期内),这样就可以确保同一个请求生命周期内写入的数据都可以立即被读取到,从而避免主从延迟导致的数据不一致,是否启用这一功能取决于你。
学院君注:当然,这只是一个针对分布式数据库系统中主从数据同步延迟的一个非常初级的解决方案,访问量不高的中小网站可以这么做,大流量高并发网站肯定不能这么干,主从读写分离本来就是为了解决单点性能问题,这样其实是把问题又引回去了,造成所有读写都集中到写数据库,对于高并发频繁写的场景下,后果可能是不堪设想的,但是话说回来,对于并发量不那么高,写操作不那么频繁的中小型站点来说,sticky 这种方式不失为一个初级的解决方案。
使用不同数据库连接
使用多个数据库连接的时候,可以通过 DB 门面上的 connection 方法访问不同连接。传递给 connection 方法的 name 对应配置文件 config/database.php 中设置的某个连接:
$users = DB::connection('read')->select(...);
甚至还可以指定数据库和连接名,使用 :: 分隔:
$users = DB::connection('mysql::read')->select(...);
你还可以使用连接实例上的 getPdo 方法访问底层原生的 PDO 实例:
$pdo = DB::connection('read')->getPdo();
运行原生 SQL 查询
配置好数据库连接后,就可以使用 DB 门面来运行查询。DB 门面为每种操作提供了相应方法:select, update, insert, delete 和 statement。
运行 Select 查询
运行一个最基本的查询,可以使用 DB 门面的 select 方法:
<?php
namespace App\Http\Controllers;
use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Controller;
class UserController extends Controller
/**
* 展示应用的用户列表.
* @return Response
*/
public function index()
$users = DB::select('select * from users where active = ?', [1]);
return view('user.index', ['users' => $users]);
传递给 select 方法的第一个参数是原生的 SQL 语句,第二个参数需要绑定到查询的参数绑定,通常,这些都是 where 子句约束中的值。参数绑定可以避免 SQL 注入攻击(输入参数校验由实现方控制,用户无法传递任意查询参数)。
select 方法以数组的形式返回结果集,数组中的每一个结果都是一个 PHP stdClass 对象:
你可以像下面这样访问结果值:
foreach ($users as $user) {
echo $user->name;
使用命名绑定
除了使用 ? 占位符来代表参数绑定外,还可以使用命名绑定来执行查询:
$results = DB::select('select * from users where id = :id', ['id' => 1]);
运行插入语句
使用 DB 门面的 insert 方法执行插入语句。和 select 一样,该方法将原生 SQL 语句作为第一个参数,将参数绑定作为第二个参数:
DB::insert('insert into users (id, name) values (?, ?)', [1, '学院君']);
运行更新语句
update 方法用于更新数据库中已存在的记录,该方法返回受更新语句影响的行数:
$affected = DB::update('update users set votes = 100 where name = ?', ['学院君']);
运行删除语句
delete 方法用于删除数据库中已存在的记录,和 update 一样,该语句返回被删除的行数:
$deleted = DB::delete('delete from users');
学院君注:使用 delete 和 update 语句时,需要非常小心,因为条件设置不慎,导致的后果有可能是无法挽回的,比如不带条件的 delete 语句删除的将是数据表的所有记录!这些都是有血淋淋的教训的。
运行一个通用语句
有些数据库语句不返回任何值,比如新增表,修改表,删除表等,对于这种类型的操作,可以使用 DB 门面的 statement 方法:
DB::statement('drop table users');
监听查询事件
如果你想要获取应用中每次 SQL 语句的执行,可以使用 listen 方法,该方法对查询日志和调试非常有用,你可以在服务提供者中注册查询监听器:
<?php
namespace App\Providers;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
/**
* Bootstrap any application services.
* @return void
*/
public function boot()
DB::listen(function ($query) {
// $query->sql
// $query->bindings
// $query->time
});
/**
* Register the service provider.
* @return void
*/
public function register()
//
数据库事务
想要在一个数据库事务中运行一连串操作,可以使用 DB 门面的 transaction 方法,使用 transaction 方法时不需要手动回滚或提交:如果事务闭包中抛出异常,事务将会自动回滚;如果闭包执行成功,事务将会自动提交:
DB::transaction(function () {
DB::table('users')->update(['votes' => 1]);
DB::table('posts')->delete();
});
处理死锁
数据库死锁指的是有两个或两个以上数据库操作相互依赖,一方需要等待另一方退出才能获取资源,但是没有一方提前退出,就会造成死锁,数据库事务容易造成的一个副作用就是死锁。为此 transaction 方法接收一个可选参数作为第二个参数,用于定义死锁发生时事务的最大重试次数。如果尝试次数超出指定值,会抛出异常:
DB::transaction(function () {
DB::table('users')->update(['votes' => 1]);
DB::table('posts')->delete();
}, 5);
手动使用事务
如果你想要手动开启事务从而对回滚和提交有更好的控制,可以使用 DB 门面的 beginTransaction 方法:
DB::beginTransaction();
你可以通过 rollBack 方法回滚事务:
DB::rollBack();
最后,你可以通过 commit 方法提交事务:
DB::commit();
注意:使用 DB 门面的事务方法还可以用于控制查询构建器和 Eloquent ORM 的事务。关于这两块内容,我们马上就会看到。
相关文章推荐:
数据库和 Eloquent 入门 —— 数据库连接配置和读写分离
数据库和 Eloquent 入门 —— 通过查询构建器实现简单的增删改查操作
Laravel
6.0
文档
数据库
读写分离
DB
增删改查
事务
事件
SQL
连接
配置
SQLite
MySQL
点赞
取消点赞
收藏
取消收藏
赞赏
分享到以下平台:
<< 上一篇:
任务调度
>> 下一篇:
查询构建器
无评论
登录后即可添加评论
升级为学院君订阅用户(新年优惠🎁)
内容导航
简介
配置
读写分离
使用不同数据库连接
运行原生 SQL 查询
监听查询事件
数据库事务
相关推荐
快速入门
Laravel 5.4 中文文档
数据库操作
快速入门
Laravel 5.7 中文文档
数据库操作
快速入门
Laravel 5.8 中文文档
数据库操作
快速入门
Laravel 7 中文文档
数据库操作
数据库入门
Laravel 8 中文文档
数据库操作
回到顶部
2022 基于 Laravel 6 构建
关于学院
订阅服务
友情链接
站点地图
本站 CDN 加速服务由又拍云赞助