搜文章
推荐 原创 视频 Java开发 iOS开发 前端开发 JavaScript开发 Android开发 PHP开发 数据库 开发工具 Python开发 Kotlin开发 Ruby开发 .NET开发 服务器运维 开放平台 架构师 大数据 云计算 人工智能 开发语言 其它开发
Lambda在线 > ArchieCMS > Thinphp模型

Thinphp模型

ArchieCMS 2018-06-28

在ThinkPHP中基础的模型类就是Think\Model类,该类完成了基本的CURD、ActiveRecord模式、连贯操作和统计查询,一些高级特性被封装到另外的模型扩展中。

基础模型类的设计非常灵活,甚至可以无需进行任何模型定义,就可以进行相关数据表的ORM和CURD操作,只有在需要封装单独的业务逻辑的时候,模型类才是必须被定义的。

模型定义

模型类并非必须定义,只有当存在独立的业务逻辑或者属性的时候才需要定义。

模型类通常需要继承系统的\Think\Model类或其子类,下面是一个Home\Model\UserModel类的定义:

 
   
   
 
  1. namespace Home\Model;

  2. use Think\Model;

  3. class UserModel extends Model {

  4. }

模型类的作用大多数情况是操作数据表的,如果按照系统的规范来命名模型类的话,大多数情况下是可以自动对应数据表。

模型类的命名规则是除去表前缀的数据表名称,采用驼峰法命名,并且首字母大写,然后加上模型层的名称(默认定义是Model),例如:

模型名 约定对应数据表(假设数据库的前缀定义是 think_)
UserModel think_user
UserTypeModel think_user_type

如果你的规则和上面的系统约定不符合,那么需要设置Model类的数据表名称属性,以确保能够找到对应的数据表。

数据表定义

在ThinkPHP的模型里面,有几个关于数据表名称的属性定义:

属性 说明
tablePrefix 定义模型对应数据表的前缀,如果未定义则获取配置文件中的DB_PREFIX参数
tableName 不包含表前缀的数据表名称,一般情况下默认和模型名称相同,只有当你的表名和当前的模型类的名称不同的时候才需要定义。
trueTableName 包含前缀的数据表名称,也就是数据库中的实际表名,该名称无需设置,只有当上面的规则都不适用的情况或者特殊情况下才需要设置。
dbName 定义模型当前对应的数据库名称,只有当你当前的模型类对应的数据库名称和配置文件不同的时候才需要定义。


举个例子来加深理解,例如,在数据库里面有一个think_categories表,而我们定义的模型类名称是CategoryModel,按照系统的约定,这个模型的名称是Category,对应的数据表名称应该是think_category(全部小写),但是现在的数据表名称是think_categories,因此我们就需要设置tableName属性来改变默认的规则(假设我们已经在配置文件里面定义了DB_PREFIX 为 think_)。

 
   
   
 
  1. namespace Home\Model;

  2. use Think\Model;

  3. class CategoryModel extends Model {

  4.    protected $tableName = 'categories';

  5. }

注意这个属性的定义不需要加表的前缀think_

如果我们需要CategoryModel模型对应操作的数据表是 top_category,那么我们只需要设置数据表前缀即可:

 
   
   
 
  1. namespace Home\Model;

  2. use Think\Model;

  3. class CategoryModel extends Model {

  4.    protected $tablePrefix = 'top_';

  5. }

如果你的数据表直接就是category,而没有前缀,则可以设置tablePrefix为空字符串。

 
   
   
 
  1. namespace Home\Model;

  2. use Think\Model;

  3. class CategoryModel extends Model {

  4.    protected $tablePrefix = '';

  5. }

没有表前缀的情况必须设置,否则会获取当前配置文件中的 DB_PREFIX

而对于另外一种特殊情况,我们需要操作的数据表是top_categories,这个时候我们就需要定义 trueTableName 属性

 
   
   
 
  1. namespace Home\Model;

  2. use Think\Model;

  3. class CategoryModel extends Model {

  4.    protected $trueTableName = 'top_categories';

  5. }

注意trueTableName需要完整的表名定义。

除了数据表的定义外,还可以对数据库进行定义(用于操作当前数据库以外的数据表),例如 top.top_categories

 
   
   
 
  1. namespace Home\Model;

  2. use Think\Model;

  3. class CategoryModel extends Model {

  4.    protected $trueTableName = 'top_categories';

  5.    protected $dbName = 'top';

  6. }

