Laravel 文档阅读:数据库起步

翻译、衍生自:https://learnku.com/docs/laravel/5.4/database

简介

Laravel 让开发者与多种数据库的交互变得非常简单,主要是利用 查询语句构造器Eloquent ORM 帮您产生与业务逻辑对应的原生 SQL 语句,避免了开发者手动书写 SQL 语句带来的烦恼。现支持的数据库如下:

  • MySQL
  • Postgres
  • SQLite
  • SQL Server

配置

数据库配置文件是 config/database.php。你可以根据实际情况,修改或添加你的数据库信息,指定默认使用的数据库连接(database connections)。

配置 SQLite

配置 SQLite 需要先创建一个数据库,使用 touch database/database.sqlite 创建,然后再配置你的环境变量——使用绝对路径指向这个新创建的数据库。

DB_CONNECTION=sqlite
DB_DATABASE=/absolute/path/to/database.sqlite

配置 SQL Server

Laravel 在配置文件 config/database.php 中,已经为您预设了 SQL Server 的连接信息,只需要按照实际情况修改即可:

'sqlsrv' => [
    'driver' => 'sqlsrv',
    'host' => env('DB_HOST', 'localhost'),
    'database' => env('DB_DATABASE', 'forge'),
    'username' => env('DB_USERNAME', 'forge'),
    'password' => env('DB_PASSWORD', ''),
    'charset' => 'utf8',
    'prefix' => '',
],

读 & 写连接

有时,您希望项目使用两种数据库——一种负责读,也就是用来执行 select 语句;另一种负责写,用来执行 insertupdatedelete 语句。Laravel 使之变得轻而易举,无论您是使用原生查询、查询语句构造器还是Eloquent ORM,都会始终使用正确的连接。

具体读 & 写连接的配置方式,看下面的例子可知:

'mysql' => [
    'read' => [
        'host' => '192.168.1.1',
    ],
    'write' => [
        'host' => '196.168.1.2'
    ],
    'driver'    => 'mysql',
    'database'  => 'database',
    'username'  => 'root',
    'password'  => '',
    'charset' => 'utf8mb4',
    'collation' => 'utf8mb4_unicode_ci',
    'prefix'    => '',
],

我们为配置信息添加了两个键:readwrite。两个键里又包含 host 键。在 mysql 中,其余的配置信息是读 & 写连接共用的配置信息。

在上面例子里,192.168.1.1 这台主机用来「读」, 196.168.1.2 这台主机用来「写」。而其余像用户名、密码、数据库编码等都是两个连接共用的配置。

使用多数据库连接

DB 门面提供了 connection 方法,用来获得某个连接。用它就可以实现使用多数据库连接的需求。给 connection 传递是一个「连接名」,这个连接名必然是要在 config/database.php 里配置的。

$users = DB::connection('foo')->select(...);

您可以用连接实例的 getPdo 方法获得底层 PDO 实例。

$pdo = DB::connection()->getPdo();

执行原生 SQL 查询

使用 DB 门面可以完成每种类型的查询:selectupdateinsertdeletestatement

执行 select 查询

使用 DB 门面的 select 方法可执行查询:

<?php

namespace App\Http\Controllers;

use Illuminate\Support\Facades\DB;
use App\Http\Controllers\Controller;

class UserController extends Controller
{
    /**
     * Show a list of all of the application's users.
     *
     * @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]);

执行 insert 语句

使用 DB 门面的 insert 方法插入数据。形如 select 方法,DB:insert 的第一个参数是原生 SQL 语句,第二个参数是绑定参数:

DB::insert('insert into users (id, name) values (?, ?)', [1, 'Dayle']);

执行 update 语句

update 方法用来更新数据库中已存在的记录,返回的结果是更新的记录数目。

$affected = DB::update('update users set votes = 100 where name = ?', ['John']);

执行 delete 语句

update 方法用来从数据库中删除记录,类似 update 方法,返回的结果是删除的记录数目。

执行一般语句

「一般语句」指没有返回结果的 SQL 语句。对于这类操作,可以使用 DB 门面上的 statement 方法。

DB::statement('drop table users');

监听查询事件

如果你要查阅 Laravel 底层执行的 SQL 语句,可以使用 listen 方法,这个方法会在程序执行 SQL 语句时调用。这对 debug 程序和记录 SQL 语句非常有用。你可以在服务提供者 AppServiceProvider 中注册、监听查询事件。

<?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);

手动使用事务

如果你要完全手动控制事务的回滚和提交,就要用 BD 门面的 beginTransaction 方法了:

DB::beginTransaction();

使用 rollBack 方法回滚事务:

DB::rollBack();

最后,使用 commit 方法提交事务:

DB::commit();
本作品采用《CC 协议》,转载必须注明作者和本文链接
本帖由 Summer 于 3年前 加精
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
讨论数量: 7
幽弥狂

我觉得数据库事务这个使用的时候有点不够优雅。。。。

3年前 评论
'mysql' => [
'read' => [
    'host' => '192.168.1.1',
],
'write' => [
    'host' => '196.168.1.2'
],
'driver'    => 'mysql',
'database'  => 'database',
'username'  => 'root',
'password'  => '',
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix'    => '',
'options' => [2 => 3,]  //这里还可以写option
],
3年前 评论

@redrain 这个我真不知道,options 的作用是什么呢?

3年前 评论

@zhangbao
$pdo = new PDO($dsn, $username, $password, $options);

3年前 评论

@redrain 官方文档里并没有这个说明。谢谢你的提示。

3年前 评论

@zhangbao 不谢,官方文档没写到的 其实很多

3年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!