TP5访问数据库架构

database.php配置数据库的配置文件 TP5默认支持4中数据库mysql,pgsql,sqlite,sqlsrv在thinkphp目录下library/think/db/connect可以看到连接器。在type配置。hostname配置数据库IP,如果外网需要外网IP,database改成数据库名

tp5查询数据库方式有3种,1通过原生sql语句查询 2使用构造器操作数据库 3使用模型和关联模型操作数据库

tp5提供Db类用于数据库操作Db::query(sql语句);(需要use) (‘?’,[参数]) sql语句

如果我们没有任何框架,用原生php来写代码,我们通常在代码用PDO对象,或者是使用MYSQL连接类,连接上之后,写一些原生sql语句进行数据查询,大家比较常见的模式。

TP5访问数据库架构_第1张图片

下面是TP5访问层数据架构。这个是面向对象的应用。我们设计了很多的类,把每个人的职责明确。我们让类与类之间,对象与对象之间产生相互的作用,关联从而完成一系列的功能。

Db  是数据库操作的入口对象,如果我们想去查询数据库,跟新数据,或者增加数据等都是通过操作DB对象完成的。另外,我们要操作数据要连接数据库,DB也肩负着连接数据库的作用,它会根据我们的配置文件连接数据库。

Db如何连接数据库?Db实际上实例化了一个Collection对象,通过实例化Collection对象来连接数据库。首先,Collection是通过PHP的PDO来实现连接。另外它并不是真正的连接数据库,而是出于待命状态,当你去执行SQL语句才会真正连接数据库,执行sql语句。也就是说TP5这种数据库连接他是惰性的,可以节约服务器数据库资源。 公有云上面的数据库连接数是要购买的,越多越贵。如果使用原生的语句操作数据库,只需要连接器内就可以完成了,并不需要使用Query和Builder。但是TP5还提供了另一种方式,叫做查询器Query通过这样一种方式也能操作数据库。Query是对数据库常用CURD的封装,它可以让我们很优雅编写sql语句。同时它也很方便链式操作。但是这些都不是Query查询器存在的真正原因。

TP5操作数据库3种方式,第一种原生sql ,另外一种使用Query查询器,还有一种是ORM模型。都是翻译成SQL语句的形式,无论哪一种方式都是通过原生sql语句执行。只不过Query查询器对原生sql做了封装。我们通过Builder生成器来翻译成原生SQL语句。Builder把相关的Query查询器翻译成原生sql之后,他又把原生sql语句传给Collection,再由连接器类连接数据库执行sql语句。如果是原生,就是Collection连接器就接受相关操作。如果不是原生,就是Query查询器来编译Builder进行翻译原生sql,在生成原生sql又回到Collection,通过Collection来执行SQL。这个就是原理和流程。我们在访问数据库,并不是通过代码直接访问,而是通过TP5数据访问中间层(俗称的DAL Data Access Layer)操作数据库。

TP5访问数据库架构_第2张图片

使用数据库中间层访问数据库,1.可以简化sql代码编写,2.不需要关系具体实现,只需要使用中间层给你的统一的DB类就可以访问不同的数据库(可以做到跨数据库的一致性)。

    数据库访问层是如何解决数据库连接和操作的呢,首先在Db是工厂模式的设计思想,在Db里面,我们对外访问,都是使用的Db操作类,但是在内部,根据配置文件,来选择不同的驱动(图中Driver),这个驱动才是觉得Connection到底是什么类型的。也就是说我们使用这样一个Db类,不需要关系连接不同数据库的一些细节代码。对于我们来说我们总是使用这样一个Db类,这样就最大方便我们写代码,也提高了我们一个开发效率。不需要关系细节是很重要的一点。如何理解驱动(Driver)他就是提供不同的类,每一种类负责一种数据库的连接thinkphp\library\think\db\connector就是连接数据库的文件夹,就是连接器的驱动。需要什么类型的时候就更改Database配置就好了,从而完成对不同数据库的支持。所以有了Collection连接器,我们不需要去关系细节,只需要在配置文件里,指明你到底想要哪个类型数据库就可以了。

    查询器Query,有个非常重要的作用,他的作用和Collector一样的,是为了隐藏细节,支持不同数据库的查询。我们都知道不同数据库在原生sql编写还是有一定差异性的。我们可以用一种方法把差异性隐藏起来,使用统一的标准来操作数据库,这种封装变化思想在我们软件开发是非常常见的,前端很多框架,也是有很多这种思想,比如jQuery,以前浏览器的兼容性一直都很头疼,不同浏览器,他的css还有js,dom操作都是有自己的执行标准,那么我们去具体操作这些不兼容的东西就需要有适配的代码,但是有jQ就不同了。jQ提供了标注的API,让我们需要遵守这个标注就可以了,我们都可以实现不同浏览器的兼容。具体的差异性的代码由jQ帮我隐藏和封装了。这种封装变化的思想在我们框架里是非常多的,不仅仅实在服务器这块。这个差异并没有被解决而只是被隐藏起来了,对于我们Query查询器他提供了标准给我们开发者,但是他的内部还是要处理差异性。那么这个Builder生成器就是处理差异性的东西,体现了我们面向对象的封装性的思想。很多时候我们把封装性理解的太简单,这里就是一个很好的提醒,隐藏的细节和差异。最终的目的是让我们客户端,我们的开发者调用起来更加方便。所以其实没有什么代码和对象是可以自动帮我们消除差异性,还是要解决差异性,除非世界上只有一种数据,大家都用一种标准,这种差异性才不存在。但是面对这些差异我们可以用我们的封装的方法,在某一个层面上面提供标准的API,然后我们开发者调用是非常方便的。同一个标准的Query查询器用不同的Builder生成器来解析Query查询器,从而来适配不同数据库。思想和原理和Connection一样的。比如db/builder下面不同的数据库.php不同类型的生成器,这不同类型的生成器会将适配不同数据库类型的sql语句。无论用3中方式哪一种都会生成原生sql语句。

        如果世界上只有一种数据库就用不到这么复杂的思想和结构,对于框架和平台而言,它面向的群体是非常多的,面向不同的数据库,需要一种通用的,适用性比较强的架构,来完成多种数据库的连接和操作,就是我们框架和平台来考虑的事情。正是由于要处理不同的数据库,处理一些不同的需求和变化。我们这样一些所谓的设计模式和面向对象的思想才需要存在。如果就是这么简单和单一,我们就直接面向过程没问题。但是往往软件开发变化是一定存在的。所以说这些都是去处理软件开发“变”这样一个问题。虽然面向过程也可以,但是代码量很多,维护的成本也会很高。但你遇到软件变化,你的代码就像纸一样,然后你就是橡皮擦,哪里变了就擦一下改一下。再变再擦,改到最后自己都不知道代码改成什么样子了。这种擦来改去有很多不好的地方,最不好的地方还是在于影响我们编码的兴趣。有时候我们写代码平铺直叙的写想到什么写什么。其他时候还好,因为我们在工作中,没有那么多时间设计思考,但是事件一旦长了,我们就对代码没有兴趣了。就会觉得是重复的,机械的毫无意义的。这是最大的缺点。如果想在产品里完全设计架构是不太现实的。但是可以在一个项目进步一点点,在另一个项目进步一点点,长期积累就可以在面对新项目快速优雅的搭建产品结构,这是需要时间积累的。不建议抱着设计模式的书看,设计模式的理解一定是来自于编码中给的,当遇到困惑的时候再去看设计模式,才会茅塞顿开。23中设计模式,不是死记硬背学下来的。


你可能感兴趣的:(PHP开发)