ORM对象关系映射

全称Object object relation mapping 对象关系映射

让我们用面向对象的方式来思考数据表。在我们传统的sql中并没有把表当做对象,我们就是理解的二维关系的数据结构。但是用ORM我们得吧每张表思考成一个对象。那么用这样一种方式查询数据库不再使用sql语句。当我们用ORM查询数据库,我们操作的不是数据库的表,我们操作的是对象。至于说对象是如何获取数据的,这些细节是不需要我们关心的。我们就是要通过对象来拿到数据。那么此时表与表的关系不再是数据结构与数据结构的外键,而是对象与对象之间的作用关系。所以说这样的方式是非常符合我们面向对象的思维方式的。

ORM不是一个什么具体语言,也不是什么具体框架,他就是一种思想。不同语言不同框架都会实现自己的ORM。最著名的ORM框架是Java的Hibernate 还有C#的EntityFramewok,python的SQLAlchemy等等。

模型与模型关联,我们说的模型特指TP5的模型,在TP5的模型里是ROM的具体实现机制。在TP5里这个模型不只是做数据库的查询,同时还可以包含一些业务逻辑。不要把模型理解为对象,不仅仅完成查询,还要包含业务逻辑。我们要说的模型概念范围更加广阔,他是业务的集合,并不仅仅是对象的集合。很多对象组合在一起也可以称作为模型。模型的作用就是用来处理比较复杂的业务逻辑。我们再说的更加直白的一些,ORM是把一个表当做一个对象来看待,但是模型有可能是对应多个对象的,同时他也有可能对应多个表。模型和对象和表之间没有必然联系,以为他们的划分并不是从表这个角度划分的。模型是根据自己的业务逻辑来划分的,简单点说就是根据功能划分的。我们继续在说这个问题,很多时候如果业务逻辑足够简单的话,会造成一个对象一个表对应一个模型。但是我们强调业务逻辑非常简单的时候,一但业务逻辑非常复杂的时候,这个业务逻辑涉及多个表或者多个对象之间的相互作用关系呢,此时这个模型或者这个对象或者表就不是一一对应的了。

1.不要把模型理解成数据库查询。数据库的查询是数据库的查询,模型是模型。模型更加关注业务逻辑,而不是数据查询。

2.不要把模型和数据库表一一对应起来。简单的业务逻辑会造成假象。就是一个模型对应一张数据库的表。但是复杂的模型和复杂的业务逻辑不是这样的,可能会横跨多个表。

对于一些比较复杂的业务逻辑,他是需要分层次处理业务逻辑的。到底分几层,怎么分就是业务设计方面的问题了。但是模型并不是只有Model这一层,他还可以进一步去划分。TP5 推荐有3层,model,service和logic。至于说你要用几层,或者说都写进model里面可以。当你想对业务逻辑进行细分的时候。比如说Model里面提供非常细小粒度的接口,然后在细小粒度的Model上面再做一个Service,那么Service是很多Model层API的集合。Service提供的是比较粗粒度的接口,这样一个业务划分也是可以的。重点不在于分几层,重点在于业务逻辑,模型是可以划分为多层的。怎么划分根据自己的业务来决定。

看起来我们之前的Db已经足够强大了,实际上如果只是简单的增删改查(curd)那么Db是完全足够的。但是往往我们在真实的项目里面,只是简单地增删改查是远远不够的。我们需要大量的业务逻辑来处理。我们可以举一个具体的例子,比如说用户登录的操作,那么在我们简单的系统里面,都能理解,登录就是比对用户的账号密码。但是这个只是简单的业务。我们还可以进一步考虑复杂的情况。比如说当用户登录不是在一个常在地,登录有一个异地登录,这个时候发个短信提醒。另外,有可能我们在多个设备上面同时登录,有时候我们为了特殊的目的,我们不先让用户同时在很多设备上登录,这时候我们在用户上登录就要做机制上的处理。比如说我在PC端登录,移动端自动下线。像这样一下比较复杂的业务,这个Db类就显得比较吃力了。我们是用ORM来处理。对象内部是包含业务逻辑的,否则就不叫对象了。刚好对象是可以写逻辑的,我们的解决方式就是,ORM对象来承载我们的业务逻辑。Db最大的劣势就是不能很好地包含处理我们的业务逻辑。

TP5的模型和Db关系:TP5model模型和Db是不分离的,因为Db是model的基础,实际Model下面还是Db类来驱动的。只不过TP5把模型的概念给单独提出来了,帮你封装好了。所以我们操作数据库,就是操作Model实体对象,而Model实体对象是如何去连接数据库的,我们不需要去关心。因为PT5已经帮我们做好了,她的下面会自动调用Db类去进行数据库操作。我们最后再总结一下,Db数据数据库访问层,但是Model模型不是数据库访问层,它是建立在数据访问层上面更加抽象的处理业务逻辑的模型层。这个就是MVC里model的作用,model才是处理这样一个业务逻辑的。

