- ORM 对象关系映射(Object Relational Mapping)
对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中。那么,到底如何实现持久化呢?一种简单的方案是采用硬编码方式,为每一种可能的数据库访问操作提供单独的方法。
这种方案存在以下不足:
1.持久化层缺乏弹性。一旦出现业务需求的变更,就必须修改持久化层的接口
2.持久化层同时与域模型与关系数据库模型绑定,不管域模型还是关系数据库模型发生变化,都要修改持久化层的相关程序代码,增加了软件的维护难度。
ORM提供了实现持久化层的另一种模式,它采用映射元数据来描述对象关系的映射,使得ORM中间件能在任何一个应用的业务逻辑层和数据库层之间充当桥梁。Java典型的ORM中间件有:Hibernate,ibatis,speedframework。
ORM的方法论基于三个核心原则:
· 简单:以最基本的形式建模数据。
· 传达性:数据库结构被任何人都能理解的语言文档化。
· 精确性:基于数据模型创建正确标准化了的结构。
- ORM的概念
让我们从O/R开始。字母O起源于"对象"(Object),而R则来自于"关系"(Relational)。几乎所有的程序里面,都存在对象和关系数据库。在业务逻辑层和用户界面层中,我们是面向对象的。当对象信息发生变化的时候,我们需要把对象的信息保存在关系数据库中。
当你开发一个应用程序的时候(不使用O/R Mapping),你可能会写不少数据访问层的代码,用来从数据库保存,删除,读取对象信息,等等。你在DAL中写了很多的方法来读取对象数据,改变状态对象等等任务。而这些代码写起来总是重复的。
ORM解决的主要问题是对象关系的映射。域模型和关系模型分别是建立在概念模型的基础上的。域模型是面向对象的,而关系模型是面向关系的。一般情况下,一个持久化类和一个表对应,类的每个实例对应表中的一条记录,类的每个属性对应表的每个字段。
ORM技术特点:
1.提高了开发效率。由于ORM可以自动对Entity对象与数据库中的Table进行字段与属性的映射,所以我们实际可能已经不需要一个专用的、庞大的数据访问层。
2.ORM提供了对数据库的映射,不用sql直接编码,能够像操作对象一样从数据库获取数据。
- ORM框架结构分析:
- MyBatis框架描述:
MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。
MyBatis使用简单的XML或注解用于配置和原始映射,将接口和Java的POJOs(Plan Old Java Objects,普通的Java对象)映射成数据库中的记录.
MyBatis和ibatis的区别:
Mybatis是ibatis的升级,Mybatis不需要写dao的实现类,只需要接口和xml配置文件,接口中声明的方法和xml中的操作id名称相同。
- JDBC到MyBatis优化改进
1).JDBC查询数据库数据,一般需要以下七个步骤:
- mybatis中的#和$的区别
(1.功能(预编译);2.性能(重复利用);3.注入;4.表名;5.order)
#{para}是预编译处理(PreparedStatement)范畴的。
${para}是字符串替换。
Mybatis在处理#时,会调用PreparedStatement的set系列方法来赋值;处理$时,就是把${para}替换成变量的值。
1).能使用 #{ } 的地方就用 #{ }
首先这是为了性能考虑的,相同的预编译 sql 可以重复利用。其次,${ } 在预编译之前已经被变量替换了,这会存在 sql 注入问题。
例如,select * from emp where ename = '用户名',如果使用$入参,用户名被传入例如‘smith or 1 = 1’,那无论ename是否匹配都能查到结果。
2).表名作为变量时,必须使用 ${ }。这是因为,表名是字符串,使用 sql 占位符替换字符串时会带上单引号 '',这会导致 sql 语法错误,例如:
select * from #{tableName} where name = #{name};
预编译之后的sql 变为:
假设我们传入的参数为 tableName = "user" , name = "Jack",那么在占位符进行变量替换后,sql 语句变为:
select * from 'user' where name='Jack';
上述 sql 语句是存在语法错误的,表名不能加单引号 ''(注意,反引号 ``是可以的)。
3).有时你只是想直接在SQL语句中插入一个不改变的字符串。比如,像ORDER BY,你可以这样来使用:
ORDER BY ${columnName}