系统的规则下,tableName会转换为小写定义,但是trueTableName定义的数据表名称是保持原样。因此,如果你的数据表名称需要区分大小写的情况,那么可以通过设置trueTableName定义来解决。

在ThinkPHP中,可以无需进行任何模型定义。只有在需要封装单独的业务逻辑的时候,模型类才是必须被定义的,因此ThinkPHP在模型上有很多的灵活和方便性,让你无需因为表太多而烦恼。

根据不同的模型定义,我们有几种实例化模型的方法,根据需要采用不同的方式:

直接实例化

可以和实例化其他类库一样实例化模型类,例如:

 
   
   
 
  1. $User = new \Home\Model\UserModel();

  2. $Info = new \Admin\Model\InfoModel();

  3. // 带参数实例化

  4. $New  = new \Home\Model\NewModel('blog','think_',$connection);

模型类通常都是继承系统的\Think\Model类,该类的架构方法有三个参数,分别是:

Model(['模型名'],['数据表前缀'],['数据库连接信息']);

三个参数都是可选的,大多数情况下,我们根本无需传入任何参数即可实例化。

参数 描述
模型名 模型的名称 和数据表前缀一起配合用于自动识别数据表名称
数据表前缀 当前数据表前缀 和模型名一起配合用于自动识别数据表名称
数据库连接信息 当前数据表的数据库连接信息 如果没有则获取配置文件中的

数据表前缀传入空字符串表示取当前配置的表前缀,如果当前数据表没有前缀,则传入null即可。

数据库连接信息参数支持三种格式:

1、字符串定义

字符串定义采用DSN格式定义,格式定义规范为:

 
   
   
 
  1. type://username:passwd@hostname:port/DbName

  2. // 3.2.1以上版本还可以支持字符集设定

  3. type://username:passwd@hostname:port/DbName#charset

例如:

 
   
   
 
  1. new \Home\Model\NewModel('blog','think_','mysql://root:1234@localhost/demo');

2、数组定义

可以传入数组格式的数据库连接信息,例如:

 
   
   
 
  1. $connection = array(

  2.    'db_type'    =>   'mysql',

  3.    'db_host'    =>   '127.0.0.1',

  4.    'db_user'    =>   'root',

  5.    'db_pwd'     =>   '12345',

  6.    'db_port'    =>    3306,

  7.    'db_name'    =>    'demo',

  8. );

  9. new \Home\Model\NewModel('new','think_',$connection);

3.2.1以上版本还可以支持数据编码设定,例如:

 
   
   
 
  1. $connection = array(

  2.    'db_type'    =>   'mysql',

  3.    'db_host'    =>   '127.0.0.1',

  4.    'db_user'    =>   'root',

  5.    'db_pwd'     =>   '12345',

  6.    'db_port'    =>    3306,

  7.    'db_name'    =>    'demo',

  8.    'db_charset' =>    'utf8',

  9. );

  10. new \Home\Model\NewModel('new','think_',$connection);

3.2.3开始还可以支持数据的部署模式和调试模式设定,例如:

 
   
   
 
  1. $connection = array(

  2.    'db_type'    =>   'mysql',

  3.    'db_host'    =>   '192.168.1.2,192.168.1.3',

  4.    'db_user'    =>   'root',

  5.    'db_pwd'     =>   '12345',

  6.    'db_port'    =>    3306,

  7.    'db_name'    =>    'demo',

  8.    'db_charset' =>    'utf8',

  9.    'db_deploy_type'=>    1,

  10.    'db_rw_separate'=>    true,

  11.    'db_debug'    =>    true,

  12. );

  13. // 分布式数据库部署 并且采用读写分离 开启数据库调试模式

  14. new \Home\Model\NewModel('new','think_',$connection);

注意,如果设置了db_debug参数,那么数据库调试模式就不再受APP_DEBUG常量影响。

3、配置定义

