ThinkPHP---thinkphp模型(M)

(1)配置数据库链接php

数据库的链接配置能够在系统配置文件ThinkPHP/Conf/convention.php中找到html

/* 数据库设置 */
    'DB_TYPE'               =>  '',     // 数据库类型,通常为MySQL
    'DB_HOST'               =>  '', // 服务器地址,本地开发时为localhost,远程为远程ip
    'DB_NAME'               =>  '',          // 数据库名
    'DB_USER'               =>  '',      // 用户名
    'DB_PWD'                =>  '',          // 密码
    'DB_PORT'               =>  '',        // 端口,3306.若是填写了MySQL,能够不填
    'DB_PREFIX'             =>  '',    // 数据库表前缀。例如sp_user,前缀为sp。至于缘由在文章里作了介绍
    'DB_PARAMS'              =>  array(), // 数据库链接参数    
    'DB_DEBUG'              =>  TRUE, // 数据库调试模式 开启后能够记录SQL日志
    'DB_FIELDS_CACHE'       =>  true,        // 启用字段缓存
    'DB_CHARSET'            =>  'utf8',      // 数据库编码默认采用utf8
    'DB_DEPLOY_TYPE'        =>  0, // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
    'DB_RW_SEPARATE'        =>  false,       // 数据库读写是否分离 主从式有效
    'DB_MASTER_NUM'         =>  1, // 读写分离后 主服务器数量
    'DB_SLAVE_NO'           =>  '', // 指定从服务器序号

找到后不能直接在系统配置文件里修改,应该放到对应配置文件里。配置文件除了系统配置文件外,还有分组/平台配置文件和应用配置文件。mysql

那么数据库配置文件位置放到哪一个层级的配置文件呢?面试

实际开发里,前台后台通常使用一个数据库,也就是说一个项目一个数据库,因此一个应用使用一个数据库,因此放到应用层级的配置文件Application\Common\Conf\config.phpsql

里。thinkphp

<?php
return array(
    //'配置项'=>'配置值'
    /* 数据库设置 */
    'DB_TYPE'               =>  'mysql',     // 数据库类型,除此外还有可能用到access,oracle,sqlite,db2
    'DB_HOST'               =>  'localhost', // 服务器地址,如果远程服务器,则填写远程IP
    'DB_NAME'               =>  'db_oa',          // 数据库名
    'DB_USER'               =>  'root',      // 用户名
    'DB_PWD'                =>  'root',          // 密码
    'DB_PORT'               =>  '3306',        // 端口
    'DB_PREFIX'             =>  'sp_',    // 数据库表前缀,设置时必须加下划线
);

(2)建立数据库和数据表数据库

数据库名:db_oa数组

数据表名:  sp_dept(department部门);缓存

准备好sql语句:服务器

create database db_oa;//建立数据库
use db_oa;//调用数据库
create table sp_dept(
    id int not null auto_increment,
    name varchar(50) not null,
    pid int not null default 0,//部门分上下级,pid只下级部门id
    sort int not null default 50,//排序
    remark varchar(255),//备注说明
    primary key(id)
)engine=myisam default charset=utf8;//引擎myisam,Mysql的默认存储引擎

知识点:not null不为空;auto_increment自增;default默认;

这里除了经过命令行cmd建立,还可使用Navicat Premium。它是一个可多重链接的数据库管理工具,它可以让你以单一程序同时链接到MySQL、SQL Server、SQLite、Oracle、

PostgreSQL数据库,让管理不一样类型的数据库更加方便。数据库/表的具体建立及使用我在文章Navicat使用方法里作了总结

(3)模型建立

1. 什么是模型?

模型是MVC中的M(model),做用负责与数据表的数据交互(CURD,即建立Create、更新Update、读取Retrieve和删除Delete操做)

 

2. 模型的建立

    ①命名规范:模型名+Model关键词+class.php(与控制器的命名规范大体相同:控制器名+Controller关键词+class.php)

       注意:由于模型是用来操做数据表,因此模型实例化时确定须要去关联一张表。所以模型名要求是不带前缀的表名,且首字母大写

    ②代码结构规范(与控制器相似)

        第一步:声明命名空间;

        第二部:引入父类模型Model.class.php;

        第三部:声明并继承父类模型。

3. 案例

    例如后期须要部门模型DeptModel.class.php实现对部门数据表sp_dept的操做,模型名的命名通常为关联的数据表表名去掉前缀。这里我在Admin/Model下建立模型文件

