Phalcon入门教程之模型CURD(1)

简介: 原文发表于:Phalcon入门教程之模型CURD(1) 上一篇《Phalcon入门教程之模型》中介绍了数据库模型操作的一些基础功能,本篇将介绍模型的 select 和 insert 用法。由于数据库模型操作的内容比较多和细,所以本篇只是粗略的介绍基础用法,以及补充文档中没有提及的一些用法和注意点。

原文发表于:Phalcon入门教程之模型CURD(1)

上一篇《Phalcon入门教程之模型》中介绍了数据库模型操作的一些基础功能,本篇将介绍模型的 selectinsert 用法。由于数据库模型操作的内容比较多和细,所以本篇只是粗略的介绍基础用法,以及补充文档中没有提及的一些用法和注意点。因此,强烈建议大家在熟读文档的前提下,再阅读此篇教程。

数据表

假设数据表名为 test_articles,数据结构及记录下:

mysql> select * from test_articles;
+-----+--------------+--------------+--------+-------------+--------------+--------+-----------+---------------------+-----------+---------------------+
| aid | title        | introduce    | status | view_number | is_recommend | is_top | create_by | create_time         | modify_by | modify_time         |
+-----+--------------+--------------+--------+-------------+--------------+--------+-----------+---------------------+-----------+---------------------+
|   1 | 英语演讲     | 纯口语式       |      1 |           0 | 0            | 0      |         1 | 2017-05-21 05:13:46 |         1 | 2017-05-21 05:13:46 |
|   2 | 限购政策     | 快买房         |      1 |           0 | 0            | 0      |         1 | 2017-05-21 05:13:46 |         1 | 2017-05-21 05:13:46 |
+-----+--------------+--------------+--------+-------------+--------------+--------+-----------+---------------------+-----------+---------------------+

其中 aid 是主键,其他每个字段的意思就不做介绍了。

查找记录

Phalcon\Mvc\Model 为数据查询提供了多种函数,下面将直接用demo来介绍其用法。

查找多条记录

使用 find() 函数可以查找多条记录:

$articleModel = new ArticlesModel();
//查询所有记录,返回一个对象
$result = $articleModel->find();
//循环输出结果
foreach($result as $record){
  var_dump($record->aid); 
  var_dump($record->title);
}

find() 函数返回的是 Phalcon\Mvc\Model\Resultset\Simple 对象,我们可以通过 foreach 循环输出结果。也可以将结果集对象转成一个二维数组:

$records = $result->toArray();

还可以统计结果集对象的记录总数:

$count = count($result);

查找单条记录

查找单条记录,可以通过使用 findFirst() 函数来实现:

$result1 = $articleModel->findFirst(1);
print_r($result1->toArray());

findFirst() 返回的就是当前模型对象(如果不明白,可以打印 $result1 即会明白),toArray() 会将其转成一维数组。

细心的朋友可能会有疑问,findFirst(1) 是按什么字段做查询条件的? 通过监听打印SQL语句,可以看到在 Phalcon 中会默认使用主键作为查询条件:

SELECT * FROM `test_articles` WHERE `test_articles`.`aid` = 1 LIMIT :APL0

当然,我们也可以使用完整的查询条件:

$result2 = $articleModel->findFirst("aid = 1");

返回的结果,和上面的 findFirst(1) 是一样的。

参数绑定

仔细观察上面的SQL语句,会发现查询条件并没有进行预处理。如果 aid 的值是通过外部数据(比如用户输入)或者变量传输进来,则有可能出现SQL注入的危险。我们必须要用参数绑定的方式来防止SQL注入:

$result2 = $articleModel->find([
  'conditions' => 'aid = :aid: AND status = :status:',
  'bind' => [
    'aid' => 2,
    'status' => 1,
  ],
]);

生成的SQL语句如下:

SELECT * FROM `test_articles` WHERE `test_articles`.`aid` = :aid AND `test_articles`.`status` = :status

经过参数替换后的SQL语句如下:

SELECT * FROM `test_articles` WHERE `test_articles`.`aid` = 2 AND `test_articles`.`status` = 1

参数绑定支持字符串和整数占位符,本篇只介绍字符串占位符,整数占位符的用法可查阅文档。

查询选项

Phalcon 提供了很多查询选项,常用的查询选项demo如下:

$articleModel->find([
  'columns' => 'aid, title', //查询字段
  'conditions' => 'aid = :aid:',  //查询条件
  'bind' => [ //参数绑定
    'aid' => 2
  ],
  'order' => 'aid DESC', //排序
  'limit' => 10, //限制查询结果的数量
  'offset' => 10, //偏移量
 ]);

全部的查询选项,请查阅文档。
很多朋友在群里问 inlike 在参数绑定下的用法,下面跟大家分享一下。

in的用法

直接上示例代码:

