数据库原生查询与查询构造器课后小结

原创 2018-11-27 10:51:53 326
摘要:一、数据库操作入口类Db的作用1.think\Db.php2.仅仅做为数据库操作的入口3.底层是通过一个__callStatic()方法来实现各种查询操作的4.仅在需要操作数据库的时候才会真正连接数据库,是真正的惰性连接二、tp51数据库操作的三大核心组件及其功1. Connection: 连接器类, think\db\Connection2. Query: 查询器类, think\db\Quer

一、数据库操作入口类Db的作用

1.think\Db.php

2.仅仅做为数据库操作的入口

3.底层是通过一个__callStatic()方法来实现各种查询操作的

4.仅在需要操作数据库的时候才会真正连接数据库,是真正的惰性连接


二、tp51数据库操作的三大核心组件及其功

1. Connection: 连接器类, think\db\Connection

2. Query: 查询器类, think\db\Query

3. Builder: 生成器类, think\db\Builder



三、连接器类的作用

1.连接数据库

2.获取数据表和字段信息;

3.基础查询(原生查询);

4.事务支持;

5.分布式支持;


内置的支持:

Mysql think\db\connector\Mysql

Pgsql think\db\connector\Pgsql

Sqlite think\db\connector\Sqlite

Sqlsrv think\db\connector\Sqlsrv


如果仅仅进行原生查询,实际上只需要连接器类就足够了,用Db类直接调用



四、查询器的作用

1.除了原生查询可以在连接类完成之外,其它的查询都是调用查询类的方法完成;

2.它衔接了连接类和生成类,统一了查询用法,所以查询类是不需要单独驱动配合的,我们也称之为查询器;

3.无论采用什么数据库,我们的查询方式是统一的;

4.Query类封装了所有的数据库CURD方法的优雅实现,包括链式方法及各种查询,并自动使用了PDO参数绑定

5.参数自动绑定是在生成器类解析生成SQL时完成,最大程度地保护你的程序避免受数据库注入攻击,查询操作

会调用生成类生成对应数据库的SQL语句,然后再调用连接类提供的底层原生查询方法执行最终的数据库查询操作

6.所有的数据库查询都使用了PDO的预处理和参数绑定机制。你所看到的大部分数据库方法都来自于查询类

而并非Db类,这一点很关键;

7.也就是说虽然我们始终使用Db类操作数据库,而实际上大部分方法都是由查询器类提供的方法。


五、生成器类Builder的作用:

1.生成类的作用是接收Query类的所有查询参数,并负责解析生成对应数据库的原生SQL语法,然后返回给

Query类进行后续的处理(包括交给连接类进行SQL执行和返回结果处理),也称为(语法)生成器。

2.生成类的作用其实就是解决不同的数据库查询语法之间的差异。

3.[查询类实现了统一的查询接口,而生成类负责数据库底层的查询对接。]

4.生成类一般不需要自己调用,而是由查询类自动调用的。也可以这么理解,生成类和查询类是一体的,

5.事实上它们合起来就是通常我们所说的查询构造器(因为实际的查询操作还是在连接器中执行的)


通常每一个数据库连接类都会对应一个生成类,框架内置的生成类包括:


数据库 生成类

Mysql think\db\builder\Mysql

Pgsql think\db\builder\Pgsql

Sqlite think\db\builder\Sqlite

Sqlsrv think\db\builder\Sqlsrv

这些生成类都继承了核心提供的生成器基类think\db\Builder,每个生成器类只需要提供差异部分的实现


六、数据库的配置分为二种:

1. 静态配置:在config/database.php,数据库配置文件中进行配置

2. 动态配置:在Db类或者Query类的connect方法中传入动态的配置参数

配置:略


七、查询基本过程

1. 开启数据库调用模式:'debug'  => true

2. 连接数据库: config/database.php

3. 导入Db类: use think\Db;

4. 在控制器中使用Db类静态调用原生查询方法query/execute进行测试

注: 原生查询仅仅使用到了连接器类,与查询器类无关


再次强调: 

1. 数据库操作主要分为连接,生成SQL查询语句与执行三部分

2. 连接器主要完成: 数据库的连接与SQL语句的执行

3. 查询器主要是负责接收参数并调用生成器生成SQL语句,不负责执行

4. 如果你只用原生查询,实际上全部操作都是在连接器Connection中完成的。



八、 原生查询

1. 这里的查询指广义的查询,即CURD,就是大家常说的: 增,删,改,查操作。

1. 原生查询是直接调用Connection类中的query()和execute()来实现。

2. query()实现读操作,主要用于select语句和存储过程的查询。

3. execute()实现写操作,例如新增,更新与删除等。