<?php
    namespace Admin\Model;//声明命名空间(分组\目录)
    use Think\Model;//引入父类模型(Think开头是由于Think.class.php文件的命名空间为Think)
    //声明并继承模型
    class DeptModel extends Model{
    }
?>

   注意:空模型仍然能够进行数据表的(CURD操做),由于继承了父类模型,能够执行基本的操做增删改查,由于父类中已经封装好了CURD方法

(4)模型实例化(建立控制器,链接数据表)

模型的本质是类,类在使用时须要实例化操做。

1. 普通实例化

    经过本身编写代码来new对象,$obj接受实例化结果,而后实例化类建立出一个对象。接下来在控制器里定义一个方法来实例化模型,使用普通方法实例化

建立部门控制器文件,Admin/Controller/DeptController.class.php:

<?php
    namespace Admin\Controller;
    use Think\Controller;
    class DeptController extends Controller{
        public function dept(){
            $model = new \Admin\Model\DeptModel();
            dump($model);
        }
    }
?>

经过输出结果,发现模型在控制器里实例化的时候自动关联了数据表,为何自动关联?

由于当前模型名字是表名去掉后缀。因此在控制器中进行实例化时,系统底层会自动关联上相关的数据表。虽然模型里没有前缀,可是配置信息里设置了数据表前缀

/* 数据库设置 */
    'DB_PREFIX'    =>  'sp_',    // 数据库表前缀,设置时必须加下划线

2. 快速实例化方法

      上述实例化方法虽然能够进行实例化操做,但使用麻烦,还需考虑命名空间。因此ThinkPHP为了简单快速高效开发,提供了两个快速方法(M和D)来实例化模型。

D方法:$obj = D(['模型名']);

             上述表示实例化咱们本身建立的模型(分组/Model目录中),除了本身建立的模型外还有父类模型(系统模型)。若是传递了模型名,则实例化指定的模型;若没有传递模型名或模型名不存在,则实例化系统模型(父类模型Model.class.php)

M方法:$obj = M(['不带前缀的表名']);

             表示直接实例化父类模型,即系统模型(Think/Model.class.php)。若指定了表名,则实例化父类模型时,关联指定表;若没有传递参数则不关联表,不关联时通常用于执行原生的sql语句(M()->query(原生的sql语句))

D和M方法区别:实例化对象不一样

案例: 

        ①实例化自定义模型,其实例化结果与普通new方法同样

$model = D('Dept');
dump($model);

       若不传参数实例化,则会实例化父类模型(系统模型)。结果与上诉不一样,系统模型Tnink/Model位置不一样,且没有关联表

$model = D();
dump($model);

      ②实例化父类模型

         若传入了表名,则会在实例化时关联数据表

$model = M('dept');//这里传递了dept数据表,因此会在实例化时关联dept数据表
$model = M();//实例化父类模型,但不关联数据表 dump(
$model);

拓展:经典面试题:

①实例化方法中D方法和M方法区别?

 

 实例化的对象不一样。D方法将自定义的模式进行实例化,若自定义模型不存在,则实例化父类模型(系统模型),而M方法是直接实例化(父类)系统模型

 ②开发中如何选取实例化方法?

 根据项目状况,若当前须要的操做在父类中已经封装好了,则直接实例化父类(M方法)。若父类中的方法不能知足开发需求,须要自定义方法,则可使用D方法实例化自定义模型。通常的增删改查操做在父类模型里已经封装好了,直接使用M方法实例化便可

【五】CURD操做

模型操做数据表的基本操做

(1)增长操做

 在MySQL里增长操做语句是insert...into...,但在ThinkPHP里系统封装好了模型里的方法add。

 语法:$model->add(一维键值数组),注意:一维数组必须是一维的关联数组,且键必须和数据表的字段名匹配。如不匹配则在增长时会被ThinkPHP过滤掉

案例:往部门表里添加一条记录

public function dept(){
            $model = M('dept');
            //声明关联数组
            $person = array(
                'name'=>'人事部',
                'pid'=>'0',
                'sort'=>'1',
                'remark'=>'这是人事部门'
            );
            $result = $model -> add($person);//返回新增记录的主键id
            dump($result);
}

补充:如何需添加多个记录?

         ①循环;

         ②addAll方法,语法:$model->addAll(二维数组),要求最里面的一维数组必须为关联数组(要求键名与数据表字段匹配),另外外层数组必须是从0开始的连续的索引数组

            注意:虽然数组中顺序无关,可是要求子数据的第一条数组的键名顺序必须与数据表一致,后面的子数组键名顺序随意,由于后面的都会按照第一条的键名顺序填写

