laravel 之 数据库

快速入门

简介

数据库读写分离
'mysql' => [
    'read' => [
        'host' => '192.168.1.1',
    ],
    'write' => [
        'host' => '196.168.1.2'
    ],
    'driver'    => 'mysql',
    'database'  => 'database',
    'username'  => 'root',
    'password'  => '',
    'charset'   => 'utf8',
    'collation' => 'utf8_unicode_ci',
    'prefix'    => '',
 ],   
使用多数据库连接
$users = DB::connection('foo')->select(...);

你也可以在连接的实例中使用 getPdo 方法访问原始的底层 PDO 实例:

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

运行原生 SQL 语句

select
$user = DB::select('select * from users where active = ?', [1]);
foreach ($users as $user) {
    echo $user->name;
}
$results = DB::select('select * from users where id = :id', ['id' => 1]);
insert
DB::insert('insert into users (id, name) values (?, ?)', [1, 'Dayle']);
update
$affected = DB::update('update users set votes = 100 where name = ?', ['John']);   // 返回此语句执行所影响的行数
delete
$deleted = DB::delete('delete from users');  // 返回此语句执行所删除的行数
运行一般声明

有些数据库没有返回值, 对于这种类型的操作,可以使用 DB facade 的 statement 方法。

DB::statement('drop table users');
监听查询事件

监控每一条 SQL 语句

# 添加 use Illuminate\Support\Facades\DB;
# App\Providers\AppServiceProvider 
# boot 方法下添加打印函数
if(1){
  DB::listen(function ($query) {
    echo "<pre>";
    var_dump($query->sql);
    var_dump($query->bindings);
    var_dump($query->time);
    echo "</pre>";
  });
}

数据库事务

普通事务
DB::transaction(function () {
    DB::table('users')->update(['votes' => 1]);

    DB::table('posts')->delete();
});
处理死锁
DB::transaction(function () {
    DB::table('users')->update(['votes' => 1]);

    DB::table('posts')->delete();
}, 5);  // 如果重试结束还没有成功执行,将会抛出一个异常:
手动操作事务

开始事务

DB::beginTransaction();

回滚事务:

DB::rollBack();

提交事务:

DB::commit();

使用 DB facade 的事务方法也适用于 查询语句构造器 和 Eloquent ORM 。

查询构造器

获取结果

get 所有值
$users = DB::table('users')->get();
foreach ($users as $user) {
    echo $user->name;
}
first 一行值
$user = DB::table('users')->where('name', 'John')->first();
echo $user->name;
value 单个值
$email = DB::table('users')->where('name', 'John')->value('email');
pluck 一列值
$titles = DB::table('roles')->pluck('title');
foreach ($titles as $title) {
    echo $title;
}
chunk 分块
DB::table('users')->orderBy('id')->chunk(100, function ($users) {
    foreach ($users as $user) {
        //  操作
        //  return false; 手动停止
    }
});
聚合

查询构造器也支持各种聚合方法,如 countmaxminavgsum

子句

$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();

原始sql(注意注入)

$users = DB::table('users')
                     ->select(DB::raw('count(*) as user_count, status'))    // 注意注入
                     ->where('status', '<>', 1)
                     ->groupBy('status')
                     ->get();

joins

# inner join
$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();

# left join
$users = DB::table('users')
            ->leftJoin('posts', 'users.id', '=', 'posts.user_id')
            ->get();

# cross join
$users = DB::table('sizes')
            ->crossJoin('colours')
            ->get();

高级join

DB::table('users')
    ->join('contacts', function ($join) {
                            $join->on('users.id', '=', 'contacts.user_id')->orOn('users.name', '=', 'contacts.user_name');
                       })

# select * from `users` inner join `contacts` on `users`.`id` = `contacts`.`user_id` or `users`.`name` = `contacts`.`user_name`)

union

$users = DB::table('users')
    ->whereNull('id')
    ->union(DB::table('users'))
    ->get();
# select * from `users` where `id` is null union (select * from `users`)

where 字句