我们可以事先在配置文件中定义好数据库连接信息,然后在实例化的时候直接传入配置的名称即可,例如:

 
   
   
 
  1. //数据库配置1

  2. 'DB_CONFIG1' => array(

  3.     'db_type'  => 'mysql',

  4.     'db_user'  => 'root',

  5.     'db_pwd'   => '1234',

  6.     'db_host'  => 'localhost',

  7.     'db_port'  => '3306',

  8.     'db_name'  => 'thinkphp'

  9. ),

  10. //数据库配置2

  11. 'DB_CONFIG2' => 'mysql://root:1234@localhost:3306/thinkphp',

在配置文件中定义数据库连接信息的时候也支持字符串和数组格式,格式和上面实例化传入的参数一样。

然后,我们就可以这样实例化模型类传入连接信息:

 
   
   
 
  1. new \Home\Model\NewModel('new','think_','DB_CONFIG1');

  2. new \Home\Model\BlogModel('blog','think_','DB_CONFIG2');

事实上,当我们实例化的时候没有传入任何的数据库连接信息的时候,系统其实默认会获取配置文件中的相关配置参数,包括:

 
   
   
 
  1. 'DB_TYPE'      =>  '',     // 数据库类型

  2. 'DB_NAME'      =>  '',     // 数据库名

  3. 'DB_USER'      =>  '',     // 用户名

  4. 'DB_PWD'       =>  '',     // 密码

  5. 'DB_PORT'      =>  '',     // 端口

  6. 'DB_PREFIX'    =>  '',     // 数据库表前缀

  7. 'DB_DSN'       =>  '',     // 数据库连接DSN 用于PDO方式

  8. 'DB_CHARSET'   =>  'utf8', // 数据库的编码 默认为utf8

如果应用配置文件中有配置上述数据库连接信息的话,实例化模型将会变得非常简单。

D方法实例化

上面实例化的时候我们需要传入完整的类名,系统提供了一个快捷方法D用于数据模型的实例化操作。

要实例化自定义模型类,可以使用下面的方式:

 
   
   
 
  1. <?php

  2. //实例化模型

  3. $User = D('User');

  4. // 相当于 $User = new \Home\Model\UserModel();

  5. // 执行具体的数据操作

  6. $User->select();

当 \Home\Model\UserModel 类不存在的时候,D函数会尝试实例化公共模块下面的 \Common\Model\UserModel 类。

D方法的参数就是模型的名称,并且和模型类的大小写定义是一致的,例如:

参数 实例化的模型文件(假设当前模块为Home)
User 对应的模型类文件的 \Home\Model\UserModel.class.php
UserType 对应的模型类文件的 \Home\Model\UserTypeModel.class.php


如果在Linux环境下面,一定要注意D方法实例化的时候的模型名称的大小写。

D方法可以自动检测模型类,如果存在自定义的模型类,则实例化自定义模型类,如果不存在,则会实例化系统的\Think\Model基类,同时对于已实例化过的模型,不会重复去实例化。

 
   
   
 
  1. D方法还可以支持跨模块调用,需要使用:

  2. //实例化Admin模块的User模型

  3. D('Admin/User');

  4. //实例化Extend扩展命名空间下的Info模型

  5. D('Extend://Editor/Info');

注意:跨模块实例化模型类的时候 不支持自动加载公共模块的模型类。

M方法实例化模型

D方法实例化模型类的时候通常是实例化某个具体的模型类,如果你仅仅是对数据表进行基本的CURD操作的话,使用M方法实例化的话,由于不需要加载具体的模型类,所以性能会更高。

例如:

 
   
   
 
  1. // 使用M方法实例化

  2. $User = M('User');

  3. // 和用法 $User = new \Think\Model('User'); 等效

  4. // 执行其他的数据操作

  5. $User->select();

M方法也可以支持跨库操作,例如:

 
   
   
 
  1. // 使用M方法实例化 操作db_name数据库的ot_user表

  2. $User = M('db_name.User','ot_');

  3. // 执行其他的数据操作

  4. $User->select();

M方法的参数和\Think\Model类的参数是一样的,也就是说,我们也可以这样实例化:

 
   
   
 
  1. $New  = M('new','think_',$connection);

  2. // 等效于 $New = new \Think\Model('new','think_',$connection);

具体的参数含义可以参考前面的介绍。

