随心的博客

好记性不如个烂笔头,随心记录!

返回顶部

TP6中数据库操作

TP6中数据库操作

要使用Db类必须使用门面方式(think\facade\Db)调用

use think\facade\Db;

一、数据库连接配置

配置文件位于,config/database.php

或者开发环境 位于根目录下的 .env 文件

APP_DEBUG = true
[APP]
DEFAULT_TIMEZONE = Asia/Shanghai
[DATABASE]
TYPE = mysql  //数据库类型  
HOSTNAME = 127.0.0.1 //连接地址
DATABASE = test  //数据库名称
USERNAME = username  //数据库用户名
PASSWORD = password  //数据库密码
HOSTPORT = 3306  //端口
CHARSET = utf8  //字符集
DEBUG = true   //是否开启debug
[LANG]
default_lang = zh-cn
动态配置数据库连接查询

\think\facade\Db::connect('demo')->table('user')->find();
数据模型中定义connection属性

protected $connection = 'demo';

 

ThinkPHP的数据库连接是惰性的,只有实际的数据操作的时候才会去连接数据库。

二、数据库分布式支持

如果需要支持分布式数据库,包括读写分离,需要设置配置参数 deploy 的值为 1

// 启用分布式数据库
'deploy'    =>  1,
'hostname'  => '192.168.1.1,192.168.1.2', //默认情况下第一个地址就是主服务器
// 数据库用户名
'username' => 'root,slave,slave',
// 数据库密码
'password' => '123456',
关于 hostname,username,password,hostport,database,dsn,charset 要么值相同就配置一个,不然就分别设置

建议使用数组定义参数,例如:

'hostname' =>[ '192.168.1.1','192.168.1.2','192.168.1.3'],
'password' => ['123456','abc,def','hello']

三、数据库支持读写分离

开启读写分类配置:

'rw_separate' => true,
默认第一个是主数据库,负责写入数据。如果设置 master_num ,则可以支持多个主服务器写入。

如果用原生SQL,写操作必须用 execute 方法,读操作必须用 query方法

刚写入数据之后,从库数据还没来得及同步完成,你可以使用 master() 进行主库查询

Db::name('user')->master(true)->find(1);
也可以开启:当我们对某个数据表进行了写操作,那么当前请求的后续所有对该表的查询都会使用主库读取

'read_master' => true,

 

四、链式操作

查询单个数据
Db::table('think_user')->where('id', 1)->find();
查询为空返回空数组
Db::table('think_user')->where('id', 1)->findOrEmpty();
说明:
如果没有任何的查询条件,也没有调用order方法的话 ,find查询不会返回任何结果。

查询结果集:

Db::table('think_user')->where('status', 1)->select();

 select 方法查询结果是一个数据集对象,如果需要转换为数组可以使用

Db::table('think_user')->where('status', 1)->select()->toArray();

 查询一个字段

Db::table('think_user')->where('id', 1)->value('name');

 查询一列

// 返回数组
Db::table('think_user')->where('status',1)->column('name');
// 指定id字段的值作为索引
Db::table('think_user')->where('status',1)->column('name', 'id');

 添加数据:

$data = ['foo' => 'bar', 'bar' => 'foo'];
Db::name('user')->save($data);
或
Db::name('user')->insert($data);

 使用save方法时,数据中有ID则为更新,没有ID则为新增

insert 方法添加数据成功返回添加成功的条数,通常情况返回 1
 
如果不希望因为存在数据表中没有的字段而抛出异常,可以使用以下方法

Db::name('user')->strict(false)->insert($data);

 添加后返回主键

$userId = Db::name('user')->strict(false)->insertGetId($data);

 更新数据:

Db::name('user')->save(['id' => 1, 'name' => 'thinkphp']);
或
Db::name('user')->where('id', 1)->update(['name' => 'thinkphp']);

 支持表达式更新

Db::name('user')->where('id',1)->exp('name','UPPER(name)')->update();
或使用raw
Db::name('user')->where('id', 1)->update([
        'name'    =>    Db::raw('UPPER(name)'),
        'score'    =>    Db::raw('score-3'),
        'read_time'    =>    Db::raw('read_time+1')
    ]);

 自增自减

