ThinkPHP 学习笔记 ( 三 ) 数据库操作之数据表模型和基础模型 ( Model )

   ThinkPHP 提供了一个 Model 类,供其他的 Model 进行继承。Model 类中是
MVC 中的模型类,它是调用 持久层
的上层类。感觉这么描述问题很多,但是有什么办法呢?但是,这个 Model
有时无法满足我们的一些需求,因此我们需要自定义一个 Model
类出来,不过自定义的 Model 同样要继承 TP 提供的 Model
类,而把我们自定义的 Model 类作为我们项目中的 Model
基类。我怎么感觉我在说绕口令,等等...我有点晕。

//TP 恶补ing... 

 

一、定义数据表模型

无聊的需求

1.模型映射

  在使用 Java 的开源项目 JeeSite
时,养成了一个不好的习惯,习惯给每张表都增加
create_by、create_date、update_by、update_date、remarks 和 del_flag
这么几个字段。如果每张表都有这几个字段,那么对每张表进行 insert
时都会对以上的字段进行设置,对每张表进行 update
时都会对其中部分字段进行更新,对每条记录进行 delete 时都其实是对
del_flag 字段进行
置位。重复操作很多,一些操作方法被修改。那么,这个时候就要自定义一个自己的
Model 来作为项目的 基类 了,这个 Model 就负责干上面我说的那些事情了。

要测试数据库是否正常连接,最直接的办法就是在当前控制器中实例化数据表,然后使用
dump 函数输出,查看数据库的链接状态。代码:

 

public function testdb(){ $obj=M("User"); dump($obj); }

自定义一个 Model

此时浏览器输出:

  自定义一个 Model,Model 中至少重新 TP 提供的 Model 中的
add、save、delete 和 select 方法。

图片 1图片 2

  定义代码如下:

