使用Laravel中的查询构造器实现增删改查功能
引言
上一篇介绍了如何在windows环境下跑一个 laravel
项目,这一篇写如何使用 laravel 中的 查询构造器
实现增删改查。
读这篇文章时我默认你已拥有如下知识:
- 了解php的基础语法
- 了解数据库设计
- 了解常用的sql查询
正文
实现增删改查前, 我们先准备一些步骤:
- php, nginx, mysql 服务正确启用
- 新建一个数据库及其数据表
开启服务我们打开上篇文章介绍的 Wnmp.exe
-> Start all
然后cmd上键入命令:
D:/wnmp/Wnmp/php/php-cgi.exe -b 127.0.0.1:9000 -c D:/wnmp/Wnmp/php/php.ini
新建一个数据库, 我命名为 shop
, 然后新建两张表
分别:
goods -> 商品表 user -> 用户表
数据表新建完成后, 我往里面随意插入了几条数据, 下图:
准备步骤已经完成, 我们打开上篇文章介绍的 testLaravel
项目
查看Laravel文档能够知道 数据库配置
在 config/database.php
里,
因为我们是mysql数据库, 所以找到对应的mysql选项:
查看 database.php
文件的mysql配置我们能够看到配置值是 变量
, 指向的是项目根目录的 .env
文件
打开 .env
文件, 我们填写对应的mysql真实配置, 下图:
配置大家看对应的key值就知道是什么含义了, 这里提下数据库密码, 为什么是 password
呢? 查看Wnmp安装目录, 我们能看到有一个 readme.txt
的文件, 文件的文本内容如下:
Copyright (c) 2012 - 2019, Kurt Cancemi (kurt@x64architecture.com) Donations are appreciated no matter if big or small. https://wnmp.x64architecture.com/donate/ Wnmp is an easy Nginx, MariaDB and PHP environment for Windows. The default login for MySQL/MariaDB/phpMyAdmin is: username: root password: password Note: you can change it via phpMyAdmin
根据文件内容 我们知道了密码是: password
, 因为是本地开发环境 这里就不更改密码了,
但如果是生产环境, 大家使用集成环境包的时候一定要变更数据库密码.
另外文中没有介绍项目的具体目录结构, 建议大家看下官方文档, 熟悉一下.
到这里项目的数据库配置就已经配完了, 关联了本地的 shop
数据库.
现在我们需要配置一下 路由
, 所有的 Laravel 路由
的配置都在根目录的 routes
里, routes
目录中有4个路由配置文件, 这里不谈其中区别, 只关注 web.php
, 后面所有路由我们都在此文件里追加.
看到这里的同学也建议看一下 laravel 的路由文档, 因为文中讲的不是很细, 传送门:
https://learnku.com/docs/lara...
顺便一说, 我个人选择 laravel
作为深入学习的php框架, laravel优雅的路由是我选择它的一个重要原因.
我这里先写几个路由, 大家感受一下:
Route::get('test/queryUsers',['uses' => 'TestController@queryUsers']); Route::post('test/queryUsers',['uses' => 'TestController@queryUsers']); Route::get('test/queryUsers/{id}',['uses' => 'TestController@queryUsers']); Route::match(['get','post'],'test/queryUsers',['uses' => 'TestController@queryUsers']); Route::any('test/queryUsers',['uses' => 'TestController@queryUsers']);
我们知道熟知的http请求方式有 get
和 post
两种.
a. 我们来依次解析上面的路由, 先看第1条:
Route::get('test/queryUsers',['uses' => 'TestController@queryUsers']);
此路由指定了 get
方式请求, 路由为 test/queryUsers
, 逻辑会走向 TestController
控制器的 queryUsers
方法
这里出现了两个名词 控制器
和 方法
注: laravel是一个 mvc框架
, 关于 mvc
的理解需要自己查些资料看看.
查询
控制器在项目里的 App/Http/Controllers
目录里, 这里我新增一个 TestController
控制器, TestController
里新增一个 queryUsers
方法:
<?php namespace App\Http\Controllers; use app\Member; use Illuminate\Support\Facades\DB; use Symfony\Component\Routing\Annotation\Route; class TestController extends Controller { public function queryUsers() { $users = DB::table('user')->get(); return $users; } }
我们先来看结果, 地址栏键入(域名 + 路由): http://test.lara.com/test/queryUsers
:
代码里很亮眼的一行:
DB::table('user')->get();
这行代码表示查询 shop数据库 user
表的全部数据, 所以我们看到 user
表中的3条记录都被返回了.
b. 现在我们来解析上面路由的第2条:
Route::post('test/queryUsers',['uses' => 'TestController@queryUsers']);
这条路由和第1条路由只有一个 post
的区别, 没错, 这是一个post请求的路由, 我们知道post请求方式无法在浏览器地址栏键入路由来得到结果, 所以我们需要使用一个工具 Postman
, 这是个好东西, 如果有同学没用过或是不知道它, 建议查一下熟悉一下, 文中不介绍它.
现在我们在 Postman
新建一个请求, 如图:
我们点击 send
得到 :
纳尼?怎么没有得到我们期望的结果, 很显然哪里不对,我们再来看看路由的文档:
https://learnku.com/docs/lara...
文档中我查找与 post
字眼的相关马迹, 看到:
原来是 CSRF
造成的, 无论是前端同学还是后端同学, 应该都对这个词不陌生, 跨站请求伪造
laravel 中为了解决 CSRF
这个隐患, 默认有保护机制, 我们需要配置 CSRF 白名单
, 根据文档, 我们知道 CSRF 白名单
的配置在 VerifyCsrfToken
中间件里, VerifyCsrfToken
中间件所在路径:
App/Http/Middleware/VerifyCsrfToken.php
打开文件, 添加 CSRF 白名单
,
protected $except = [ 'http://test.lara.com/test/queryUsers', ];
完成这步后我们再打开 postman, 点击 send
可以看到数据如期望返回:
c. 现在我们来解析上面路由的第3条:
Route::get('test/queryUsers/{id}',['uses' => 'TestController@queryUsers']);
可以看出这条路由的区别在于路由末尾的 {id}
, 开发中我们会有这样的需求, 前端传递一个用户id, 后端返回这个id对应的该用户信息
此时需要修改下 TestController
控制器 queryUsers
方法:
public function queryUsers() { $id = request()->id; // 此种方式获取参数 $users = DB::table('user')->where('id', $id)->get(); return json_encode($users); }
白话文解释一下这条sql: 在table表里查询id = $id(路由传递的值)的记录,
查看结果, 符合预期:
d. 现在我们来解析上面路由的第4条和第5条:
Route::match(['get','post'],'test/queryUsers',['uses' => 'TestController@queryUsers']); Route::any('test/queryUsers',['uses' => 'TestController@queryUsers']);
这俩路由我就不演示了, 分别解释一下, match
里路由为指定的请求方式, 一种或多种,
而 any
则是匹配任意方式, 无论是通过 get
还是 post
方式请求, 都能得到我们想要的结果.
我们再看看上面我设计的goods表
我们能看到这两条数据不知道创建的用户是谁, 但是有uid值, 这时候我们希望一个接口既返回商品信息又能够让我知道创建者是谁, 此时就需要用到多表联查了, 我们新增一个路由:
Route::get('test/queryGoods',['uses' => 'TestController@queryGoods']);
然后 TestController
里新增一个 queryGoods
方法:
public function queryGoods() { $goods = DB::table('goods') ->leftJoin('user', 'goods.uid', '=', 'user.id') ->get(); return json_encode($goods); }
如期望一样返回数据:
[{ id: 1, uid: 1, name: "测试商品1", desc: null, img_urls: null, price: "99.00", old_price: "78.00", real_name: "陈云", nickname: "穷摇.", head_url: null, age: null, gender: null, level: null }, { id: 2, uid: 2, name: "测试商品2", desc: null, img_urls: null, price: "290.00", old_price: "389.00", real_name: "欧阳欣欣", nickname: "小欣欣", head_url: null, age: null, gender: null, level: null } ]
但是用户信息所有字段全部被返回了, 有些时候我们为了安全, 只需要返回指定字段, 比如我们只需要返回 user
表中的 real_name
和 head_url
字段, 那么我们就需要做一下字段的约束:
public function queryGoods() { $goods = DB::table('goods') ->leftJoin('user', 'goods.uid', '=', 'user.id') ->select('goods.*', 'user.real_name', 'user.head_url') ->get(); return json_encode($goods); }
关注下这行代码:
select('goods.*', 'user.real_name', 'user.head_url')
这行代码表示返回goods表中的 所有字段
以及user表中的 real_name
和 head_url
字段, 就完美达到了我们想要的结果.
新增
至此查询已经基本写的差不多了, 我们开始向数据表里 新增
数据
我们新增一个 post
请求的路由 test/addUser
:
Route::post('test/addUser',['uses' => 'TestController@addUser']);
添加 CSRF 路由白名单
protected $except = [ 'http://test.lara.com/test/queryUsers', 'http://test.lara.com/test/addUser', ];
然后 TestController
里新增一个 addUser
方法:
public function addUser() { $real_name = request()->real_name; $nickname = request()->nickname; DB::table('user')->insert( ['real_name' => $real_name, 'nickname' => $nickname] ); $users = DB::table('user')->get(); return json_encode($users); }
打开 postman
, 添加参数:
{"real_name":"刘亦菲","nickname":"小菲菲"}
点击send, 发现数据如期望一样正确插入.
查询构造器提供 insert
方法用于插入记录到数据库中。 insert 方法接收数组形式的字段名和字段值进行插入操作
DB::table('user')->insert( ['real_name' => $real_name, 'nickname' => $nickname] );
编辑
我们新增一个 put
请求的路由 test/updateUser
:
同样添加 CSRF
Route::put('test/updateUser',['uses' => 'TestController@updateUser']);
路由白名单
protected $except = [ 'http://test.lara.com/test/queryUsers', 'http://test.lara.com/test/addUser', 'http://test.lara.com/test/updateUser', ];
然后 TestController
里新增一个 updateUser
方法:
public function updateUser() { $id = request()->id; $nickname = request()->nickname; DB::table('user') ->where('id', $id) ->update(['nickname' => $nickname]); $users = DB::table('user')->get(); return json_encode($users); }
打开 postman
, 我们知道刚刚新增的记录返回的 刘亦菲
的id是4, 我们根据 id
来更新下它的 nickname
, postman 里添加请求参数:
{"id":"4", "nickname": "小阿菲~"}
点击send, 发现数据如期望一样正确更新.
查询构造器提供 update
方法用于更新已有的记录。 接受包含要更新的字段及值的数组
->where('id', $id)->->update(['nickname' => $nickname]);
删除
我们新增一个 delete
请求的路由 test/deleteUser
:
Route::delete('test/deleteUser',['uses' => 'TestController@deleteUser']);
同样添加 CSRF 路由白名单
protected $except = [ 'http://test.lara.com/test/queryUsers', 'http://test.lara.com/test/addUser', 'http://test.lara.com/test/updateUser', 'http://test.lara.com/test/deleteUser', ];
然后 TestController
里新增一个 deleteUser
方法:
public function deleteUser() { $id = request()->id; DB::table('user') ->where('id', $id) ->delete(); $users = DB::table('user')->get(); return json_encode($users); }
打开 postman
, 我们现在想把 刘亦菲
的记录在数据库里删掉, 我们知道她的 id
是 4, 我们根据 id
来删除它, 添加请求参数:
{"id":"4"}
点击send, 发现数据如期望一样正确删除 (已经没有id为4的记录).
laravel中查询构造器可以使用 delete
方法从表中删除记录。添加 where
子句来约束 delete 的条件:
->where('id', $id)->delete();
文章有很多方法没有介绍到, 建议需要学习的同学看下文档, 传送门:
https://learnku.com/docs/lara...
总结
栏 目:PHP代码
下一篇:PHP 7安装使用体验之性能大提升,兼容性强,扩展支持不够(升级PHP要谨慎)
本文地址:http://www.codeinn.net/misctech/190341.html