一、数据库相关的操作
1. 数据库配置
(1) 默认的全局数据库配置
在appliation/database.php文件中设置全局的数据库配置信息,数据库基本定义信息如下:
return [// 数据库类型'type' => 'mysql',// 服务器地址'hostname' => '127.0.0.1',// 数据库名'database' => '',// 用户名'username' => 'root',// 密码'password' => '',// 端口'hostport' => '',// 连接dsn'dsn' => '',// 数据库连接参数'params' => [],// 数据库编码默认采用utf8'charset' => 'utf8',// 数据库表前缀'prefix' => '',// 数据库调试模式'debug' => true,// 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)'deploy' => 0,// 数据库读写是否分离 主从式有效'rw_separate' => false,// 读写分离后 主服务器数量'master_num' => 1,// 指定从服务器序号'slave_no' => '',// 是否严格检查字段是否存在'fields_strict' => true,// 数据集返回类型'resultset_type' => 'array',// 自动写入时间戳字段'auto_timestamp' => false,// 时间字段取出后的默认时间格式'datetime_format' => 'Y-m-d H:i:s',// 是否需要进行SQL性能分析'sql_explain' => false,
];
(2)可自定义单个模块的数据库连接
在模块文件夹下创建database.php,模块的数据库配置文件中只需要配置和全局数据库配置文件差异的部分,相同的不需要重复配置。
2. 原生查询—-CRUD
设置好数据库连接信息后,就可以直接进行原生的SQL查询操作了,包括 query 和 execute 两个方法,实现数据表的CURD操作
在数据库中已存在表tb_admin数据表
(1) 创建—-C(Create)
//插入记录
$res=Db::execute("INSERT INTO tb_admin(`name`,pwd) VALUES('zhang',MD5('123456'))"); return dump($res);
执行的SQL语句为:
INSERT INTO tb_admin(`name`,pwd) VALUES('zhang',MD5('123456'))
(2) 更新—-U(Update)
// 更新记录
$result = Db::execute('update tb_admin set name = "lisi" where id = 6');
dump($result);
执行的SQL语句为:
INSERT INTO tb_admin(`name`,pwd) VALUES('zhang',MD5('123456'))
(3) 读取—-R(Read)
//读取记录
$result = Db::query('select * from tb_admin where id = 6');
dump($result);
执行的SQL语句为:
select * from tb_admin where id = 6
(4) 删除—-D(Delete)
// 删除数据
$result = Db::execute('delete from tb_admin where id = 9 ');
dump($result);
执行的SQL语句为:
delete from tb_admin where id = 9
(5)其他操作
原则上,读操作都使用 query 方法,写操作使用 execute 方法。
query 方法用于查询,默认情况下返回的是数据集(二维数组), execute 方法的返回值是影响的行数。
// 显示数据库列表
$result = Db::query('show tables from myshop');
dump($result);
// 清空数据表
$result = Db::execute('TRUNCATE table think_data');
dump($result);
(5) 切换数据库
方法一:
$result = Db::connect([
// 数据库类型'type' => 'mysql',
// 服务器地址'hostname' => '127.0.0.1',
// 数据库名'database' => 'myshop',
// 数据库用户名'username' => 'root',
// 数据库密码'password' => '123456',
// 数据库连接端口'hostport' => '3306',
// 数据库连接参数'params' => [],
// 数据库编码默认采用utf8'charset' => 'utf8',
// 数据库表前缀'prefix' => 'tb_',
])->query('select * from tb_admin');
dump($result);
方法二:
采用字符串方式定义(字符串方式无法定义数据表前缀和连接参数)
$result = Db::connect('mysql://root:123456@127.0.0.1:3306/myshop#utf8'
)->query('select * from tb_admin where id = 6');
dump($result);
方法三:
定义多个数据库配置:
为了简化代码,通常的做法是事先在配置文件中定义好多个数据库的连接配置,在应用配置文件 application/config.php 中添加配置如下:
// 数据库配置1
'db1' => [
// 数据库类型'type' => 'mysql',
// 服务器地址'hostname' => '127.0.0.1',
// 数据库名'database' => 'myshop',
// 数据库用户名'username' => 'root',
// 数据库密码'password' => '123456',
// 数据库连接端口'hostport' => '3306',
// 数据库连接参数'params' => [],
// 数据库编码默认采用utf8'charset' => 'utf8',
// 数据库表前缀'prefix' => 'tb_',
],
// 数据库配置2
'db2' => [
// 数据库类型'type' => 'mysql',
// 服务器地址'hostname' => '127.0.0.1',
// 数据库名'database' => 'test',
// 数据库用户名'username' => 'root',
// 数据库密码'password' => '123456',
// 数据库连接端口'hostport' => '3306',
// 数据库连接参数'params' => [],
// 数据库编码默认采用utf8'charset' => 'utf8',
// 数据库表前缀'prefix' => 'test_',
],
就可以直接在 connect 方法中传入配置参数进行切换数据库连接,例如:
$result = Db::connect('db1')->query('select * from tb_admin where id = 1');
$result = Db::connect('db2')->query('select * from think_data where id = 1');
dump($result);
connect 方法中的配置参数需要完整定义,并且仅仅对当此查询有效,下次调用 Db 类的时候还是使用默认的数据库连接。如果需要多次切换数据库查询,可以使用:
$db1 = Db::connect('db1');
$db2 = Db::connect('db2');
$db1->query('select * from tb_admin where id = 1');
$db2->query('select * from tb_admin where id = 1');
(6)参数绑定
实际开发中,可能某些数据使用的是外部传入的变量,为了让查询操作更加安全,我们建议使用参数绑定机制,例如上面的操作可以改为:
方法一:
使用?占位符
$res=Db::execute("INSERT INTO tb_admin(`name`,pwd) VALUES(?,?)",["wu","md5('123456')"]); return dump($res);
方法二:
使用命名占位符
$res = Db::execute('update tb_admin set name =:name where id= :id',['name'=>'mang','id'=>'10']);
dump($res);
3. 查询构造器
(1)使用table()
//插入记录
$res=Db::table("tb_admin")->insert(['name'=>'nihao','pwd'=>md5('123456')]);dump($res);
//更新记录$res=Db::table("tb_admin")->where('id',12)->update(['name'=>'hello']);dump($res);
//查询数据$res=Db::table("tb_admin")->where('id',12)->select();dump($res);
//删除数据$res=Db::table("tb_admin")->where('id',13)->delete();dump($res);
(2)使用name()—-可简化代码,不会因为数据库的表前缀的变化而改变CURD代码
//插入记录
$res=Db::name("admin")->insert(['name'=>'hhh','pwd'=>md5('123456')]);dump($res);
//更新记录$res=Db::name("admin")->where('id',15)->update(['name'=>'haha']);dump($res);
//查询数据$res=Db::name("admin")->where('id',12)->select();dump($res);
//删除数据$res=Db::name("admin")->where('id',16)->delete();dump($res);
注:使用name可以省略表的前缀名
(3)使用助手函数db(),进行代码简化
$db = db("admin");
//插入记录
$res=$db ->insert(['name'=>'daha','pwd'=>md5('123456')]);
dump($res);
//更新记录
$res=$db->where("id",16)->update(['name'=>'xiaozi']); dump($res);
//查询数据
$res=$db->where('id',17)->select();
dump($res);
//删除数据
$res=$db->where('id',18)->delete();
dump($res);
注:db 助手函数默认会每次重新连接数据库,因此应当尽量避免多次调用。
4. 链式操作—进行复杂的数据库查询操作
链式操作不区分先后顺序,只要在查询方法(select方法)之前调用即可:
常用的链式操作方法如下:
(1) 举例:
// 查询十个满足条件的数据 并按照id倒序排列
$list = Db::name('admin')->field('id,name')->order('id', 'desc')->limit(10)->select();
dump($list);
(2) find()与select() 的区别
find(【主键】)——-查询一条记录,默认取的是查询结果的第一行,返回的是一维数组,若想查结果集中的具体的某一行,可在find() 中添加主键值进行查询,没有满足条件的话则默认返回 null (也支持设置是否抛出异常)。
$res=Db::name('admin')->field('id,name')->order('id','asc')->find(3);
dump($res);
select()—–查询所有满足条件的记录,返回二维数组。
二、查询语言
1. 查询表达式
相关的可支持的查询表达式如下:
表达式不区分大小写
(1)使用表达式
表达式查询的时候,where方法的参数依次为:
where( 字段名,条件表达式,查询值 )
$result = Db::name('admin')->where('id', '>=', 6)->limit(10)->select();
dump($result);
(2)原生的SQL语句表达式
where方法的参数依次为:
where( 字段名,’exp’,表达式及值)
例如:
$result = Db::name('admin')->where('id', 'exp','>= 3')->limit(10)->select();
dump($result)
(3)使用多个字段进行查询
$result = Db::name('admin')// id 在 1到3之间的->where('id', 'between', [4, 8])// name 中包含think->where('name', 'like', '%h%')->select();
dump($result);
2、批量查询—-一个方法,多个查询条件混合查询
(1)一般批量查询
$result = Db::name('admin') ->where(['id'=>['between','2,6'],'name'=>['like','%h%'],])->select();dump($result);
(2)使用OR和AND进行混合查询
$result = Db::name('data')
// name 中包含think->where('name', 'like', '%h%')->where('id', ['in', [1, 2, 3]],['between', '5,8'],'or')->limit(10); dump($result);
(3) 使用批量查询
$result = Db::name('admin')->where(['id' => [['in', [1, 2, 3]], ['between', '5,8'], 'or'],'name' => ['like', '%h%'],])->limit(10)->select();
dump($result);
3、快捷查询——-多个字段需要使用相同的查询条件
(1)&方式查询
$result = Db::name('admin')->where('id&status', '>', 0)->limit(10)->select();
dump($result);
(2)|方式查询
$result = Db::name('admin')->where('id|status', '>', 0)->limit(10)->select();
dump($result);
4、获取数值—–value()获取某一行的某个数值 使用value(参数)方法,参数为查询表的字段名
$name = Db::name('admin')->where('id','>', 8)->value('name');
dump($name);
注:不需要写select()方法
5、获取列数值—-column()
(1)一般获取用法
$list=Db::name('admin')->where('id','>',4)->column('name');
dump($list);
**注:不需要写select()方法
运行结果如下图:**
(2)以ID为索引的列数据
$list = Db::name('admin')->where('id','>', 6)->column('name', 'id');
dump($list);
(3)以主键为索引的列数据
$list = Db::name('admin')->where('id','>',6)->column('*', 'id');
dump($list);
6、聚合查询—–不需要select()
举例说明:
$count = Db::name('admin')->where('id','>', 1)->count();
dump($count);
7、字符串查询
$result = Db::name('admin')->where('id > :id AND name IS NOT NULL', ['id' => 10])->select();
dump($result);
执行的sql语句是:
SELECT * FROM `tb_admin` WHERE ( id > '10' AND name IS NOT NULL )
8、时间(日期)查询——whereTime()
whereTime()三个字段,第二个可省:
// 查询创建时间大于2016-1-1的数据$result = Db::name('data')->whereTime('create_time', '>', '2016-1-1')->select();dump($result);
// 查询本周添加的数据$result = Db::name('data')->whereTime('create_time', '>', 'this week')->select();dump($result);
// 查询最近两天添加的数据$result = Db::name('data')->whereTime('create_time', '>', '-2 days')->select();dump($result);
// 查询创建时间在2016-1-1~2016-7-1的数据$result = Db::name('data')->whereTime('create_time', 'between', ['2016-1-1', '2016-7-1'])->select();dump($result);
9、分块查询—– 查询大量数据,chunk(处理条数,回调函数{})
可减小内存开销,可以把1万条记录分成 100 次处理,每次处理 100 条记录,代码示例如下:
Db::name('admin')->where('id', '>', 0)->chunk(30, function ($list) {
// 处理30条记录foreach($list as $data){echo "<pre>";print_r($data)."<br>";echo "</pre>";}});