public function dept(){
            $model = M('dept');
            //声明关联数组
            $person = array(
                array(
                    'remark'=>'这是人事部门2',
                    'name'=>'人事部2',
                    'pid'=>'0',
                    'sort'=>'1'
                ),
                array(
                    'remark'=>'这是人事部门1',
                    'name'=>'人事部1',
                    'pid'=>'0',
                    'sort'=>'1'
                )
                
            );
            $result = $model -> addAll($person);//返回新增记录的逐渐id
            dump($result);
        }

(2)修改操做

在MySQL里修改操做使用update table语句+where条件。在ThinkPHP中使用save方法,语法:$model->save(一维关联数组)

条件须要一维关联数组必须有主键信息(至关于where条件),若没有主键信息,则至关于批量修改。在ThinkPHP里,为了仿制误操做致使批量修改或删除,不容许批量操做

案例:使用save方法修改部门表中财务部门信息

public function dept(){
            //实例化模型
            $model = M('dept');
            //声明关联数组
            $change = array(
                'id'=>2,//当前表获得主键,若是没有指定主键信息,则返回值为false。表示修改操做没有执行
                'name'=>'修改2',
                'remark'=>'修改备注'
            );
            $result = $model -> save($change);//返回值表示收到影响的行数
            dump($result);
        }

注意:必须有主键信息(至关于where条件),不然返回false

 (3)查询操做

MySQL查询操做为select。在ThinPHP里系统封装了两个方法用于查询,select方法和find方法

       select语法:①$model->$select();  查询所有信息

                           ②$model->select(id);  查询指定id的信息

                           ③$model->select('id1,id2,id3,id4...');   等价于MySQL的where id in('1,2,3,4'),表示查询指定id集合的信息

        find语法:①$model->find();    查询当前数据表的第一个信息,至关于limit 1;

                         ②$model->find(id);  查询表里指定id的数据

区别:select方法返回值是二维数组,即便只查询到了一条记录也是返回二维数组;而find方法返回一维数组

案例:使用select和find方法查询部门表中的数据

public function select(){
            //实例化模型
            $model = M('dept');
            //select查询
$result = $model->select();//查询全部 $result = $model->select('1');//查询id为1的记录
$result = $model->select('1,3,5');//查询id为1,3,5的记录 dump(
$result); }

select方法即便只查询一条数据,仍然会返回二维数组,以下

array(1) {
  [0] => array(5) {
    ["id"] => string(1) "1"
    ["name"] => string(3) "one"
    ["pid"] => string(1) "0"
    ["sort"] => string(2) "50"
    ["remark"] => string(9) "第一个"
  }
}

 对比find查询结果以下

array(5) {
  ["id"] => string(1) "1"
  ["name"] => string(3) "one"
  ["pid"] => string(1) "0"
  ["sort"] => string(2) "50"
  ["remark"] => string(9) "第一个"
}

 find查询:

public function select(){
            //实例化模型
            $model = M('dept');
            //find查询
            $result = $model->find();//返回第一条记录,至关于limit 1
            $result = $model->find('2');//返回指定id所在的记录
            dump($result);
}

(4)删除操做

在MySQL中使用delete from语句删除,在ThinkPHP里系统封装好了delete方法删除记录

语法:

       ①$model->delete();    //由于ThinkPHP不支持没有指定主键的操做,因此该方法不支持

       ②$model->delete(id);  删除指定id对应的记录

       ③$model->delete('id1,id2,id3,...')   删除多个id对应的记录

注意:删除分两种物理删除、逻辑删除。

         物理删除:真删除

         逻辑删除:假删除,本质是修改操做。在数据表里定义一个状态字段status,取值0和1。当进行读取时只会读取状态值为1的数据,若用户点击删除,则会触发状态status转为0。从而在读取时获取不到,形成删除的假象。实际开发中也是常有逻辑删除(信息就是资源!!)

案例:使用delete进行删除操做(真删除)

public function del(){
            //实例化模型
            $model = M('dept');
            //delete删除
            $result = $model->delete();//返回false
            $result = $model->delete('1');//删除指定id的记录,返回影响行数
            $result = $model->delete('1,2,3');//删除多个id的记录,返回影响行数
            dump($result);
}

 

【六】Tp中的模型

具体在文章视频学习笔录---ThinkPHP---thinkphp模型(M)拓展里做总结

相关文章
相关标签/搜索