文档章节

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

喵了_个咪
 喵了_个咪
发布于 2015/10/06 11:45
字数 2380
阅读 814
收藏 2

#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对数据库的操作,关于数据库操作的一些小技巧会单独在进阶篇中抽出一小节来讲讲在实际项目开发中遇到的问题以及如何解决,希望大家进一步关注!

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

官网QQ交流群:421032344 欢迎大家的加入!

© 著作权归作者所有

共有 人打赏支持
喵了_个咪
粉丝 328
博文 151
码字总数 200145
作品 4
杨浦
技术主管
私信 提问
加载中

评论(2)

喵了_个咪
喵了_个咪

引用来自“KeenLeung”的评论

你好,想请教一下大神T_T进行 insert 操作,如果字符中包含中文字符,应该怎么处理 ?谢谢
应该是没有问题的 可以正常使用 是不是你的数据库的字符集配置的有问题 还有问题的话可以加群 421032344 一起讨论
K
KeenLeung
你好,想请教一下大神T_T进行 insert 操作,如果字符中包含中文字符,应该怎么处理 ?谢谢
PhalApi 1.3.5 贺岁发布,PHP 轻量接口框架

[前言] 借春节来临之际, PhalApi(π框架)在此发布v1.3.5幺鸡贺岁小版本,同时祝愿各位同学新春快乐、万事如意! 基于老版本开发的应用可以无缝升级到v1.3.5版本,直接覆盖核心文件PhalApi...

暗夜在火星
2017/01/06
825
6
PhalApi(π框架) v1.4.1 发布,PHP 轻量级 API 接口开发框架

[前言] 夏天的脚步悄悄来临,在各位小伙伴的辛勤付出下,PhalApi迎来了新版本V1.4.1,在这次更新中着重以开发者便捷为本新增优化了很多功能,如对接口文档添加了各项重要功能可以直接在文档页面进...

喵了_个咪
2017/07/01
1K
4
PhalApi-v1.3.4 发布,PHP 轻量级开源接口框架

PhalApi-v1.3.4 (暑假炫酷版)发布,PHP轻量级开源接口框架 【前言】 在这火辣辣的季节里,在大家共同的努力下,PhalApi又迎来了重要的一次更新,在本次更新中更多的吸取了大家的建议,对Pha...

喵了_个咪
2016/08/02
1K
7
PhalApi-v1.3.1 (感恩版)发布,PHP 轻量级开源接口框架

PhalApi-v1.3.1 (感恩版)发布,PHP轻量级开源接口框架 [前言] 感恩节来临之际,PhalApi迎来了等候了一个多月的v1.3.1版本更新. 在v1.3.1版本中着重对1.3.0版本中存在BUG进行了修复,并且进一步...

喵了_个咪
2015/11/28
1K
5
PhalApi 1.2.0 发布,PHP 后台接口开发框架

PhalApi 1.2.0 版本的开启,是为了更好地进入多人协助开发时代 其中,主要更新内容如下: 1、接口返回参数,根据代码return注释,自动生成在线文档 2、接口参数规则中追加对文件参数的验证支...

暗夜在火星
2015/06/05
1K
30

没有更多内容

加载失败,请刷新页面

加载更多

极路由4刷OpenWrt(LEDE)

申请开发者模式 登录路由器后台 进入插件中间 选中路由器信息 申请开发者权限 安装开发者插件 刷 Bootloader 下载 极路由4 的 Breed 通过SSH登录路由器 (必须安装开发者插件,端口 1022 账号...

dingdayu
31分钟前
2
0
浅淡个人学习嵌入式Linux过程

我专业是电子信息工程,在初入大学的时候,我们的班主任便要我们多多去了解一些关于电子方面的知识。后来我了解到了嵌入式,继而了解到了嵌入式Linux。其实我们学习linux差不多就学习linux内...

linux-tao
今天
6
0
SpringBoot使用GraphQL简单学习-1

官网 一、GraphQL简介 1.GraphQL是什么? GraphQL 既是一种用于 API 的查询语言也是一个满足你数据查询的运行时。 GraphQL 对你的 API 中的数据提供了一套易于理解的完整描述,使得客户端能够...

wind2012
今天
4
0
Android的WIFI局域网对讲机

https://blog.csdn.net/z979451341/article/details/79280749 (三)Android局域网内语音对讲 基于UDP语音传输 https://blog.csdn.net/stormxiaofeng/article/details/80513947 Android7.0手......

shzwork
今天
2
0
vuex

一直有个误区 vuex既然页面刷新会丢失 那还有什么意义 。 重新翻看了下文档才恍然大误,vuex主要解决的是不同组件间的通信。 跨页面数据共享本质上还是用sessionStorage/localStorage...

东东笔记
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部