1、什么是ORM:
ORM(Object Relational Mapping)对象关系映射,一般指持久化数据和实体对象的映射
只要提供了持久化类与表的映射关系,ORM框架在运行时就能参照映射文件的信息,把对象持久化到数据库中。
ORM就是对象关系匹配,是为了解决面向对象与关系数据库存在的互不匹配的问题。简单来说,就是把关系数据库中的数据转换成面向对象程序中的对象。
2、为什么需要ORM
ORM的出现充当了对象和数据库层次的桥梁作用。
实现一个最简单的部门信息的CURD,如果你能做到修改数据结构而不用修改任何代码,那么你就初步实现了业务逻辑和数据访问的分离;再如果,修改界面的查询条件或者列表而不用修改任何代码,那么你就初步实现了业务逻辑和界面的分离;能做到这些,就差不多是MVC的设计模式了
为方便程序员通过代码将数据写入数据库,一般的语言开发的厂商都会为各种数据库适配数据库连接的驱动程序,比如ADO.Net,JDBC等。
但是数据库连接的驱动程序的职责在于管理连接数据库,设置连接参数等信息,通常会返回各自封装好的数据集类型,驱动程序封装的类型往往是以数据为核心进行描述的,现代化的软件设计为了简便描述事物的特征都而以面向对象思想为核心,两者之间的转换还有很多的路要走。
除却转换部分,Sql语句的编写也是一大学问,一般的编程语言都没有为sql语句定义类型,这是因为每种数据库的sql语句风格都是不一样的,难以给出一个统一的方案。退而求其次,一般的编程语言都采用字符串形式传递sql语句到数据库驱动程序。抛弃各种各样的sql语句的学习之外,这种方式有一个很大的弊端,那就是sql语句的拼写极容易由于手误而犯错。
在这种场景下,ORM框架诞生了!
即没有ORM的情况下,主要有两个槽点:
1.驱动返回类型和对象不能良好映射
2.SQL语句的学习成本及易错率(多种数据库语句难以全部掌握)
3、实现原理:
ORM如何改善这两个槽点:
1.数据驱动返回的数据通常都是以数据为核心的数据集合,我们需要通过手动将类对象和数据库返回的列数据进行一一匹配获取,然后赋值到对象上。在这里要感谢泛型和反射两大语法,通过泛型和反射,我们可以获取到任何实体类的属性而不是具体到某一种类型,通过遍历实体类的属性去数据集合中一一获取并复制返回。这一操作便将数据集合的数据完美包装成了以面向对象为核心的和类相关的对象数据集合。
2.sql语句的拼写,我们可以提供一套公共sql语句模板,然后在具体实体对象操作的时候将实体对象的属性名称和属性值当作参数拼接进去,组装成完整的sql语句(例如java体系中的Mybatis框架)或者依旧采用封装一套浅显易懂的Api,Api内部通过对应方法和实体对象的组装成sql语句(例如.Net体系中EntityFramework框架)。
ORM还为我们做了什么?------“缓存”。
ORM框架的缓存系统一般是较为复杂的,而且每种ORM框架对缓存的实现机制都是不同的。整体的思路却是一致的,对访问频率较高的数据进行缓存,并在对数据编辑的时候要对缓存进行更新,以免出现数据不一致的问题。
4、ORM框架有哪些:
1 ) Nhibernate
原因:用的比较多,资料也比较好找。
2 ) Castle ActiveRecord
原因: 不用配置对象的XML文件,这点比Nhibernate爽
.Net体系:
EntityFramework,功能强大,微软的东西
lambda api,有些庞大臃肿,很多功能用不上
Dapper,轻量级,数据库种类支持丰富,sql写法灵活,运行速度快
CYQ.Data,自动化,日志,分布式缓存,弱类型,api简介
Java体系:
MyBatis/ibatas,映射采用Xml配置sql,多种映射关系灵活配置,sql需要手动编写到配置,轻量级,半自动。MyBatis通过映射配置文件,将SQL所需的参数和返回的结果字段映射到指定对象,MyBatis不会自动生成SQL,需要自己定义SQL语句,不过更方便对SQL语句进行优化。入门简单,即学即用,提供了数据库查询的自动对象绑定功能,而且延续了很好的SQL使用经验,对于没有那么高的对象模型要求的项目来说,相当理想。PO是扁平化的。同样的需求,iBATIS的工作量比Hibernate要大很多。iBATIS的缺点就是框架还是比较简陋,功能尚有缺失,虽然简化了数据绑定代码,但是整个底层数据库查询实际还是要自己写的,工作量也比较大,而且不太容易适应快速数据库修改。当系统属于二次开发,无法对数据库结构做到控制和修改,那iBATIS的灵活性将比Hibernate更适合。系统数据处理量巨大,性能要求极为苛刻,这往往意味着我们必须通过经过高度优化的SQL语句(或存储过程)才能达到系统性能设计指标。在这种情况下iBATIS会有更好的可控性和表现。
Hibernate,Xml配置sql,支持HQL语句,移植性好,日志,重量级,功能全,全自动。Hibernate对数据库结构提供了完整的封装,实现了POJO对象与数据库表之间的映射,能够自动生成并执行SQL语句。只要定义了POJO 到数据库表的映射关系,就可以通过Hibernate提供的方法完成数据库操作。Hibernate符合JPA规范,就是Java持久层API。学习门槛不低,要精通门槛更高,怎么设计好O/R映射,对性能影响较大。PO是可以表达立体的对象继承、聚合等关系的。数据库无关性比较好,O/R映射能力强。hibernate还能够自动建表,这样的好处就在于你带着这个程序,无论到什么机器上,你都不需要数据库,应为它能自动为你完成,而ibatas就必须要有相应的数据库表才能进行移植。如果你对Hibernate相当精通,而且对Hibernate进行了适当的封装,那么你的项目整个持久层代码会相当简单,需要写的代码很少,开发速度很快,非常爽。
Speedment,lambda api,依赖java8
5、怎样选用合适的ORM框架:
1)ORM将数据转换为对象所用时间
2)在并发比较大的情况下(不是非常大)数据会莫名其妙的被改掉,比如说我用多个线程多次通过该框架访问数据库后数据就错掉了。
3) 出错了信息提示不明确,因为是内部用的,有些异常直接用try catch给隐藏起来了。
4) 在使用的过程中有可能是ORM自身的BUG,引起程序异常,这样一边要检查上层程序,同是还要去排除底层ORM的bug,这样很浪费时间的。
5)如果有复杂sql的话推荐用 mybatis 轻量,配置少,灵活是优点。否则 Entity Framework 是不错的选择,Linq2EF 开发速度快。
6、优缺点:
ORM注定了业务逻辑和数据库的高度耦合,确切的说一个业务实现只能对于一个数据结构,连改一下数据结构都要修改程序,更不用说同时支持不同的数据结构了。
ORM框架降低了学习门槛,一个对sql语句并不熟悉的开发人员也可以很容易通过简易的ORM框架Api进行数据库的操作。
提高了开发效率,ORM使我们减少很多繁琐重复的工作量,让我们的注意力集中在实现业务上。
一定程度上提高了程序的响应速度。
ORM框架的弊端也很明显,框架会自动生成Sql语句,所有场景的sql语句都是同一套模板,难以自动针对场景对sql语句进行良好的优化,某种场景下很容易生成执行很慢的sql语句。如果让DBA看到这样的执行sql,必定引来抓狂崩溃。
ORM框架只是为了满足绝大多数的场景而生的,特殊需要优化sql的场景下,我们完全可以直接使用驱动手动执行sql或使用ORM框架内提供的sql语句api进行自定义sql语句。