MyBatis知多少(15)数据模型
瘦数据模型是一种最为臭名昭著并且问题多多的对关系数据库系统的滥用。不幸的是,有时又的确需要瘦数据模型。所谓瘦数据模型,就是简单地将每张表都设计为一种通用数据结构,用于存储名值对的集合。这非常像Java中的属性文件。有时这些表也可用于存储元数据,例如期望的数据类型等。这是必要的, 因为数据库只允许一列有一种类型定义。要更好地理解瘦数据模型,考虑下面这个典型的地址数据的示例,如表1-2所示。
|
表1-2典型模型中的地址数据
|
|
很显然这个地址数据表可以进一步规I范化。例如,可以创建COUNTRY (国家)、STATE (州)、 CITY (城市)和ZIP (邮编)这样的关联表。但当前这样一个设计对于大多数应用程序来说既简 |
|
还是使用以上的数据, |
如果将它们放入一个瘦数据模型对应的表中, |
结果将如表1-3所示。 |
|
表1-3瘦数据模型中的地址数据 |
||
|
ADDRESSJD |
FIELD |
VALUE |
|
1 |
STREET |
123 Some Street |
|
1 |
CITY |
San Francisco |
|
(续) |
||
|
ADDRESS ID |
FIELD |
VALUE |
|
1 |
STATE |
California |
|
1 |
ZIP |
12345 |
|
1 |
COUNTRY |
USA |
|
2 |
STREET |
456 Another Street |
|
2 |
STATE |
New York |
|
2 |
ZIP |
54321 |
|
2 |
COUNTRY |
USA |
这样的设计绝对是场噩梦。首先,没有任何可能对它进一步规范化了,虽然当前的模型只能 算作第一范式。其次,没有任何机会创建与COUNTRY表、CITY表、STATE表或ZIP表的关联关系了,因为我们不可能在同一列上定义多个外键。再次,如果希望执行一条涉及多个地址字段(例如,执行一个以街道和城市作为查询条件的查询语句)的“样例查询”,这样的数据实在让人头痛,它可能需要一大堆复杂的子查询。再看看更新的情况,这样的设计就性能来说也特别糟糕, 仅仅是插入一个地址就需要在同一张表上执行5条插入语句。这种情况下出现锁竞争甚至死锁的 可能性也大大增加了。此外,这个瘦数据模型中记录的数量整整是我们的规范化数据模型的5倍。 由于记录数量过大,又缺少明确的数据定义,而且更新一条记录时需要的更新语句过多,创建有 效的索引也是不可能的了。
不用再多说了,这个设计确实问题多多,我们为何要不惜一切代价避免这样的设计,原因已经再明白不过了。但话说回来,这个设计也不是毫无用处,它唯一的用武之地就在于那些需要动态字段的应用程序。有些应用程序的确有这样的需求,它允许用户对他们的记录添加额外的数据。 如果用户希望能定义新的字段,然后在应用程序运行时动态地把数据插入到这些字段中,那么这样的模型就可以工作得很好。也就是说,所有的已知数据还是应该正确地规范化,而这些额外的动态字段则可以通过关联关系与这些已知数据建立父子关系。这样的设计同样存在我们之 前讨论过的所有问题,但它们被最小化了,因为大部分数据(很可能是那些最重要的数据)都 己经被正确地规范化了。
即使在一个企业数据库中遇到了瘦数据模型,MyBatis也可以帮助你处理它。要将若干个类映射为瘦数据模型是非常困难的,甚至是根本不可能的,因为你连数据模型中可能存在哪些字段都 无法明确。此时你最好将这样的类映射为一个散列表(hashtable),而幸运的是iBATIS支持这种 映射。使用MyBatis,你不必将每一张表都映射为一个用户定义的类。MyBatis允许你将关系数据映 射为Java基本类型(primitive)、Map实例、XML还有用户定义类(如JavaBean)。这种巨大的灵 活性使得iBATIS对于包括瘦数据模型在内的复杂数据模型非常有效。