where('votes', '=', 100)  # 等价于   where('votes', 100)
where('votes', '>=', 100)
where('votes', '<>', 100)
where('name', 'like', 'T%')
where([
    ['status', '=', '1'],
    ['subscribed', '<>', '1'],
])
->where('votes', '>', 100) -> orWhere('name', 'John')
whereBetween('votes', [1, 100])
whereNotBetween('votes', [1, 100])
whereIn('id', [1, 2, 3])
whereNotIn('id', [1, 2, 3])
whereNull('updated_at')
whereNotNull('updated_at')
whereDate('created_at', '2016-12-31')
whereMonth('created_at', '12')
whereDay('created_at', '31')
whereYear('created_at', '2016')
whereColumn('first_name', 'last_name') # 检测两个列的数据是否一致
whereColumn('updated_at', '>', 'created_at')
whereColumn([
    ['first_name', '=', 'last_name'],
    ['updated_at', '>', 'created_at']
])

更高级的 where 子句

DB::table('users')
    ->where('name', '=', 'John')
    ->orWhere(function ($query) {
      $query->where('votes', '>', 100)
        ->where('title', '<>', 'Admin');
    })
    ->get();
# select * from `users` where `name` = John or (`votes` > 100 and `title` <> Admin)
DB::table('users')
            ->whereExists(function ($query) {
                $query->select(DB::raw(1))
                      ->from('orders')
                      ->whereRaw('orders.user_id = users.id');
            })
            ->get();
# select * from users
# where exists (
#    select 1 from orders where orders.user_id = users.id
# )

json 查询语句

本特性仅支持 MySQL 5.7+ 和 Postgres数据库。可以使用 -> 运算符来查询 JSON 列数据:

$users = DB::table('users')
                ->where('options->language', 'en')
                ->get();

$users = DB::table('users')
                ->where('preferences->dining->meal', 'salad')
                ->get();

Ordering, Grouping, Limit 及 Offset

orderBy
$users = DB::table('users')
                ->orderBy('name', 'desc')
                ->get();

latest/oldest

$user = DB::table('users')
                ->latest()
                ->first();
// 默认查询结果将依据 created_at 列。
inRandomOrder
$randomUser = DB::table('users')
                ->inRandomOrder()
                ->first();
groupBy / having / havingRaw
$users = DB::table('users')
                ->groupBy('account_id')
                ->having('account_id', '>', 100)
                ->get();
$users = DB::table('orders')
                ->select('department', DB::raw('SUM(price) as total_sales'))
                ->groupBy('department')
                ->havingRaw('SUM(price) > 2500')
                ->get();
skip / take
$users = DB::table('users')->skip(10)->take(5)->get();
# select * from `users` limit 5 offset 10
# 等同于
$users = DB::table('users')
                ->offset(10)
                ->limit(5)
                ->get();

条件语句

$role = $request->input('role');

$users = DB::table('users')
                ->when($role, function ($query) use ($role) {
                    return $query->where('role_id', $role);
                })
                ->get();
# 只有当 when 方法的第一个参数为 true 时,闭包里的 where 语句才会执行。如果第一个参数是 false,这个闭包将不会被执行。
$sortBy = null;

$users = DB::table('users')
                ->when($sortBy, function ($query) use ($sortBy) {
                    return $query->orderBy($sortBy);
                }, function ($query) {
                    return $query->orderBy('name');
                })
                ->get();
# # 只有当 when 方法的第一个参数为 true 时,闭包里的 where 语句才会执行。如果第一个参数是 false,第二个闭包被执行。

Inserts

DB::table('users')->insert(
    ['email' => 'john@example.com', 'votes' => 0]
);
DB::table('users')->insert([
    ['email' => 'taylor@example.com', 'votes' => 0],
    ['email' => 'dayle@example.com', 'votes' => 0]
]);

Updates

DB::table('users')
            ->where('id', 1)
            ->update(['votes' => 1]);
Updating JSON Columns
DB::table('users')
            ->where('id', 1)
            ->update(['options->enabled' => true]);

自增或自减

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']);

Deletes

# 慎用 DB::table('users')->delete();