// score 字段加 1
Db::table('think_user')->where('id', 1)->inc('score')->update();
// score 字段加 5
Db::table('think_user')->where('id', 1)->inc('score', 5)->update();
// score 字段减 1
Db::table('think_user')->where('id', 1)->dec('score')->update();
// score 字段减 5
Db::table('think_user')->where('id', 1)->dec('score', 5)->update();
删除数据:
// 根据主键删除
Db::table('think_user')->delete(1);
Db::table('think_user')->delete([1,2,3]);

// 条件删除    
Db::table('think_user')->where('id',1)->delete();
Db::table('think_user')->where('id','<',10)->delete();

没有任何条件调用delete会返回错误。如果确实需要删除所有数据,可以使用

// 无条件删除所有数据
Db::name('user')->delete(true);

 查询表达式:

 格式如下:

where('字段名','查询表达式','查询条件');
// = 等于
Db::name('user')->where('id','=',100)->select();    
//<> 不等于
Db::name('user')->where('id','<>',100)->select();
//>    大于
Db::name('user')->where('id','>',100)->select();    
//>=    大于等于    
Db::name('user')->where('id','>=',100)->select();
//<    小于
Db::name('user')->where('id', '<', 100)->select();    
<=    小于等于
Db::name('user')->where('id', '<=', 100)->select();
//[NOT] LIKE 模糊查询
Db::name('user')->where('name', 'like', 'thinkphp%')->select();
//[NOT] BETWEEN    (不在)区间查询    
Db::name('user')->where('id','between','1,8')->select();
//[NOT] IN    (不在)IN 查询
Db::name('user')->where('id','in','1,5,8')->select();
或
Db::name('user')->where('id','in',[1,5,8])->select();
//[NOT] NULL :
Db::name('user')->where('name', null)->where('email','null')
->where('name','not null')->select();

 

 链式操作示例:

Db::table('think_user')
    ->where('status',1)
    ->order('create_time')
    ->limit(10)
    ->select();
链式where条件:

//1、表达式条件
Db::table('think_user')->where('id','>',1)->where('name','thinkphp')->select(); 

//2、数组条件
Db::table('think_user')->where(['name'=>'thinkphp','status'=>1])->select(); 
//3、字符串条件
Db::table('think_user')->whereRaw('type=1 AND status=1')->select(); 
或需要传入变量,配合预处理机制,确保更加安全
Db::table('think_user')
->whereRaw("id=:id and username=:name", ['id' => 1 , 'name' => 'thinkphp'])
->select();
链式table操作

Db::field('user.name,role.title')
->table([
    'think_user'=>'user',
    'think_role'=>'role'
])
->limit(10)->select();
链式alias操作,设置表的别名

Db::table('think_user')
->alias('a')
->join('think_dept b ','b.user_id= a.id')
->select();
field操作

Db::table('user')->field('id,title,content')->select();
或使用别名
Db::table('user')->field('id,nickname as name')->select();
或使用SQL函数
Db::table('user')->fieldRaw('id,SUM(score)')->select();
strict操作

提交了非法字段会抛出异常,可以在配置中关闭严格字段检查

'fields_strict'    =>    false,
也可以临时关闭

// 关闭字段严格检查
Db::name('user')->strict(false)->insert($data);
limit操作

//获取满足要求的10个用户
Db::table('user')->where('status',1)->field('id,name')->limit(10)->select();
//limit方法也可以用于写操作,例如更新满足要求的3条数据:
Db::table('user')->where('score',100)->limit(3)->update(['level'=>'A']);

//分页查询,查询从第20行开始的10条数据
Db::table('article')->limit(20,10)->select();
page操作

// 查询第一页数据
Db::table('article')->page(1,10)->select(); 
// 查询第二页数据
Db::table('article')->page(2,10)->select(); 
order操作

//没有指定排序规则,默认 asc
Db::table('user')->where('status', 1)->order('id')->select();
//指定排序规则
Db::table('user')->where('status', 1)->order('id', 'desc')->select();
group操作

通常用于结合合计函数,根据一个或多个列对结果集进行分组。

Db::table('user')->field('user_id,username,max(score)')
    ->group('user_id')->select();
对多个字段进行分组
Db::table('user')->field('user_id,test_time,username,max(score)')
    ->group('user_id,test_time')->select();
having操作

Db::table('score')
    ->field('username,max(score)')->group('user_id')
    ->having('count(test_time)>3')->select(); 
join操作

