2010 Java持久化之旅 --起源

在广大人民群众和资深玩家的建议下,我开始认真得不得再认真的学习Java持久层的技术。目前关于持久层的书太多,高手建议下,貌似开发hibernate 作者写的Persistence with hibernate 比较靠谱,so ,学习开始。先把这周的学习内容总结下。
1.起源
任何事情产生,都有原因。Hibernate或者其他持久层的框架iBATIS之类我一直认为是因为很多人不会写SQL或者说写不好SQL。But,看了P书Part1后,偶知道,偶错了。
SQL诞生
首先,从持久化说起。持久化,就是把Aplication的状态或者部分状态,保存到可以断电之后依然存在的设备中(比如说,纸上。。。)。
而所有这些东西中,平板文件,XML或者。。。纸,都不是很靠谱,也不好管理,不好阅读。所以,这是为什么数据库产生的原因。

持久化来了
继续来说持久化,把数据(Application中的状态)存入数据库中,然后在一定时间取出来,持久化大概就这样。
具体来说,持久化需要做到以下几点才能叫做真正的成功:
a.能够保存,组织数据,并且可以把数据以一定结构读出
b.处理并发,和保证数据完整性(如果存银行的时候是5000,取出来的时候是5块,那么久没必要存银行了)
c.处理数据共享

问题也来了
我看到这里的时候也很奇怪,为啥米会有问题,把对象的属性保存到数据库不久完事了吗?
但是,因为OO的出现,本来过程化编程中的结构体和数据库表之间几乎相等的映射关系被打破了。

a.Application模型粒度与数据库模型粒度不匹配
假设有个User中有一些基本属性,又有一个名为Bill的对象引用。类像这样
User{
//some popers
String name;
Bill bill;
//methods
}
Bill{
//bill propers
}
数据库表
create table USER{
NAME varchar(10);
//the following propers represents bill information
MONEY int;
LAST_DATE int;
}
在Application中,有2层User,Bill (用DDD来说就是2个实体对象模型) 但在数据库这一层,我们只看到了一个表。
当时看到这里的时候,我就在想,作者傻呀,我再建一个BILL表不久完了。对,但这回引来另外一个模型不匹配。

b.关系映射不匹配
就像上面例子,如果我们多见一个表BILL.
首先需要明白的是:OO映射使用的是Reference,但数据库映射使用的是外键。这之间的区别会导致一些现在还没看到的问题:
我们先稍微修改下上面的两个类
User{
//some popers
String name;
Set<Bill> bills;
//methods
}
Bill{
Set<User> usersToPayTheBill;
//bill propers
}
简单的一一对应,变成了多对多。现在的问题是,如何能让数据库表现出这种关系呢?对,中间表。
这张中间表,USER_BILL可以使用User和Bill的主键做外键。问题搞定了。。。。吗?
我并没有在Application模型中看到哪里有USER_BILL表可以对应过去的地方。这也实际上是问题a,粒度匹配不上导致的。

c.问题还在继续,OO中的继承关系如何表示
还是拿代码说事,现在User和Bill都在和谐世界中改进了下,开始使用面向接口编程了。。。
User{
//some popers
String name;
Bill bill;
//methods
}
abstract Bill{
long defaultBill = 1000;
//bill propers
}
BillForDuty extends Bill{
//BillForDuty propers
}
BillForRent extends Bill{
//BillForRent propers
}
其他不用说,直接傻眼。对象模型中的继承是叫做Type Inheritance,但关系数据库中的对应类的Table不是一个类型,不存在SuperTable和SubTable之说。
问题还没有结束,面向对象中继承封装和多态,才说了一个不匹配。
当我把一个BillForDuty 得实力丢给User时,只有运行时才会知道这个Bill 引用背后就是个BillForDuty 而不是其他的Bill类型。如果我想根据对象去查询相关信息,我只有寄希望SQL可以做到,但是由于前面说过关系数据库维护关系是通过外键,而外键是直接把值绑定到具体的表上,所以挂了。

d.Equivalent不匹配
就是说对象的equals()或者 == 法在数据库这一层体现说来。因为不管是equals()还是 == ,都是针对对象模型,关系数据库的等同性是由主键决定。

e.查找不匹配
对象模型中要查找一个具体的值 比如 someObject.getProperA().getProperB() 就ok了。但是在关系数据库中要这样写
select * from Object o left outer join A a on a.B_id = o.O_id where o.A=123
好像没问题,但是问题就是:在对象模型中,你不知道getProperA()拿出来是什么就可以继续拿A中B的值,但是在关系数据库中尼必须先知道A是123才能继续找。
*这里有个问题。。。不是PreparedStatement就可以解决者问题吗?

模型不匹配的代价
最大的体会就是,要扭曲领域模型去匹配更难搞定的数据库模型。
今天到此为止,明后争取天把第二部分的总结弄好。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值