DB::table('users')->where('votes', '>', 100)->delete();

# 慎用 DB::table('users')->truncate();

悲观锁

DB::table('users')->where('votes', '>', 100)->sharedLock()->get();
# 共享锁可防止选中的数据列被篡改,直到事务被提交为止
DB::table('users')->where('votes', '>', 100)->lockForUpdate()->get();
# 使用「更新」锁可避免行被其它共享锁修改或选取

分页

查询构造器分页

$users = DB::table('users')->paginate(15);
# 使用 groupBy 语句的分页操作无法由 Laravel 有效执行。如果你需要在一个分页结果集中使用 groupBy,建议你查询数据库并手动创建分页器。
$users = DB::table('users')->simplePaginate(15);
# 显示简单的「上一页」和「下一页」的链接,不需要显示页码链接,这对于大数据集非常有用。

Eloquent 模型分页

$users = App\User::paginate(15);
$users = User::where('votes', '>', 100)->paginate(15);
$users = User::where('votes', '>', 100)->simplePaginate(15);

手动创建分页

Illuminate\Pagination\PaginatorIlluminate\Pagination\LengthAwarePaginator 实例

Paginator 类不需要知道结果集中的数据项总数;然而,由于这个,该类没有用于检索最后一页索引的方法。

LengthAwarePaginator 接收的参数几乎和 Paginator一样;但是,它需要计算结果集中的数据项总数。

换一种说法,Paginator 对应于查询语句构造器和 Eloquent 的 simplePaginate 方法,而 LengthAwarePaginator 对应于 paginate 方法。

显示分页结果

<div class="container">
    @foreach ($users as $user)
        {{ $user->name }}
    @endforeach
</div>

{{ $users->links() }}
# links 方法生产的 HTML 兼容 Bootstrap CSS framework
自定义分页器的 URI
Route::get('users', function () {
    $users = App\User::paginate(15);
    $users->withPath('custom/url');
    //
});
# http://example.com/custom/url?page=N
附加参数到分页链接中
{{ $users->appends(['sort' => 'votes'])->links() }}
{{ $users->fragment('foo')->links() }}
# 附加「哈希片段」到分页器的链接中,你应该使用 fragment 方法。
Route::get('users', function () {
    return App\User::paginate()->toJson();
});
{
    "current_page": 1,
    "data": [
        {
            "id": 1,
            "name": "michael",
            "email": "754497892@qq.com",
            "created_at": "2017-07-28 03:04:07",
            "updated_at": "2017-07-28 03:04:07"
        },
        {
            "id": 3,
            "name": "aaa",
            "email": "aaa@qq.com",
            "created_at": "2017-08-02 02:04:54",
            "updated_at": "2017-08-02 02:04:54"
        }
    ],
    "from": 1,
    "last_page": 1,
    "next_page_url": null,
    "path": "http://192.168.1.63/home",
    "per_page": 15,
    "prev_page_url": null,
    "to": 2,
    "total": 2
}

自定义分页视图

如果你不使用 Bootstrap,你可以自定义你自己的视图去渲染这些链接。当在分页器实例中调用 links 方法,传递视图名称作为方法的第一参数:

{{ $paginator->links('view.name') }}

// 传递数据到视图中...
{{ $paginator->links('view.name', ['foo' => 'bar']) }}

然而,自定义分页视图最简单的方法是通过 vendor:publish 命令将它们导出到你的 resources/views/vendor 目录:

php artisan vendor:publish --tag=laravel-pagination

这个命令将视图放置在 resources/views/vendor/pagination 目录中。这个目录下的 default.blade.php 文件对应于默认分页视图。你可以简单地编辑这个文件以修改分页的 HTML 。

分页器示例方法

$results->count()
$results->currentPage()
$results->firstItem()
$results->hasMorePages()
$results->lastItem()
$results->lastPage() (当使用 simplePagination 时无效)
$results->nextPageUrl()
$results->perPage()
$results->previousPageUrl()
$results->total() (当使用 simplePagination 时无效)
$results->url($page)

数据库迁移

数据填充

Redis

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值