$result3 = $articleModel->find([
  'conditions' => 'aid IN ({aids:array})',
    'bind' => [
      'aids' => [1, 2]
    ],
]);

like的用法

示例代码如下:

$result4 = $articleModel->find([
  'conditions' => 'title like :title:',
  'bind' => [
    'title' => '%英语%',
  ],
]);

添加记录

添加单条记录

添加单条记录可用 create() 函数:

$articleModel = new ArticlesModel();
$result = $articleModel->create([
    'title' => 'phalcon测试',
    'introduce' => 'Phalcon入门教程',
    'status' => 1,
    'view_number' => 1,
    'is_recommend' => 1,
    'is_top' => 1,
    'create_by' => 1,
    'create_time' => date('Y-m-d H:i:s'),
    'modify_by' => 1,
    'modify_time' => date('Y-m-d H:i:s')
]);
if (!$result) { 
    //添加记录失败,获取错误信息
    $errorMessage = implode(',', $this->getMessages());
    echo $errorMessage;
}else {
    //添加记录成功,获取新增记录的主键aid
    $aid = $articleModel->aid;
    echo $aid;
}

create() 函数返回的是 boolean 值。如果返回值为 false ,我们可以通过模型的 getMessages() 函数来获取错误信息;若返回值为 true ,则可以直接获取最新的主键ID,即我们通常所说的 lastInsertId

批量添加记录

Phalcon 中并没有提供批量添加记录的函数,需要开发者自己动手实现,本篇跟大家分享两种实现批量添加记录的方法。

循环逐条添加

通过循环逐次添加一条记录,这种方法在性能上损耗较大,不推荐使用。但是这种方法牵涉到 Phalcon 模型的底层实现原理,所以这里拿出来跟大家分析一下。上代码:

$articleModel = new ArticlesModel();
//var_dump($articleModel->title);  //下面测试用
for ($i = 1; $i <= 10; $i++) {
    $data = [
        'title' => "phalcon测试{$i}",
        'introduce' => "Phalcon入门教程{$i}",
        'status' => $i,
        'view_number' => $i,
        'is_recommend' => 1,
        'is_top' => 1,
        'create_by' => $i,
        'create_time' => date('Y-m-d H:i:s'),
        'modify_by' => $i,
        'modify_time' => date('Y-m-d H:i:s')
    ];
    $result = $articleModel->create($data);
    if (!$result) {
        $errorMessage = implode(',', $articleModel->getMessages());
        exit($errorMessage);
    }else {
        $aid = $articleModel->aid;
        echo $aid;
        //var_dump($articleModel->title);  //下面测试用
    }
    echo '<br />';
}

这段代码的运行结果可能会出乎很多人的意料,只有循环中的第一条数据入库成功,并返回了主键ID,其他的数据入库时直接报错:

Record cannot be created because it already exists

意思是因为记录已经存在,所以无法再次入库。在前面 添加单条记录 的时候,我们有提到获取 lastInsertId 的方式,是直接通过模型的成员属性方式获取:

$aid = $articleModel->aid;

关键点就在这里,Phalcon 模型对象会把当前入库的数据,全部赋值给模型对象的成员属性,包括主键ID。我们做个测试,打开上面代码中的两处注释部分,再次运行后可以看到,第一次打印 title 成员属性的时候,会报一个 Notice 错误,提示信息是未定义的成员属性。当第二次打印 title 成员属性的时候,却有值了,而且是循环中第一条记录的 title 值。看到这里,相信大家应该已经差不多能明白其中的实现原理了。因为入库成功那条记录返回的主键ID也被赋值给模型对象的成员属性,create() 函数内部会判断当前对象的主键成员属性是否有值,在有值的情况下,就不再生成SQL语句发送到Mysql服务端,直接抛出错误信息。请记住这一点,Phalcon 模型的 update() 函数也是基于此原理实现的(下一篇教程会提到)。那么,通过循环逐条添加记录的方法要如何实现呢?请看代码:

$articleModel = new ArticlesModel();
for ($i = 1; $i <= 10; $i++) {
    $data = [
        'title' => "phalcon测试{$i}",
        'introduce' => "Phalcon入门教程{$i}",
        'status' => $i,
        'view_number' => $i,
        'is_recommend' => 1,
        'is_top' => 1,
        'create_by' => $i,
        'create_time' => date('Y-m-d H:i:s'),
        'modify_by' => $i,
        'modify_time' => date('Y-m-d H:i:s')
    ];
    $clone = clone $articleModel; //克隆一个新对象,使用新对象来调用create()函数
    $result = $clone->create($data);
    if (!$result) {
        $errorMessage = implode(',', $clone->getMessages());
        exit($errorMessage);
    }else {
        $aid = $clone->aid;
        echo $aid;
    }
    echo '<br />';
}

每循环一次,就克隆出一个新对象,通过新对象来调用 create() 函数添加数据记录。因为每个对象间的成员属性都是独立的,所以全部数据都会添加成功。