4. 原生查询也是基于PDO实现的(如果不熟悉PDO,请复习之前课程),所以支持参数绑定

5. 参数绑定支持用通用占位符与命名占位符二种格式

<?php 
	namespace app\index\controller;
	use think\Db;

	class Curd
	{
		public function select()
		{
			$sql = "SELECT name AS 姓名,salary AS 薪资 FROM staff WHERE salary >? LIMIT ?;";
			$res = Db::query($sql,[5000,3]);
			dump($res);

			$sql2 = "SELECT name AS 姓名,salary AS 薪资 FROM staff WHERE salary >:salary LIMIT :num;";
			$res2 = Db:query($sql2,['num'=>5,'salary'=>5000]);
			dump($res2);

		}

		public function update()
		{
			$sql = "UPDATE staff SET salary = :salary WHERE Staff_id = :staff_id;";
			Db::execute($sql,['salary' =>[6500,\PDO::PARAM_INT],'staff_id' =>[10,\PDO::PARAM_INT]]);
			// 如果失败会自动中止运行,抛出异常
			return '更新成功';
		}

	}

九、查询构造器查询

查询类的自动链式调用

1.查询类就是think\db\Query类,自动实例化查询类,无需手动实例化。

2.调用Db类的任何方法都会自动实例化查询类,并由查询类自动实例化连接器类执行查询。


必须熟练掌握的10大查询方法

1. table():  指定查询数据表

2. field(): 指定查询字段

3. where(): 指定查询条件

4. order(): 指定结果排序

5. limit(): 指定查询结果数

6. find(): 查询一条记录

7. select(): 查询数据集

8. insert(): 写入数据

9. update(): 更新数据

10.delete(): 删除数据

<?php 
	namespace app\index\controller;
	use think\Db;

	class Query
	{
		
		public function find()
		{
			$res = Db::table('staff')->find(10);
			$res = Db::table('staff')
				->where('staff_id',11)
				->find();
			$res = Db::table('staff')
				->field(['name'=>'姓名','sex'=>'性别','age'=>'年龄']) //可设置字段别名
				->where('staff_id',11)
				->find();	
			dump($res);	
		}

		public function select()
		{
			$res = Db::table('staff')
						->field(['name' =>'姓名','salary' =>'工资'])
						->where('salary','>',3000)
						->order('salary','DESC')
						->limit(5)
						->select();
		}

		public function insert()
		{
			$data = [
			'name' => '胡一刀',
			'sex' => 0,
			'age' => 49,
			'salary' => 5300
			];
			$num = Db::table('staff')->insert($data);
			$id = Db::getLastInsID();
			return $num ? '添加成功,ID= '.$id :'没有记录被添加';

			$id = Db::table('staff')->insertGetId($data);
			return $num ? '添加成功,ID= '.$id :'没有记录被添加';

			// 但是推荐使用data()方法,将要新增的记录打包,尽量不要再最终方法中传入参数
			$num = Db::table('staff') ->data($data)->insert();
			$id = Db::getLastInsID();
			return $num ? '添加成功,ID= '.$id :'没有记录被添加';

			//新增多条记录 insertAll(),语法与新增单条基本一致
		//新增多条记录,返回新增记录的数量
		$data = [
			['name' => '张飞','sex' => 0,'age' => 48,'salary' => 6900],
			['name' => '刘备','sex' => 0,'age' => 58,'salary' => 4500],
			['name' => '关羽','sex' => 0,'age' => 53,'salary' => 4700],
		];
		$num = Db::table('staff')->data($data)->insertAll();
		return $num ? '添加成功'.$num.'条记录~~' : '没有记录被添加';
		}

		public function update()
		{
			$num = Db::table('staff')
						->where('salary','<=',4000)
						->data(['salary'=>Db::raw('salary+1000')])
						->update();
			$num = Db::table('staff')
			//如果更新记录中存在主键,则直接根据主键更新
			       ->update(['sex'=>1,'staff_id'=>19]);
						return $num ? '更新成功'.$num.'条记录~~' : '没有记录被更新';
		}

		public function delete()
		{
			$num = Db::table('staff')
				->where('salary','>',10000)
				->delete();
				return $num ? '删除成功'.$num.'条记录~~' : '没有记录被删除';
			//提醒: 删除数据是非常危险的操作,强烈建议使用框架提供的软删除来实现,即用更新来模拟删除
			//提示: 在实际开发过程中,尽可能避免直接在控制器进行数据库操作,而是使用模型来实现
		}

	}


批改老师:韦小宝批改时间:2018-11-27 11:24:18
老师总结:很棒!这是写了很久的吧!很不错!用心了!

发布手记

热门词条