ThinkPHP 数据库操作(五) : 存储过程、数据集、分布式数据库

存储过程

5.0支持存储过程,如果我们定义了一个数据库存储过程 sp_query ,可以使用下面的方式调用:

$result = Db::query('call sp_query(8)');

返回的是一个二维数组,也可以使用参数绑定,例如:

$result = Db::query('call sp_query(?)',[8]);
// 或者命名绑定
$result = Db::query('call sp_query(:id)',['id'=>8]);

 

数据集

数据库的查询结果也就是数据集,默认的配置下,数据集的类型是一个二维数组,我们可以配置成数据集类,就可以支持对数据集更多的对象化操作,需要使用数据集类功能,可以配置数据库的resultset_type 参数如下:

return [
    // 数据库类型
    'type' => 'mysql',
    // 数据库连接DSN配置
    'dsn' => '',
    // 服务器地址
    'hostname' => '127.0.0.1',
    // 数据库名
    'database' => 'thinkphp',
    // 数据库用户名
    'username' => 'root',
    // 数据库密码
    'password' => '',
    // 数据库连接端口
    'hostport' => '',
    // 数据库连接参数
    'params' => [],
    // 数据库编码默认采用utf8
    'charset' => 'utf8',
    // 数据库表前缀
    'prefix' => 'think_',
    // 数据集返回类型
    'resultset_type' => 'collection',
];

返回的数据集对象是 think\Collection ,提供了和数组无差别用法,并且另外封装了一些额外的方法。可以直接使用数组的方式操作数据集对象,例如:

// 获取数据集
$users = Db::name('user')->select();
// 直接操作第一个元素
$item = $users[0];
// 获取数据集记录数
$count = count($users);
// 遍历数据集
foreach($users as $user){
    echo $user['name'];
    echo $user['id'];
}

需要注意的是,如果要判断数据集是否为空,不能直接使用 empty 判断,而必须使用数据集对象的isEmpty 方法判断,例如:

$users = Db::name('user')->select();
if($users->isEmpty()){
    echo '数据集为空';
}

Collection 类包含了下列主要方法:

如果只是个别数据的查询需要返回数据集对象,则可以使用

Db::name('user')
    ->fetchClass('\think\Collection')
    ->select();

 

分布式数据库

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

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

//分布式数据库配置定义
return [
    // 启用分布式数据库
    'deploy' => 1,
    // 数据库类型
    'type' => 'mysql',
    // 服务器地址
    'hostname' => '192.168.1.1,192.168.1.2',
    // 数据库名
    'database' => 'demo',
    // 数据库用户名
    'username' => 'root',
    // 数据库密码
    'password' => '',
    // 数据库连接端口
    'hostport' => '',
]

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

'hostport'=>'3306,3306'

'hostport'=>'3306'

等效。

'username'=>'user1',
'password'=>'pwd1',

'username'=>'user1,user1',
'password'=>'pwd1,pwd1',

等效。

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

'rw_separate' => true,

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

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

  如果从数据库连接错误,会自动切换到主数据库连接。

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

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

posted @ 2019-03-29 16:46  没事儿写个bug  阅读(1875)  评论(0编辑  收藏  举报