object(Model)#5 (20) { ["_extModel:private"] => NULL ["db:protected"] => object(DbMysql)#7 (18) { ["dbType:protected"] => string(5) "MYSQL" ["autoFree:protected"] => bool(false) ["model:protected"] => string(7) "_think_" ["pconnect:protected"] => bool(false) ["queryStr:protected"] => string(28) "SHOW COLUMNS FROM `tpk_user`" ["modelSql:protected"] => array(1) { ["user"] => string(28) "SHOW COLUMNS FROM `tpk_user`" } ["lastInsID:protected"] => NULL ["numRows:protected"] => int(2) ["numCols:protected"] => int(0) ["transTimes:protected"] => int(0) ["error:protected"] => string(0) "" ["linkID:protected"] => array(1) { [0] => resource(27) of type (mysql link) } ["_linkID:protected"] => resource(27) of type (mysql link) ["queryID:protected"] => resource(28) of type (mysql result) ["connected:protected"] => bool(true) ["comparison:protected"] => array(10) { ["eq"] => string(1) "=" ["neq"] => string(2) "<>" ["gt"] => string(1) ">" ["egt"] => string(2) ">=" ["lt"] => string(1) "<" ["elt"] => string(2) "<=" ["notlike"] => string(8) "NOT LIKE" ["like"] => string(4) "LIKE" ["in"] => string(2) "IN" ["notin"] => string(6) "NOT IN" } ["selectSql:protected"] => string(96) "SELECT%DISTINCT% %FIELD% FROM %TABLE%%JOIN%%WHERE%%GROUP%%HAVING%%ORDER%%LIMIT% %UNION%%COMMENT%" ["bind:protected"] => array(0) { } } ["pk:protected"] => string(2) "id" ["tablePrefix:protected"] => string(4) "tpk_" ["name:protected"] => string(4) "user" ["dbName:protected"] => string(0) "" ["connection:protected"] => string(0) "" ["tableName:protected"] => string(0) "" ["trueTableName:protected"] => string(8) "tpk_user" ["error:protected"] => string(0) "" ["fields:protected"] => array(5) { [0] => string(2) "id" [1] => string(8) "username" ["_autoinc"] => bool(true) ["_pk"] => string(2) "id" ["_type"] => array(2) { ["id"] => string(7) "int(11)" ["username"] => string(11) "varchar(20)" } } ["data:protected"] => array(0) { } ["options:protected"] => array(0) { } ["_validate:protected"] => array(0) { } ["_auto:protected"] => array(0) { } ["_map:protected"] => array(0) { } ["_scope:protected"] => array(0) { } ["autoCheckFields:protected"] => bool(true) ["patchValidate:protected"] => bool(false) ["methods:protected"] => array(13) { [0] => string(5) "table" [1] => string(5) "order" [2] => string(5) "alias" [3] => string(6) "having" [4] => string(5) "group" [5] => string(4) "lock" [6] => string(8) "distinct" [7] => string(4) "auto" [8] => string(6) "filter" [9] => string(8) "validate" [10] => string(6) "result" [11] => string(4) "bind" [12] => string(5) "token" } }
 1 <?php 2 namespace Admin\Model; 3 use Think\Model; 4 5 /** 6 * 项目中其他 Model 类的基类 7 * 该类继承自 TP 提供的基类 Model 8 */ 9 class BaseModel extends Model {10 11 /**12 * 继承基类 Model 的 add 方法13 * 自动插入 id create_by create_date update_by update_date del_flag14 */15 public function add($data='',$options=array(),$replace=false) {16 17 $data["id"] = $this->getUuid();18 $data["create_by"] = "";19 $data["create_date"] = date("Y-m-d H:i:s");20 $data["update_by"] = "";21 $data["update_date"] = date("Y-m-d H:i:s");22 $data["del_flag"] = '0';23 24 return parent::add($data, $options, $replace);25 }26 27 /**28 * 获得 未删除 的所有数据29 * 记录是否被删除通过 del_flag 字段来进行确定30 */31 public function select($options=array()) {32 $map["del_flag"] = 0;33 $this->where($map);34 35 return parent::select($options);36 }37 38 /**39 * 获取 全部 的所有数据40 */41 public function selectAll($options=array()) {42 return parent::select($options);43 }44 45 /**46 * 更新数据47 * 更新数据时,要更新 update_by update_date 两个字段48 */49 public function save($data='',$options=array()) {50 $data["update_by"] = "";51 $data["update_date"] = date("Y-m-d H:i:s");52 53 return parent::save($data, $options);54 }55 56 /**57 * 删除也是更新58 * 设置 删除 标志位即可59 */60 public function delete($data='',$options=array()) {61 $data["del_flag"] = 1;62 63 return parent::save($data, $options);64 }

  这样,我们的 BaseModel 就定义好了,以后项目中的 Model 就不再继承 TP
的 Model 类了,而是继承我们自定义的 BaseModel 了。

如果没有提示错误即为成功。

 

M("User") 就是模型映射,M 函数等于 new Model() ,Model
类是模型的基类,也是数据库操作的基类, "User"
是该类的一个成员属性,表示模型名称,模型名称与数据库中的数据表进行映射。注意:User
"U" 要大写,数据库中此时应该存在一张 user
表,系统会根据配置文件中的设置给 user 表添加前缀,例如
tpk_user。如果不需要为表添加前缀,将模型名称首字母改为小写,例如
M("user")。

继承我们定义的基类

 

  继承的 BaseModel 的方法和继承 Model 的方法是一样的,只是使用 use
引入命名空间到当前作用域时的需要修改为我们的命名空间,而不是再去使用 TP
提供的命名空间。代码如下:

2.自定义模型

1 <?php2 namespace Admin\Model;3 use Admin\Model\BaseModel;4 5 class TrunkModel extends BaseModel {

D
函数用于快速实例化自定义模型,可以进行复杂的数据库操作,比如数据检验、数据缓存、数据加工等。自定义模型存放在
Lib/Model 目录下,例如为数据表 tpk_article
数据表建立模型映射,则需要创建 ArticleModel.class.php,然后使用 D
函数进行实例化,ArticleModel 模型将与 tpk_article 表进行映射。

  use 引入的命名空间是 Admin\Model\BaseModel ,因为我们定义的
BaseModel 的命名空间是 Admin\Model,因为这里的 TrunkModel 和 BaseModel
在一个命名空间下,省去 use 也是可以的。

例:使用 select() 输出 tpk_article 表的数据 ( select()
方法用于列出所有符合条件的数据 ) :

 

class IndexAction extends Action { public function article(){ $obj=D("Article"); $rows=$obj->select(); dump($rows); } }

  这样,在我们用 D 方法实例化 TrunkModel 的对象后,使用 add
方法插入数据时,就会先调用 BaseModel 中的 add
方法了,这样我们每张表都有的 create_by 等一系列字段就都会自动得到了。

浏览器输出:

图片 3图片 4

array(6) { [0] => array(7) { ["id"] => string(1) "1" ["title"] => string(4) "test" ["content"] => string(12) "test_content" ["category"] => string(13) "test_category" ["area"] => string(6) "北京" ["add_user"] => string(5) "admin" ["add_time"] => string(19) "2014-11-20 23:03:44" } [1] => array(7) { ["id"] => string(1) "2" ["title"] => string(12) "吼吼吼吼" ["content"] => string(18) "任溶溶柔然人" ["category"] => string(14) "test_category2" ["area"] => string(6) "河北" ["add_user"] => string(5) "admin" ["add_time"] => string(19) "2014-11-22 15:16:12" } [2] => array(7) { ["id"] => string(1) "4" ["title"] => string(7) "test2_m" ["content"] => string(4) "haha" ["category"] => string(0) "" ["area"] => string(6) "福建" ["add_user"] => NULL ["add_time"] => string(19) "2014-11-22 11:44:26" } [3] => array(7) { ["id"] => string(1) "5" ["title"] => string(2) "22" ["content"] => NULL ["category"] => string(0) "" ["area"] => string(6) "福建" ["add_user"] => NULL ["add_time"] => string(19) "2014-11-22 12:40:58" } [4] => array(7) { ["id"] => string(1) "6" ["title"] => string(1) "1" ["content"] => string(1) "2" ["category"] => string(0) "" ["area"] => string(6) "福建" ["add_user"] => NULL ["add_time"] => NULL } [5] => array(7) { ["id"] => string(1) "7" ["title"] => string(6) "lalala" ["content"] => string(6) "hohoho" ["category"] => string(0) "" ["area"] => string(6) "北京" ["add_user"] => NULL ["add_time"] => NULL } }

 

例2:让 tpk_article 表的内容根据客户所在的地区显示当地的新闻:

ArticleModel.class.php:

<?php class ArticleModel extends Model{ public function article(){ $rows=$this->where("area='{$this->checkUserArea()}'")->select(); return $rows; } protected function checkUserArea(){ return "北京"; }

控制器代码:

IndexAction.class.php:

<?php class IndexAction extends Action { $obj=D("Article"); $rows=$obj->article(); $this->assign("list",$rows); $this->display();

同时视图代码:

TPL/Index/article.html:

<!DOCTYPE html> <html> <body> <volist name="list" id="vo"> <li><{$vo.title}> - <{$vo.area}> - <{$vo.content}></li> </volist> </body> </html>

附:数据表 tpk_article 的表结构为:

图片 5

总结:自定义模型映射,一个模型对应一个数据表,所有增删改查都在模型类中完成。M
实例化的参数是数据库的表名,D 实例化的是自己在 model
文件夹下建立的模型文件。

 

3.create 方法

TP 对数据的插入和更新都做了高度封装:提供了 create()
方法用于创建数据对象。

概念:数据对象 ——
数据字段与数据表之间的关系,数据会被映射为类成员,再与数据表映射,最后实现数据的插入或更新。

create() 方法是连贯操作、CURD 操作的集合 (
包括数据创建、数据检验、表单验证、自动完成等 )。

cerate() 的数据源由 POST 表单提供,比如表单中有 username
表单元素,则该元素会被自动映射为数据表中的 username
字段。数据对象创建成功以后,对象被存放于内存中。

例:添加数据

控制器:IndexAction,动作:add_article,代码:

IndexAction.class.php:

<?php class IndexAction extends Action { Public function add_article(){ $this->display(); } }

视图: Tpl/Index/add_article.html:

<!DOCTYPE html> <html> <body> <form method="post" action="__URL__/add"> <input type="text" name="title" placeholder="标题"><br><br> <textarea name="content" id="content" placeholder="内容"></textarea><br><br> <input type="submit" name="submit" value="提交"> </form> </body> </html>

__URL__/add 表示当前控制器的 add 动作。

add 动作代码:

相关文章

Comment ()
评论是一种美德,说点什么吧,否则我会恨你的。。。