• ThinkPHP---thinkphp模型(M)


    (1)配置数据库连接

    数据库的连接配置可以在系统配置文件ThinkPHP/Conf/convention.php中找到

    /* 数据库设置 */
        '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'           =>  '', // 指定从服务器序号

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

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

    实际开发里,前台后台一般使用一个数据库,也就是说一个项目一个数据库,所以一个应用使用一个数据库,所以放到应用层级的配置文件ApplicationCommonConfconfig.php

    里。

    <?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 AdminModel;//声明命名空间(分组目录)
        use ThinkModel;//引入父类模型(Think开头是因为Think.class.php文件的命名空间为Think)
        //声明并继承模型
        class DeptModel extends Model{
        }
    ?>

       注意:空模型仍然可以进行数据表的(CURD操作),因为继承了父类模型,可以执行基本的操作增删改查,因为父类中已经封装好了CURD方法

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

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

    1. 普通实例化

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

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

    <?php
        namespace AdminController;
        use ThinkController;
        class DeptController extends Controller{
            public function dept(){
                $model = new AdminModelDeptModel();
                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)拓展里作总结

  • 相关阅读:
    最近在学习vala,并打算用它写点东西, 先上个习作 -- popplersample
    GTK# 学习笔记
    monodevelop2.0在SmartQ5上成功运行
    c, cs, vala 性能简单测试
    在Q5上用vala写程序
    树结构型数据在基于关系型数据库的分布式应用的解决方案
    常用常忘的delegate,记一下。
    JSON
    HTML5脚本编程
    event事件对象
  • 原文地址:https://www.cnblogs.com/fightjianxian/p/8667333.html
Copyright © 2020-2023  润新知