phalapi-入门篇5(数据库操作和Model层)

phalapi-入门篇5(数据库操作和Model层)

前言

先在这里感谢phalapi框架创始人@dogstar,为我们提供了这样一个优秀的开源框架.

本小节主要讲解基于notorm的数据库操作以及使用Model层进行快速的数据层的开发,请确保装有PDO拓展.

附上:

官网地址:http://www.phalapi.net/

开源中国Git地址:http://git.oschina.net/dogstar/PhalApi/tree/release

1. 基于PDO的notorm进行的数据库操作

phalapi的数据库操作是使用的开源的notorm进行的,notorm是基于PDO链接数据库,在框架内部默认链接的是mysql数据库,如需修改链接其他数据库请修改 /PhalApi/PhalApi/DB/NotORM.php中的getPdo方法:

 $dsn = sprintf('mysql:dbname=%s;host=%s;port=%d',
                $dbCfg['name'],
                isset($dbCfg['host']) ? $dbCfg['host'] : 'localhost',
                isset($dbCfg['port']) ? $dbCfg['port'] : 3306
            );

再讲之前其实这里是有一个坑的,机智的童鞋应该发现了框架自带的user数据库里面有一个以from命名字段,应为在notorm生成sql语句的时候不会给自动自动加上引号 ,所以在修改添加删除有涉及这个字段的时候会报错,所以我们在这里把它改成phone(所以大家要注意字段名不能为关键字)

下面我们正式来讲解如何使用,我们先在Demo/Api下面创建一个DB.php文件作为我们的DB模块,

<?php
/**
 * 数据库接口服务类
 */
class Api_DB extends PhalApi_Api{
    public function getRules(){
        return array(
            'insert' => array(
                'id'    => array('name' => 'id', 'require' => true, 'desc' => '用户Id'),
                'name'  => array('name' => 'name', 'require' => true, 'desc' => '用户名称'),
                'phone' => array('name' => 'phone', 'require' => true, 'desc' => '用户手机号码'),
            ),
            'select' => array(
                'id' => array('name' => 'id', 'require' => true, 'desc' => '用户Id'),
            ),
            'update' => array(
                'id'    => array('name' => 'id', 'require' => true, 'desc' => '用户Id'),
                'name'  => array('name' => 'name', 'require' => true, 'desc' => '用户名称'),
                'phone' => array('name' => 'phone', 'require' => true, 'desc' => '用户手机号码'),
            ),
            'delete' => array(
                'id' => array('name' => 'id', 'require' => true, 'desc' => '用户Id'),
            ),
        );
    }

一共是增删改查四个接口代表四种操作(这里一定要配置好数据库,以及运行框架自带的sql文件phalapi_test.sql)

1.1 insert接口

我们先写增加接口如下:

/**
 * 新增表服务
 * @return int id 新增列的Id
 */
public function insert(){
    $data = array(                                               //用数组构成需要插入键值一一对应
        'id'    => $this->id,
        'name'  => $this->name,
        'phone' => $this->phone,
    );
    $rs   = DI()->notorm->user->insert($data);                  //执行数据库操作user代表的是表,返回结果是插入成功的值
    return $rs['id'];                                           //返回插入的id
}

重要的是 $rs = DI()->notorm->user->insert($data); 这段代码执行了sql语句,user是表名(这里的表名会加下在dbs中配置的表前缀组成一个完整的表名)我们试着运行一下http://localhost/Public/?service=DB.insert&name=miaomi&phone=13010001000&id=2会得到以下结果

1.2 select接口

查询接口如下:

/**
 * 查询
 * @return array data 结果集
 */
public function select(){
    $data   = array();
    $data[] = DI()->notorm->user->select('name,phone')->where('id', $this->id)->fetch();
    $data[] = DI()->notorm->user->select('name,phone')->where('id = ?', $this->id)->fetchAll();
    $data[] = DI()->notorm->user->select('name,phone')->where('id != ?', $this->id)->fetchRows();
    return $data;
}

执行http://localhost/Public/?service=DB.select&id=2会得到以下结果

为什么会有这样的区别,通过下面的一些小提示大家就能看到区别在哪里:

1.2.1 select方法

select方法主要是用来指定返回值,接受的是一个string他的作用于真正查询语句select和from之间填充,大家如果把select('name,phone') 改为 select('*') 就会得到包括id的所有字段的返回

1.2.2 where方法和排序

where方法是查询中的重要的一个环节

where('id', $this->id)等同于where('id = ?', $this->id)

where('id != ?', $this->id)这种方式只要是为了指定条件大于,等于,小于,不等于

当然如果是需要有多个条件就使用连续的where就可以->where('id != ?',1)->where('phone','1301000100')这种形式

关于排序的使用其实和where差不多使用->order('字段名')如果要反排序在字段名后面加上DESC

1.2.3 fetch,fetchAll和fetchRows

大家有看到上面执行的三条查询语句后面的结束放到都不同这里讲解一下他们的区别和怎么用他们使用单独去执行sql语句

fetch方法是获取单独的一条数据返回结果是不带下标的数组 ,fetchAll和fetchRows不同在于他们返回的是包含多条数据一个带下标的数组,可以看到在条件一样的情况下第一条和第二条查询出来的结果区别是第二条多了一个0的下标,从此可得到如果是确定返回结果只有一条优先使用fetch,如果是多条结果优先使用fetchAll和fetchRows.

fetchAll和fetchRows还提供了一个功能就是单独执行sql语句

$sql = 'select * from tbl_user where id = :id';
$params = array(':id' => $this->id);                 //替换:id为请求参数的id
DI()->notorm->user->queryAll($sql, $params);         //或fetchRows($sql, $params)

这样就可以执行sql语句,包括一些复杂的查询sql可以使用此内方法执行(关联查询应当优先使用这种形式)

1.3 update接口

修改接口如下:

/**
 * 修改
 */
public function update(){
    $data = array(
        'name'  => $this->name,
        'phone' => $this->phone,
    );
    $rs   = DI()->notorm->user->where('id', $this->id)->update($data);
    if($rs === false){
        throw new PhalApi_Exception_BadRequest('修改数据失败');
    }
}

大家可以试一试执行之后是否有修改数据库http://localhost/Public/?service=DB.update&id=2&phone=13011112222&name=wenwenwen

使用其实和添加接口差不多只是一个是吧id作为值,一个是作为条件

比较值得讲一下的是为什么使用if($rs === false)

原因是这样的,这里执行update方法之后获取得是影响行数,如果原本值就是一样的那就回返回0,只有在真正语句失败的时候会返回false所以这里使用全等于false作为判断是否执行成功的条件

1.4 delete接口

删除接口如下:

/**
 * 删除
 */
public function delete(){
    $rs   = DI()->notorm->user->where('id', $this->id)->delete();
    if($rs === false){
        throw new PhalApi_Exception_BadRequest('删除数据失败');
    }
}

http://localhost/Public/?service=DB.delete&id=2

删除的操作也很简单,不过if($rs === false)就算没有删除到数据也会返回成功,只有当语句失败会反悔false,如果需要未删除到数据提示出错的同学可以把等号减少一个

1.5 打印sql语句

有的时候光靠自己去看代码很难确定是不是哪里写的有问题,但是如果查看生成出来的sql语句就能很快的确定问题出现在哪里

大家可以试试在请求参数中加上 就可以打印出来生成的sql语句方便调试

包括执行时间和先后顺序也一同打印出来了,也可以帮助大家找到慢查询在哪里

2. 使用Model进行数据库操作

使用Model操作是为了提高开发效率,让同样数据库操作可以进行高度的复用,也便于修改起来改一处则全改这种效果

2.1 传统的Model操作

所谓传统的Model操作也就是把数据操作封装起来,方便调用比如/Model/User.php下面的getByUserId方法

public function getByUserId($userId) {
    return DI()->notorm->user->select('*')->where('id = ?', $userId)->fetch();
}

在内部直接封装数据库操作使用如下代码调用