MyBatis被设计为一个混合型解决方案,它并不试图解决所有的问题,相反它只希望能解决那些最重要的问题。MyBatis从各种数据库访问工具中汲取了大量的优秀思想。像存储过程一样,所有的MyBatis语句都有一个签名,定义了语句的名字和输入输出(封装)。与内联SQL类似,MyBatis允许SQL语句按照其最自然的方式书写,并且可以直接使用语言中的变量作为输入输出参数和结 果。像动态SQL—样,MyBatis允许在运行时修改SQL。这样的查询语句可以根据用户的请求动态 构建。从对象/关系映射工具中,MyBatis借用了许多概念,包括高速缓存、延迟加载,还有更高 级的事务管理。
在一个应用程序的架构中,MyBatis适用于持久层。MyBatis也通过提供一些特性来支持其他层, 这些特性使得对所有这些层的需求的实现都变得更加容易。例如,一个Web搜索引擎可能需要搜 索结果的分页列表。MyBatis支持这种特性,因为它允许査询时指定返回结果的偏移量和行数量。这就使得分页操作可以在一个较低的层次上执行,同时保持数据库细节可以远离我们 的应用程序。
MyBatis可用于任何大小和用途的数据库。首先,MyBatis非常适合于那些较小的应用程序数据库,因为它非常容易学习和快速上手。其次,MyBatis对大型企业应用程序也非常合适,因为它没有对数据库的设计、行为或者那些可能对我们的应用程序如何使用数据库产生影响的依赖关系做 任何假设。再次,即使是对于那些在设计上存在着争议或者深陷于高层政策混乱之中的数据库, MyBatis也可以工作得很好。综上所述,MyBatis被设计得非常灵活以至于几乎可适用于任何情况了。 当然,使用MyBatis也可以为你节省大量的时间,因为你再不用写那些重复的、样本一样的代码了。
讨论了 MyBatis的理念和起源。后面将仔细解释什么是MyBatis以及它是如何工作的。
系列文章:
MyBatis知多少(15)数据模型的更多相关文章
- MyBatis知多少(26)MyBatis和Hibernate区别
iBatis和Hibernate之间有着较大的差异,但两者解决方案很好,因为他们有特定的领域.我个人建议使用MyBatis的,如果: 你想创建自己的SQL,并愿意维持他们. 你的环境是由关系数据模型驱 ...
- MyBatis知多少(26)调试
这是很容易,同时与iBATIS的工作程序进行调试. iBATIS有内置的日志支持,并适用于下列日志库,并在这个顺序搜索他们. Jakarta Commons日志记录(JCL). Log4J JDK 日 ...
- MyBatis知多少(25)动态SQL
使用动态查询是MyBatis一个非常强大的功能.有时你已经改变WHERE子句条件的基础上你的参数对象的状态.在这种情况下的MyBatis提供了一组可以映射语句中使用,以提高SQL语句的重用性和灵活性的 ...
- MyBatis知多少(24)存储过程
使用MyBatis配置来调用存储过程.为了理解这一章,首先需要了解我们是如何在MySQL中创建一个存储过程. 在继续对本节学习之前,可以自行学习MySQL存储过程. 我们已经在MySQL下有EMPLO ...
- MyBatis知多少(23)MyBatis结果映射
resultMap的元素是在MyBatis的最重要和最强大的元素.您可以通过使用MyBatis的结果映射减少高达90%的JDBC编码,在某些情况下,可以让你做JDBC不支持的事情. ResultMap ...
- MyBatis知多少(22)MyBatis删除操作
本节从表中使用MyBatis删除记录. 我们已经在MySQL下有EMPLOYEE表: CREATE TABLE EMPLOYEE ( id INT NOT NULL auto_increment, f ...
- MyBatis知多少(21)更新操作
上一章展示了如何使用MyBatis对表进行读取操作.本章将告诉你如何在一个表中使用MyBatis更新记录. 我们已经在MySQL下有EMPLOYEE表: CREATE TABLE EMPLOYEE ( ...
- MyBatis知多少(20)MyBatis读取操作
上篇展示了如何使用MyBatis执行创建操作表.本章将告诉你如何使用MyBatis来读取表. 我们已经在MySQL下有EMPLOYEE表: CREATE TABLE EMPLOYEE ( id INT ...
- MyBatis知多少(19)MyBatis操作
若要使用iBATIS执行的任何CRUD(创建,写入,更新和删除)操作,需要创建一个的POJO(普通Java对象)类对应的表.本课程介绍的对象,将“模式”的数据库表中的行. POJO类必须实现所有执行所 ...
随机推荐
- paip. 调试技术打印堆栈 uapi print stack java php python 总结.
paip. 调试技术打印堆栈 uapi print stack java php python 总结. 作者Attilax 艾龙, EMAIL:1466519819@qq.com 来源:attil ...
- js实现点击一个按钮进行两种状态的切换(toggle)
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8 ...
- Hibernate入门3.配置映射文件深入
Hibernate入门3.配置映射文件深入 2013.11.27 前言: 之前的两节是在Java项目中如何使用hibernate,并且通过一个简单地项目实践,期间有很多的错误,一般都是因为配置包的问题 ...
- DataGridViewComboBoxColumn值无效
值无效,可能是你下拉框选项,没有这样的值,而你却设置这个值. dataGridView1.Rows[i].Cells[].Value = "选项一"; 解决方法就是在窗体的构造函数 ...
- C#中Math.Round()实现中国式四舍五入
C#中Math.Round()实现中国式四舍五入 C#中的Math.Round()并不是使用的"四舍五入"法.其实在VB.VBScript.C#.J#.T-SQL中Round函数都 ...
- js Array 交集 并集 差集 去重
最劲项目需要用到js数组去重和交集的一些运算,我的数组元素个数可能到达1000以上,网上的实现方式都是2次循环,性能不适合我的需求,1000*1000那循环次数太多了,所以我这里采用对象object来 ...
- 使用React、Node.js、MongoDB、Socket.IO开发一个角色投票应用的学习过程(三)
这几篇都是我原来首发在 segmentfault 上的地址:https://segmentfault.com/a/1190000005040834 突然想起来我这个博客冷落了好多年了,也该更新一下,呵 ...
- JAVA中类、实例与Class对象
已同步更新至个人blog:http://dxjia.cn/2015/08/java-class-object/ 类 类是面向对象编程语言的一个重要概念,它是对一项事物的抽象概括,可以包含该事物的一些属 ...
- Mac上编译libimobiledevice库
0.准备工作: 使用brew或Mac Ports安装:libgnutls or openssl. libplist .libusb.libusbmuxd 1.下载代码: 下载地址:https://gi ...
- jarsigner 签名android apk
1.查看签名: jarsigner -verify app_signed.apk 查看是否签名,如果已经签名会打印 "jar verified". jarsigner -verif ...