M方法实例化的时候,默认情况下是直接实例化系统的\Think\Model类,如果我们希望实例化其他的公共模型类的话,可以使用如下方法:

 
   
   
 
  1. $User = M('\Home\Model\CommonModel:User','think_','db_config');

  2. // 相当于 $User = new \Home\Model\CommonModel('User','think_','db_config');

如果你的模型类有自己的业务逻辑,M方法是无法支持的,就算是你已经定义了具体的模型类,M方法实例化的时候是会直接忽略。

实例化空模型类

如果你仅仅是使用原生SQL查询的话,不需要使用额外的模型类,实例化一个空模型类即可进行操作了,例如:

 
   
   
 
  1. //实例化空模型

  2. $Model = new Model();

  3. //或者使用M快捷方法是等效的

  4. $Model = M();

  5. //进行原生的SQL查询

  6. $Model->query('SELECT * FROM think_user WHERE status = 1');

实例化空模型类后还可以用table方法切换到具体的数据表进行操作

我们在实例化的过程中,经常使用D方法和M方法,这两个方法的区别在于M方法实例化模型无需用户为每个数据表定义模型类,如果D方法没有找到定义的模型类,则会自动调用M方法。

通常每个模型类是操作某个数据表,在大多数情况下,系统会自动获取当前数据表的字段信息。

系统会在模型首次实例化的时候自动获取数据表的字段信息(而且只需要一次,以后会永久缓存字段信息,除非设置不缓存或者删除),如果是调试模式则不会生成字段缓存文件,则表示每次都会重新获取数据表字段信息。

字段缓存保存在Runtime/Data/_fields/ 目录下面,缓存机制是每个模型对应一个字段缓存文件(注意:并非每个数据表对应一个字段缓存文件),命名格式是:

数据库名.模型名(小写).php

例如:

 
   
   
 
  1. demo.user.php    // User模型生成的字段缓存文件

  2. demo.article.php // Article模型生成的字段缓存文件

3.2.3版本开始,字段缓存的文件名调整为

数据库名.数据表前缀+模型名(小写).php

例如:

 
   
   
 
  1. demo.think_user.php    // User模型生成的字段缓存文件

  2. demo.top_article.php // Article模型生成的字段缓存文件

字段缓存包括数据表的字段信息、主键字段和是否自动增长,如果开启字段类型验证的话还包括字段类型信息等等,无论是用M方法还是D方法,或者用原生的实例化模型类一般情况下只要是不开启调试模式都会生成字段缓存(字段缓存可以单独设置关闭)。

可以通过设置DB_FIELDS_CACHE 参数来关闭字段自动缓存,如果在开发的时候经常变动数据库的结构,而不希望进行数据表的字段缓存,可以在项目配置文件中增加如下配置:

 
   
   
 
  1. // 关闭字段缓存

  2. 'DB_FIELDS_CACHE'=>false

注意:调试模式下面由于考虑到数据结构可能会经常变动,所以默认是关闭字段缓存的。

如果需要显式获取当前数据表的字段信息,可以使用模型类的getDbFields方法来获取当前数据对象的全部字段信息,例如:

 
   
   
 
  1. $User   = M('User');

  2. $fields = $User->getDbFields();

如果你在部署模式下面修改了数据表的字段信息,可能需要清空Data/_fields目录下面的缓存文件,让系统重新获取更新的数据表字段信息,否则会发生新增的字段无法写入数据库的问题。

如果不希望依赖字段缓存或者想提高性能,也可以在模型类里面手动定义数据表字段的名称,可以避免IO加载的效率开销,例如:

 
   
   
 
  1. namespace Home\Model;

  2. use Think\Model;

  3. class UserModel extends Model {

  4.    protected $fields = array('id', 'username', 'email', 'age');

  5.    protected $pk     = 'id';

  6. }

pk属性定义当前数据表的主键名,默认值就是id,因此如果是id的话可以无需定义。

3.2.3版本以上,支持定义复合主键,例如:

 
   
   
 
  1. namespace Home\Model;

  2. use Think\Model;

  3. class ScoreModel extends Model {

  4.    protected $fields = array('user_id', 'lession_id','score');

  5.    protected $pk     = array('user_id','lession_id');

  6. }