INNER JOIN: 等同于 JOIN(默认的JOIN类型),如果表中有至少一个匹配,则返回行
LEFT JOIN: 即使右表中没有匹配,也从左表返回所有的行
RIGHT JOIN: 即使左表中没有匹配,也从右表返回所有的行
FULL JOIN: 只要其中一个表中存在匹配,就返回行
//join 方式
Db::table('think_artist')
->alias('a')
->join('work w','a.id = w.artist_id')
->join('card c','a.card_id = c.id')
->select();
//left join 方式
Db::table('think_user')
->alias('a')
->leftJoin('word w','a.id = w.artist_id')
->select();

 

五、聚合查询

count:Db::table('think_user')->count();
max:Db::table('think_user')->max('score');
min:Db::table('think_user')->min('score');
avg: Db::table('think_user')->avg('score');
sum: Db::table('think_user')->sum('score');

六、分页查询

 控制器代码:

// 查询状态为1的用户数据 并且每页显示10条数据
$list = Db::name('user')->where('status',1)->order('id', 'desc')->paginate(10);
// 获取分页显示
$page = $list->render();
return view('index', ['list' => $list, 'page' => $page]);

 

 HTML代码:

<div>
<ul>
{volist name='list' id='user'}
    <li> {$user.nickname}</li>
{/volist}
</ul>
</div>
{$page|raw}
获取总数据

// 获取总记录数
$count = $list->total();
分页后数据处理

$list = Db::name('user')->where('status',1)->order('id', 'desc')
->paginate()->each(function($item, $key){
    $item['nickname'] = 'think';
    return $item;
});
模型中分页数据处理,无需return

$list = User::where('status',1)->order('id', 'desc')->paginate()->each(function($item, $key){
    $item->nickname = 'think';
});
分页参数:

$list = Db::name('user')->where('status',1)->paginate([
    'list_rows'=> 20,
    'query'    => $data
]);

七、时间查询 whereTime

// 大于某个时间
Db::name('user')->whereTime('birthday', '>=', '1970-10-1')->select();
// 小于某个时间
Db::name('user')->whereTime('birthday', '<', '2000-10-1')->select();
// 时间区间查询
Db::name('user')->whereTime('birthday', 'between', ['1970-10-1', '2000-10-1'])
    ->select();
// 不在某个时间区间
Db::name('user')->whereTime('birthday', 'not between', ['1970-10-1', '2000-10-1'])
    ->select();

八、原生查询

V6.0.3+版本开始,原生查询仅支持Db类操作

query方法

Db::query("select * from think_user where status=:id", ['id' => 1]);
//从主库读取
Db::query("select * from think_user where status=:id", ['id' => 1], true);
execute方法

Db::execute("update think_user set name='thinkphp' where status=1");
参数绑定

//问号占位符绑定
Db::query("select * from think_user where id=? AND status=?", [8, 1]);
// 命名绑定
Db::execute("update think_user set name=:name where status=:status",
 ['name' => 'thinkphp', 'status' => 1]);
 //注意不支持对表名使用参数绑定

九:事务操作

使用事务处理的话,需要数据库引擎支持事务处理。比如 MySQL 的 MyISAM 不支持事务处理,需要使用 InnoDB 引擎。

最简单的事务闭包操作:

Db::transaction(function () {
    Db::table('think_user')->find(1);
    Db::table('think_user')->delete(1);
});
手动运行事务:

// 启动事务
Db::startTrans();
try {
    Db::table('think_user')->find(1);
    Db::table('think_user')->delete(1);
    // 提交事务
    Db::commit();
} catch (\Exception $e) {
    // 回滚事务
    Db::rollback();
}

十:存储过程

//数据访问层调用存储过程
$resultSet = Db::query('call procedure_name');
foreach ($resultSet as $result) {

}

//存储过程可以支持输入和输出参数,以及进行参数绑定操作。
$resultSet = Db::query('call procedure_name(:in_param1,:in_param2,:out_param)', [
    'in_param1' => $param1,
    'in_param2' => [$param2, PDO::PARAM_INT],
    'out_param' => [$outParam, PDO::PARAM_STR | PDO::PARAM_INPUT_OUTPUT, 4000],
]);

 

数据集:

// 获取数据集
$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 '数据集为空';
}

 

 

 

 

 

posted @ 2021-11-04 17:06  yangphp  阅读(4464)  评论(0编辑  收藏  举报