Model层需要继承tp5的model。继承了Model我们的Bannel变成了模型。原来我们是在Model自己写代码用Db类来查询数据。但是无论是那种形式都是从控制器调用Model。如果不去继承think的model需要自己编写方法,并且还需要处理查询逻辑。但是继承了think model就不需要编写查询方法了。直接去调用get方法。无论是不是继承think/model,都因该视成模型对象。区别在于TP5给你准备好了think/model这样一个基类,让你直接调用get方法,不去继承的话,同样是model模型层,只不过就没有直接调用get方法的能力,需要自己编写类似的方法!!!不去继承框架的模型,自己编写模型层也可以。只不过更加的麻烦一些,调用Db或者原生sql,来完成查询逻辑。不过模型查询方式不是直接返回了数组,他直接返回了模型对象。这是模型和Db最大的区别。既然ORM是以对象的方式思考数据库,那么不仅仅是调用的方式是采用对象方式调用,同时返回结果也一定是对象,否则如何称作用对象方式操作数据库。返回来的对象有什么优势和好处?返回数组没什么办法操作,只能使用数组内置的PHP基本方法和函数,但是这是远远不够的。如果返回对象的话,有很多的方法和属性,这些方法和属性都可以进一步为我们,查询结果提供很大的帮助,比如append,hidden.....这是ORM的一个很大的好处,在写业务逻辑会大量使用到。我们都不需要返回json对象,直接返回对象,就会对对象的序列化,从而得到我们要的json结果。不过不会按照json格式化形。我们需要改成json形式。在config的‘default return type’就是默认的类型的,改成json即可。

模型:通常情况下都需要继承think/model类,另外一个模型一般是对应一个数据库的表的(业务比较简单,大多数情况下面)关联模型就是多张表关联的。数据库表是有主表和从表概念,如何把从表映射到ORM对象中来呢。TP5就是关联模型的方案来解决对应数据库的主从表。在默认情况下数据库表的名字和我们模型的类名是一一对应的,也就是说我们不需要特别设置。对象的名字就是同名数据库表的对象映射,但是表名和类名并不一定要相等。如果不想一样我们就需要指定到底哪张表。

protected $table = '表名';

我们只需要设置对象的属性就可以了。

另外TP5有自动生成Banner文件的命令 打开终端ALT+F12 php think make:modle 模块/模型名

遇到查询TP5推荐静态方式,当然也可以换种写法我们可以先实例化,然后->也可以

静态和实例化模型,在模型查询这块使用静态最好。因为1静态方法调用更加简洁2模型本质意义,我们都知道数据库基本单位是表,以及表里面一条一条记录,ORM是关系型数据库的映射和对照,我们在ORM如何表示表和记录。面向对象类和对象。类对应数据库的一张表,但是并不对应表的一条记录。当你把类实例化之后得到一个具体的对象后,他才是数据库表下面的纪录。类是一个抽象的东西,并不是一个具体的事物,类是用来描述对象相关的属性和行为的。只有把类New出来之后才能代表一个事物。类就是生产对象的模板。new了一个后实例化的模型对象,是一条记录,这条记录再GetID这个说不过去,已经是一个记录你还Get什么。静态的方式就很合理的,类对应数据库的一张表,就说得通,从很多记录get一个。从合理性角度出发

查询有get,find,all,select

get和find只能查询一条数据库的纪录,只能返回一个

all和select返回的是一组记录,就是一组对象

get和all是模型特有的方法,find和selcet是Db特有的方法

用Db是不能使用get和all

用模型可以使用selcet和find

因为Db是模型的基石,他们两者不能分离的。在模型的内部访问数据层还是Db。    

我们编写代码很多时候适用于解决现实世界很多问题,编码本身就是现实事物的一个抽象,所以能用面向对象方式就用面向对象方式。我们要很好的掌握模型要理解四个原则,1 模型和数据库访问层是2个概念,模型是用来处理业务的,Db访问层就是用来查询数据库的,模型是建立在Db的基础上的 2 不要因为模型性能稍差就放弃使用模型 3 我们要用面向对象的思维来使用设计模型 4 模型他的底层仍然是访问数据库抽象的,自动调用下面的数据库访问层

模型性能: 模型的性能一定比原生sql要慢,每一种技术和模式都有自己的优点和缺点。在性能可以允许的范围区间内,性能稍差可以接受。好的代码第一原则不是性能,而是可读性。首先使用框架就已经性能损耗,因为抽象封装,那么就不适用框架了吗?如果一味追求性能直接去使用C和汇编吧。因为性能有损耗,但是开发效率会提高。绝大多数的产品对性能的要求远远没有那么高。如果产品访问很慢,也不一定是ORM引起的。ORM的差距是用户感觉不出来的。主要是SQL语句写的不好。他就是封装一下,可以更好的更优雅封装代码,性能损耗没有那么高。除非有很多高并发,非常在意sql性能,就用原生sql。绝大多数ORM够了。

外键:

public function items(){
    return $this->hasMany('需要关联的表名','关联模型的外键',‘当前模型的主键’);
} 
一对多是hasmany,一对一是belongsTo

this就是这张表,hasmany就是有多个通过关联模型外键和当前模型的主键关联在一起的。

另外取出关联数组的数据需要在控制器with(‘关联方法名items’)链式方法

如果关联多张表with(['方法1',‘方法2’]),嵌套关联用 方法1.方法2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值