除了可以设置数据表的字段之外,我们还可以定义字段的类型,用于某些验证环节。例如:

 
   
   
 
  1. namespace Home\Model;

  2. use Think\Model;

  3. class UserModel extends Model {

  4.    protected $fields = array('id', 'username', 'email', 'age',

  5.        '_type'=>array('id'=>'bigint','username'=>'varchar','email'=>'varchar','age'=>'int')

  6.    );

  7. }

ThinkPHP内置了抽象数据库访问层,把不同的数据库操作封装起来,我们只需要使用公共的Db类进行操作,而无需针对不同的数据库写不同的代码和底层实现,Db类会自动调用相应的数据库驱动来处理。目前的数据库包括Mysql、SqlServer、PgSQL、Sqlite、Oracle、Ibase、Mongo,也包括对PDO的支持。

如果应用需要使用数据库,必须配置数据库连接信息,数据库的配置文件有多种定义方式。

一、全局配置定义

常用的配置方式是在应用配置文件或者模块配置文件中添加下面的配置参数:

 
   
   
 
  1. //数据库配置信息

  2. 'DB_TYPE'   => 'mysql', // 数据库类型

  3. 'DB_NAME'   => 'thinkphp', // 数据库名

  4. 'DB_USER'   => 'root', // 用户名

  5. 'DB_PWD'    => '123456', // 密码

  6. 'DB_PORT'   => 3306, // 端口

  7. 'DB_PREFIX' => 'think_', // 数据库表前缀

  8. 'DB_CHARSET'=> 'utf8', // 字符集

  9. 'DB_DEBUG'  =>  TRUE, // 数据库调试模式 开启后可以记录SQL日志 3.2.3新增

数据库的类型由DB_TYPE参数设置。

下面是目前支持的数据库设置:

DB_TYPE设置 支持的数据库类型
mysql或mysqli mysql
pgsql pgsql
sqlite sqlite
mssql 或sqlsrv sqlserver
oracle oracle
ibase ibase
mongo mongo
PDO PDO支持的所有数据库 3.2.3以上版本取消了PDO设置


3.2.3以下版本,如果DB_TYPE使用PDO类型的话,数据库类型则由DB_DSN配置决定。 3.2.3以上版本,DB_DSN无需设置,由系统自动设置。

如果是3.2.3版本的话,由于全部采用PDO方式,所以DB_TYPE需要配置为实际的数据库类型,不再支持设置为PDO,也不再区分mysql和mysqli。

或者采用如下配置

 
   
   
 
  1. 'DB_DSN' => 'mysql://root:123456@localhost:3306/thinkphp#utf8'

使用DB_DSN方式定义可以简化配置参数,DSN参数格式为:

数据库类型://用户名:密码@数据库地址:数据库端口/数据库名#字符集

字符集设置需要3.2.1版本以上有效,字符集如果没有设置的话,默认为utf8。

如果两种配置参数同时存在的话,DB_DSN配置参数优先。

注意:如果要设置分布式数据库,暂时不支持DB_DSN方式配置。

如果采用PDO驱动的话,则必须首先配置DB_TYPE为pdo,然后还需要单独配置其他参数,例如:

 
   
   
 
  1. //PDO连接方式

  2. 'DB_TYPE'   => 'pdo', // 数据库类型

  3. 'DB_USER'   => 'root', // 用户名

  4. 'DB_PWD'    => '', // 密码

  5. 'DB_PREFIX' => 'think_', // 数据库表前缀

  6. 'DB_DSN'    => 'mysql:host=localhost;dbname=thinkphp;charset=utf8'

注意:PDO方式的DB_DSN配置格式有所区别,根据不同的数据库类型设置有所不同,具体可以参考PHP手册。

配置文件定义的数据库连接信息一般是系统默认采用的,因为一般一个应用的数据库访问配置是相同的。该方法系统在连接数据库的时候会自动获取,无需手动连接。

可以对每个模块定义不同的数据库连接信息,如果开启了调试模式的话,还可以在不同的应用状态的配置文件里面定义独立的数据库配置信息。

二、模型类定义

