(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' => '', // 指定从服务器序号

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

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

实际开发里,前台后台一般使用一个数据库,也就是说一个项目一个数据库,所以一个应用使用一个数据库,所以放到应用层级的配置文件Application\Common\Conf\config.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 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)拓展里作总结

ThinkPHP---thinkphp模型(M)的更多相关文章

  1. thinkphp在模型中自动完成session赋值

    相信用过thinkphp的用户都知道thinkphp的模型可以完成很多辅助功能,比 如自动验证.自动完成等,今天在开发中遇到自动完成中需要获取session值 然后自动赋值的功能,具体看代码:clas ...

  2. ThinkPHP 关联模型(二十)

    原文:ThinkPHP 关联模型(二十) ThinkPHP关联模型 两表关联查询:Message 和  user  关联条件uid(参考手册:模型->关联模型) 步骤: 一:创建Message表 ...

  3. ThinkPHP框架模型连贯操作(八)

    原文:ThinkPHP框架模型连贯操作(八) Thinkphp的连贯操作使用起来也是很灵活: *可能这里有的mysql函数没全部罗列出来,大家可以举一反三,形式雷同 一.常用连贯操作 1.where ...

  4. ThinkPHP 的模型使用详细介绍--模型的核心(七)

    原文:ThinkPHP 的模型使用详细介绍--模型的核心(七) 注意:本节是ThinkPhp框架对数据操作的核心处理部分 大家还是在这里看清楚可以将其剪切放到代码编辑器中查看 本章节给大家着重介绍模型 ...

  5. ThinkPHP 的模型使用对数据库增删改查(五)

    原文:ThinkPHP 的模型使用对数据库增删改查(五) ThinkPHP 的模型使用 // 直接连接数据库,但是得先去配置文件中配置下才行 class IndexAction extends Act ...

  6. thinkphp 中模型究竟是什么用?

    thinkphp 中模型究竟是什么用? 问题 似乎所有的操作都能在控制器中就能完成,模型除了几种验证之外,究竟是干什么用的,这个问题一直没理解透 解答 解答一 要明白这个问题,必须了解 MVC 历史. ...

  7. ThinkPHP关联模型详解

    在ThinkPHP中,关联模型更类似一种mysql中的外键约束,但是外键约束更加安全,缺点却是在写sql语句的时候不方便,ThinkPHP很好得解决了这个问题.但是很多人不动关联模型的意思.现在就写个 ...

  8. ThinkPHP关联模型如何关联非主键

    ThinkPHP关联模型默认是主键外键关联 官方并没有提供相关文档 如何实现非主键与非主键间之间的关联 <?php namespace Admin\Model; use Think\Model\ ...

  9. ThinkPHP支持模型的分层

    ThinkPHP支持模型的分层 ,除了Model层之外,我们可以项目的需要设计和创建其他的模型层. 大理石平台支架 通常情况下,不同的分层模型仍然是继承系统的\Think\Model类或其子类,所以, ...

  10. ThinkPHP - 关联模型 - 一对多

    使用之前,先引入文件夹,否则相应的功能不能实现. 如果对thinkPHP不精通,使用或开发的时候,最好直接使用完成版本的ThinkPHP. 关系模型定义: <?php /** * 继承自 Rel ...

随机推荐

  1. 【bzoj4034】[HAOI2015]T2

    siz[v]表示以v为根的子树的节点数 top[v]表示v所在的重链的顶端节点 fa[v]表示v的父亲 pos[v]表示v的父边标号 mx[v]表示v的子树中边的标号最大的那条边 参考:http:// ...

  2. Bridge Page

    http://www.zzbaike.com/wiki/%E6%A1%A5%E9%A1%B5 桥页(Bridge Page),又叫“门页”(Doorway/Portal/Jump/Entry Page ...

  3. luogu3942将军令

    https://www.zybuluo.com/ysner/note/1302132 题面 在大小为\(n\)的树上选择尽量少的点,使得所有未选择的点距离选择了的点小于等于\(k\). \(n\leq ...

  4. [POI2011]LIZ-Lollipop

    https://www.zybuluo.com/ysner/note/1303462 题面 给一个只有\(1\)和\(2\)的序列,每次询问有没有一个子串的和为\(x\). \(n\leq10^6\) ...

  5. vue商品详情页添加动画(eg)

    <template> <div class="food" transition="move"></div> </tem ...

  6. Final关键字解析

    final 在 Java 中是一个保留的关键字,可以声明变量.方法.类. 什么是final变量 / 类 / 方法? 任何变量前被 final 修饰就是 final 变量,定义的类前被 final 修饰 ...

  7. 聊聊LuaJIT

    JIT 什么是JITJIT = Just In Time即时编译,是动态编译的一种形式,是一种优化虚拟机运行的技术. 程序运行通常有两种方式,一种是静态编译,一种是动态解释,即时编译混合了这二者.Ja ...

  8. jwt的应用生成token,redis做储存

    解释一下JWT JWT就是一个字符串,经过加密处理与校验处理的字符串,由三个部分组成.基于token的身份验证可以替代传统的cookie+session身份验证方法.三个部分分别如下: header. ...

  9. yii int

    @echo off rem ------------------------------------------------------------- rem Yii command line ini ...

  10. Python Turtle绘图

    1. 画布(canvas) 画布就是turtle为我们展开用于绘图区域, 我们可以设置它的大小和初始位置 1.1 设置画布大小 turtle.screensize(canvwidth=None, ca ...