批量添加

我们常用的批量添加方式是生成一条 insert 语句把数据添加入库,下面跟大家分享我在项目中封装的函数:

//文件路径:Marser\app\frontend\models\ArticlesModel.php
class ArticlesModel extends \Marser\App\Frontend\Models\BaseModel {

    /*** 表名*/
    const TABLE_NAME = 'articles';

    public function initialize(){
        parent::initialize();
        $this->set_table_source(self::TABLE_NAME);
    }

    /**
     * 批量添加
     * @param array $data
     * @return boolean
     * @throws \Exception
     */
    public function batch_insert(array $data){
        if (count($data) == 0) {
            throw new \Exception('参数错误');
        }
        $keys = array_keys(reset($data));
        $keys = array_map(function ($key) {
            return "`{$key}`";
        }, $keys);
        $keys = implode(',', $keys);
        $sql = "INSERT INTO " . $this->getSource() . " ({$keys}) VALUES ";
        foreach ($data as $v) {
            $v = array_map(function ($value) {
                return "'{$value}'";
            }, $v);
            $values = implode(',', array_values($v));
            $sql .= " ({$values}), ";
        }
        $sql = rtrim(trim($sql), ',');
        //DI中注册的数据库服务名称为"db"
        $result = $this->getDI()->get('db')->execute($sql);
        if (!$result) {
            throw new \Exception('批量入库记录');
        }
        return $result;
    }
}

以上代码已托管在github:https://github.com/KevinJay/marser-phalcon-demo

最后,欢迎大家加入QQ群交流讨论:

  • 广州PHP高端交流群:158587573
  • Phalcon玩家群:150237524
目录
相关文章
Layui 内置方法 - layer.confirm(询问框)
Layui 内置方法 - layer.confirm(询问框)
1899 0
|
JavaScript 前端开发
若依框架文档开发手册----开发中常用功能模块(中)
若依框架文档开发手册----开发中常用功能模块
4666 0
|
SQL JSON 前端开发
若依RuoYi脚手架二次开发教程(二次开发必学技能)
本次我们将通过一个菜品管理模块开发的案例,来演示拿到若依框架后,如何在若依管理系统上进行二次开发,升级改造为自己的管理系统。适合以若依作为项目脚手架的公司开发人员、毕业设计的学生及开源项目学习者。
7072 1
若依RuoYi脚手架二次开发教程(二次开发必学技能)
|
11月前
|
前端开发 NoSQL Java
【Java若依框架】RuoYi-Vue的前端和后端配置步骤和启动步骤
本文介绍了如何配置和启动基于Java的若依(RuoYi)项目,涵盖后端和前端的详细步骤。首先,准备Redis、MySQL以及IDE(如Idea和VS)。接着,通过GitHub获取代码并导入到IDE中,执行必要的SQL文件和配置数据库密码。然后,启动Redis并进行相关配置。最后,按照前端配置步骤克隆前端代码库,打开终端执行命令完成前端配置。整个过程详细记录了每一步的操作,帮助开发者顺利部署若依项目。 如果你觉得有帮助,请点赞、关注和收藏,这将是我持续分享的动力!
6005 4
|
运维 监控 NoSQL
|
SQL XML JavaScript
【若依Java】15分钟玩转若依二次开发,新手小白半小时实现前后端分离项目,springboot+vue3+Element Plus+vite实现Java项目和管理后台网站功能
摘要: 本文档详细介绍了如何使用若依框架快速搭建一个基于SpringBoot和Vue3的前后端分离的Java管理后台。教程涵盖了技术点、准备工作、启动项目、自动生成代码、数据库配置、菜单管理、代码下载和导入、自定义主题样式、代码生成、启动Vue3项目、修改代码、以及对代码进行自定义和扩展,例如单表和主子表的代码生成、树形表的实现、商品列表和分类列表的改造等。整个过程详细地指导了如何从下载项目到配置数据库,再到生成Java和Vue3代码,最后实现前后端的运行和功能定制。此外,还提供了关于软件安装、环境变量配置和代码自动生成的注意事项。
29199 73
|
域名解析 JavaScript 前端开发
宝塔快速部署若依项目
宝塔快速部署若依项目
|
网络安全 数据安全/隐私保护 网络协议
ssh密钥创建分发(端口号非22)&脚本实现自动创建分发密钥
1.1 服务端端口号变化了,如何基于秘钥连接 1.1.1 环境准备 实验环境: [root@test ~]# cat /etc/redhat-release CentOS release 6.
1585 0
|
Android开发
《Android应用开发攻略》——1.13 从模拟器/Android设备获得屏幕截图
本节书摘来自华章计算机《Android应用开发攻略》一书中的第1章,第1.13节,作者:(美)达尔文(Darwin, I. F.)著, 更多章节内容可以访问云栖社区“华章计算机”公众号查看。
1407 0

热门文章

最新文章