    $model = new Model_User();
    $rs = $model->getByUserId($userId);

2.2 框架自带的Model操作

当然这里介绍model的目的当然是解读一下phalapi内部提供的model操作

使用自带model操作只需要继承PhalApi_Model_NotORM 在实现如下方法

protected function getTableName($id) {
    return 'user';
}

这个方法主要作用是为了添加这个model 的表名,其实这两个操作在/Model/User.php中已经实现了,我们来重构一下getByUserId方法如下

public function getByUserId($userId) {
    return $this->getORM()->select('*')->where('id = ?', $userId)->fetch();
}

$this->getORM()相当于DI()->notorm->(getTableName中设置的表名)

然后我们重写select接口如下:

public function select(){
    $model = new Model_User();
    return $model->getByUserId($this->id);
}

可以获得以下结果

在这里phalapi自带的model和传统的model对比起来区别在于,phalapi统一制定表名不会应为方法果断导致的表名写错的失误

另一方面phalapi自带的model提供了很多字基础操作,利用自动提示功能可以看到

我们来再次改造一下selete接口使用model自带的方法

public function select(){
    $model = new Model_User();
    return $model->get($this->id);
}

执行结果和上面是一样的,这里注意一点这里Id的名字是dbs中配置的'key' => 'id',要和数据库中的ID字段名对应,但是这样会有一些问题会在后面进阶篇提及到

3. 总结

在本小节着重讲了CURD操作,以及其中的一些操作的使用和怎么使用phalapi的model层,希望大家看完本小节之后进行一些练习来熟练的掌握使用phalapi对数据库的操作,关于数据库操作的一些小技巧会单独在进阶篇中抽出一小节来讲讲在实际项目开发中遇到的问题以及如何解决,希望大家进一步关注!

注:笔者能力有限有说的不对的地方希望大家能够指出,也希望多多交流!

时间: 2024-10-18 12:10:17

phalapi-入门篇5(数据库操作和Model层)的相关文章

[PhalApi实战篇(1)]Redis队列处理异步任务

[PhalApi实战篇(1)]Redis队列处理异步任务 前言 先在这里感谢phalapi框架创始人@dogstar,为我们提供了这样一个优秀的开源框架. 哈喽大家好呀!之前编写的PhalApi入门篇和进阶篇已经过去了好久了,在此之间也回答了很多小伙伴各种各样的问题,这里也希望吧里面一些问的比较多的和比较有趣的以及笔者在使用PhalApi一些新的体会,都提取出来为大家带来一些能够在实际开发中可以使用的技术或思想,那么我们就开始我们实战篇中的第一节 Redis队列处理异步任务 大家希望喵咪在Pha

PHP简单数据库操作类实例【支持增删改查及链式操作】_php技巧

本文实例讲述了PHP简单数据库操作类.分享给大家供大家参考,具体如下: 在进行项目开发时,数据库是必不可少的东西了.但是很多时候却又对数据库SQL语句的繁杂而感到头疼.提供一个我自己使用的数据库操作类(模型Model),供大家使用.支持增.删.改.查,支持链式操作,代码不到100行,非常小巧方便,很适合小项目的快速部署使用. /** * * @Authot: summer * * @E-mail: wenghang1228@me.com * * @Data: 2015-02-06 * * @Pr

php数据库操作model类(使用__call方法)_php技巧

本文实例讲述了php数据库操作model类.分享给大家供大家参考,具体如下: 该数据库操作类使用__call()方法实现了数据的查找功能. 代码如下: <?php /* 作者 : shyhero */ define("HOSTNAME","127.0.0.1"); define("USERNAME","root"); define("PASSWORD",""); define(&q

php实现的简单数据库操作Model类_php技巧

本文实例讲述了php实现的简单数据库操作Model类.分享给大家供大家参考,具体如下: 该数据库模型类可实现数据库的增删改查,简化数据库操作. 1. config.php代码: <?php define("HOSTNAME","127.0.0.1"); define("USERNAME","root"); define("PASSWORD",""); define("DA

php字符串操作函数入门篇

php教程字符串操作函数入门篇 1.字符串的定义与显示 定义:通过"",''来标志 显示:echo()和print(),但print()具有返回值值,1,而echo()没有,但echo比print()要快,print()能用在复合语句中. 2.字符串的格式化 printf(string $format[,mixed$args]) 第一参数是格式字符串,$args是要替换进来的值,prinf("%d",$num); 说明,如果想打印一个"%",必须

phalcon-入门篇8(Model层基础使用2)

phalcon-入门篇8(Model层基础使用2) 本教程基于phalcon2.0.9版本 前言 先在这里感谢各位phalcon技术爱好者,我们提供这样一个优秀的交流平台 在上一节我们已经介绍了,phalcon-Model层的配置和最简单的CURD的使用,那么你认为这样就完了?phalcon当然不会让你失望,今天跟着笔者一同来看phalcon还有那些新奇的使用方式,在上一篇我们仅仅只是建立了一个空的model层,这里今天也会对model的简单使用封装,函数今天一些说明,希望大家喜欢~ 注:笔者水

phalapi-进阶篇1(Api,Domain,和Model)

phalapi-进阶篇1(Api,Domain,和Model) 前言 先在这里感谢phalapi框架创始人@dogstar,为我们提供了这样一个优秀的开源框架. 本小节已经步入了进阶篇,在进阶篇中会着重谈论一些框架中运用的一些好的思想并且进行解读,本小节主要是讲解在Phalapi框架中推荐使用的三层结构Api+Domain+Model将从各个角度和整体角度进行讲解. 附上: 官网地址:http://www.phalapi.net/ 开源中国Git地址:http://git.oschina.net

phalapi-进阶篇5(数据库读写分离以及多库使用)

phalapi-进阶篇5(数据库读写分离以及多库使用) 前言 先在这里感谢phalapi框架创始人@dogstar,为我们提供了这样一个优秀的开源框架. 读写分离是我们常用的一种解决方案,它可以解决大量读操作的时候数据库瓶颈的问题,我们在真正开发一个项目的过程中可能会遇一个接口或者一个操作中需要用到多个数据库操作的时候怎么办,今天的教程就从这个两个问题出来,来聊聊使用phalapi怎么解决这个问题. 附上: 官网地址:http://www.phalapi.net/ 开源中国Git地址:http:

phalapi-入门篇6(小技巧和浅谈API适用范围以及入门篇总结)

phalapi-入门篇6(小技巧和浅谈API适用范围以及入门篇总结) 前言 先在这里感谢phalapi框架创始人@dogstar,为我们提供了这样一个优秀的开源框架. 本篇文章的目的在于把框架自带的一些好用,封装好的一些方便开发的类库简单的说一下,灵活使用可以提高开发效率,再就是因为在交流过程中有很多童鞋提出了一些关于什么样的项目怎么用API和web端怎么使用API这类的问题,我就我的理解把我的一些想法和大家交流一下,最后是对于入门篇做一下总结,以及对后面的一些教程做一下说明. 附上: 官网地址