如果在某个模型类里面定义了connection属性的话,则实例化该自定义模型的时候会采用定义的数据库连接信息,而不是配置文件中设置的默认连接信息,通常用于某些数据表位于当前数据库连接之外的其它数据库,例如:

 
   
   
 
  1. //在模型里单独设置数据库连接信息

  2. namespace Home\Model;

  3. use Think\Model;

  4. class UserModel extends Model{

  5.    protected $connection = array(

  6.        'db_type'  => 'mysql',

  7.        'db_user'  => 'root',

  8.        'db_pwd'   => '1234',

  9.        'db_host'  => 'localhost',

  10.        'db_port'  => '3306',

  11.        'db_name'  => 'thinkphp',

  12.        'db_charset' =>    'utf8',

  13.    );

  14. }

也可以采用字符串方式定义,例如:

 
   
   
 
  1. //在模型里单独设置数据库连接信息

  2. namespace Home\Model;

  3. use Think\Model;

  4. class UserModel extends Model{

  5.    //或者使用字符串定义

  6.    protected $connection = 'mysql://root:1234@localhost:3306/thinkphp#utf8';

  7. }

如果我们已经在配置文件中配置了额外的数据库连接信息,例如:

 
   
   
 
  1. //数据库配置1

  2. 'DB_CONFIG1' => array(

  3.    'db_type'  => 'mysql',

  4.    'db_user'  => 'root',

  5.    'db_pwd'   => '1234',

  6.    'db_host'  => 'localhost',

  7.    'db_port'  => '3306',

  8.    'db_name'  => 'thinkphp',

  9.    'db_charset'=>    'utf8',

  10. ),

  11. //数据库配置2

  12. 'DB_CONFIG2' => 'mysql://root:1234@localhost:3306/thinkphp#utf8';

那么,我们可以把模型类的属性定义改为:

 
   
   
 
  1. //在模型里单独设置数据库连接信息

  2. namespace Home\Model;

  3. use Think\Model;

  4. class UserModel extends Model{

  5.    //调用配置文件中的数据库配置1

  6.    protected $connection = 'DB_CONFIG1';

  7. }

 
   
   
 
  1. //在模型里单独设置数据库连接信息

  2. namespace Home\Model;

  3. use Think\Model;

  4. class InfoModel extends Model{

  5.    //调用配置文件中的数据库配置1

  6.    protected $connection = 'DB_CONFIG2';

  7. }

三、实例化定义

除了在模型定义的时候指定数据库连接信息外,我们还可以在实例化的时候指定数据库连接信息,例如: 如果采用的是M方法实例化模型的话,也可以支持传入不同的数据库连接信息,例如:

 
   
   
 
  1. $User = M('User','other_','mysql://root:1234@localhost/demo#utf8');

表示实例化User模型,连接的是demo数据库的other_user表,采用的连接信息是第三个参数配置的。如果我们在项目配置文件中已经配置了DB_CONFIG2的话,也可以采用:

 
   
   
 
  1. $User = M('User','other_','DB_CONFIG2');

需要注意的是,ThinkPHP的数据库连接是惰性的,所以并不是在实例化的时候就连接数据库,而是在有实际的数据操作的时候才会去连接数据库(额外的情况是,在系统第一次实例化模型的时候,会自动连接数据库获取相关模型类对应的数据表的字段信息)。

除了在预先定义数据库连接和实例化的时候指定数据库连接外,我们还可以在模型操作过程中动态的切换数据库,支持切换到相同和不同的数据库类型。用法很简单, 只需要调用Model类的db方法,用法:

Model->db("数据库编号","数据库配置");

数据库编号用数字格式,对于已经调用过的数据库连接,是不需要再传入数据库连接信息的,系统会自动记录。对于默认的数据库连接,内部的数据库编号是0,因此为了避免冲突,请不要再次定义数据库编号为0的数据库配置。

数据库配置的定义方式和模型定义connection属性一样,支持数组、字符串以及调用配置参数三种格式。

Db方法调用后返回当前的模型实例,直接可以继续进行模型的其他操作,所以该方法可以在查询的过程中动态切换,例如:

 
   
   
 
  1. $this->db(1,"mysql://root:123456@localhost:3306/test")->query("查询SQL");

该方法添加了一个编号为1的数据库连接,并自动切换到当前的数据库连接。

当第二次切换到相同的数据库的时候,就不需要传入数据库连接信息了,可以直接使用:

 
   
   
 
  1. $this->db(1)->query("查询SQL");

如果需要切换到默认的数据库连接,只需要调用:

 
   
   
 
  1. $this->db(0);

如果我们已经在项目配置中定义了其他的数据库连接信息,例如:

 
   
   
 
  1. //数据库配置1

  2. 'DB_CONFIG1' = array(

  3.    'db_type'  => 'mysql',

  4.    'db_user'  => 'root',

  5.    'db_pwd'   => '1234',

  6.    'db_host'  => 'localhost',

  7.    'db_port'  => '3306',

  8.    'db_name'  => 'thinkphp'

  9. ),

  10. //数据库配置2

  11. 'DB_CONFIG2' => 'mysql://root:1234@localhost:3306/thinkphp';

我们就可以直接在db方法中调用配置进行连接了:

 
   
   
 
  1. $this->db(1,"DB_CONFIG1")->query("查询SQL");

  2. $this->db(2,"DB_CONFIG2")->query("查询SQL");

如果切换数据库之后,数据表和当前不一致的话,可以使用table方法指定要操作的数据表:

 
   
   
 
  1. $this->db(1)->table("top_user")->find();

ThinkPHP内置了分布式数据库的支持,包括主从式数据库的读写分离,但是分布式数据库必须是相同的数据库类型。

配置DB_DEPLOY_TYPE 为1 可以采用分布式数据库支持。如果采用分布式数据库,定义数据库配置信息的方式如下:

 
   
   
 
  1. //分布式数据库配置定义

  2. 'DB_DEPLOY_TYPE'=> 1, // 设置分布式数据库支持

  3. 'DB_TYPE'       => 'mysql', //分布式数据库类型必须相同

  4. 'DB_HOST'       => '192.168.0.1,192.168.0.2',

  5. 'DB_NAME'       => 'thinkphp', //如果相同可以不用定义多个

  6. 'DB_USER'       => 'user1,user2',

  7. 'DB_PWD'        => 'pwd1,pwd2',

  8. 'DB_PORT'       => '3306',

  9. 'DB_PREFIX'     => 'think_',

连接的数据库个数取决于DB_HOST定义的数量,所以即使是两个相同的IP也需要重复定义,但是其他的参数如果存在相同的可以不用重复定义,例如:

 
   
   
 
  1. 'DB_PORT'=>'3306,3306'

 
   
   
 
  1. 'DB_PORT'=>'3306'

等效。

 
   
   
 
  1. 'DB_USER'=>'user1',

  2. 'DB_PWD'=>'pwd1',

 
   
   
 
  1. 'DB_USER'=>'user1,user1',

  2. 'DB_PWD'=>'pwd1,pwd1',

等效。

还可以设置分布式数据库的读写是否分离,默认的情况下读写不分离,也就是每台服务器都可以进行读写操作,对于主从式数据库而言,需要设置读写分离,通过下面的设置就可以:

 
   
   
 
  1. 'DB_RW_SEPARATE'=>true,

在读写分离的情况下,默认第一个数据库配置是主服务器的配置信息,负责写入数据,如果设置了DB_MASTER_NUM参数,则可以支持多个主服务器写入。其它的都是从数据库的配置信息,负责读取数据,数量不限制。每次连接从服务器并且进行读取操作的时候,系统会随机进行在从服务器中选择。

还可以设置DB_SLAVE_NO 指定某个服务器进行读操作。

3.2.3版本开始,如果从数据库连接错误,会自动切换到主数据库连接。

调用模型的CURD操作的话,系统会自动判断当前执行的方法的读操作还是写操作,如果你用的是原生SQL,那么需要注意系统的默认规则:写操作必须用模型的execute方法,读操作必须用模型的query方法,否则会发生主从读写错乱的情况。

注意:主从数据库的数据同步工作不在框架实现,需要数据库考虑自身的同步或者复制机制。

版权声明:本站内容全部来自于腾讯微信公众号,属第三方自助推荐收录。《Thinphp模型》的版权归原作者「ArchieCMS」所有,文章言论观点不代表Lambda在线的观点, Lambda在线不承担任何法律责任。如需删除可联系QQ:516101458

文章来源: 阅读原文

相关阅读

关注ArchieCMS微信公众号

ArchieCMS微信公众号:ArchieCMS

ArchieCMS

手机扫描上方二维码即可关注ArchieCMS微信公众号

ArchieCMS最新文章

精品公众号随机推荐