大约一年以前我为了学习一些Hibernate专业知识因此我参加了一个Hibernate项目从那时起我一直在使用Hibernate框架下的JPA(Java持久API)实现使用的思想仍就是一样的那个项目使用了一个数据库这个数据库规模有些大略显落后并且还被许多的应用程序共用为了尽快加入到项目中我开始学习一些Hibernate知识从书本上的例子开始学习感觉很简单学起来也很快但是发现从零开始开发一个项目并且控制它又是另外一回事了试着在一个大型复杂被许多应用程序共用的数据库上使用Hibernate就又完全不同了弄清楚了我可能遭遇到的技术难点我开始想别的招了要尽快从另外的方向开始克服困难
在最终的学习和实践中我发现我还是学到了许多重要的东西虽然我们的项目还没有完全做完但是我认为我们目前已经非常漂亮的应用了Hibernate/JPA的一些思想现在我需要重新思考反省我所学到的东西如下便是我学到的一些心得
)和数据库管理员成为朋友
目前存在一个趋势就是一些Java开发者忽视数据库管理员的重要性这便犯了一个很大的错误对于要取得任何的ORM(对象关系映射)技术的成功和数据库管理员保持一个良好的工作关系是至关重要的有如下两个原因
单独数据库管理员虽然不能使Hibernate项目成功但是他们通常可以让这些项目失败
数据库管理员对数据库本身具有很好的洞察力很好的职业习惯告诉你一些易犯的错误和操作建议我能记起这样的很多例子一个数据库管理员的建议节约了我们很多的时间和提供给我们一个很好的解决方案
在大多数情况下拥有好的数据库管理员并且和他们保持良好的关系对你ORM(对象关系映射)工作至关重要
)从一开始使用(最好强制使用)好的命名标准
我们知道对命名标准的讨论将会有争议的但是我们必须明确一件事情我们的命名要让我们的数据模型有意义这能让开发者使用起来简单以免他们迷惑所以如何命名实体和属性是非常重要的我有我喜欢命名标准并且认为他们是最好的但是在这里我不想把他们强加于你们最重要的是你自己做出决定使用什么样的命名标准并且让所有人使用它实际上不仅仅命名标准需要统一其它的也需要(如布尔型用Y/N 或者 /表示)
)不要试着映射所有的属性
我们总是设法使用工具如Dali来映射所有的东西然后形成一张表格(一些表格有上百列 !)这最终会很麻烦为什么?因为我们使用的是共用的先前的数据库有许多的字段是我们并不关心和从来不使用的映射它们只会导致性能问题和造成混乱
)让数据库做自己擅长的工作
我们想有一个好的清晰的数据模型因此我们不惜任何代价写一些额外的查询语句来获取对象相关数据要么使用存储过程要么使用函数这是做法是错误的数据库优势在于存储而不是保持Hibernate创建或读写的数据举个例子我们有一个对象与之相关联的有一个状态这个状态在整个应用程序中都要用到因此它毫无疑问是要执行的但是我们不想每次都要单独的写一个查询语句这个问题在于这个状态是从一些统计计算中派生出来的并且这些统计计算需要用到一对多的关系每次从加载的对象中读取数据的代价是非常高的后来跟我们其中的一位数据库管理员交流了一下发现一个我们可以使用的sql函数能够很快的获得该状态我们使用@Formula来映射成一个状态属性就能得到我们所需要的所有东西这仍就是域模型的一部分但是执行起来非常好有时像这样的一个折衷的办法能够起到很大的效果
)分解数据库
在一开始我就想在Hibernate中模型化整个数据库结果发现这是不切实际的原因如下a)这是一项巨大的工程并且要花费几周的时间而用户根本看不到你做了什么实际的工作
b)我不可能在第一次就把它弄好后继的开发者无论如何都会修改它们的
现在有一个趋势就是希望在开始之前将所有的事情都进行映射但是当时你开始这么做后你不需在这上面花很多的时间我后来发现一个好的办法就是将数据库分解工作的时候一块一块的进行发现这很有帮助
)密切注意触发器
密切注意数据库触发器有如下两个原因
a)在后台触发器很隐蔽的执行了一些功能让你很是疑惑不知道发生了什么
b)当你在Hibernate端需要复制一些东西的时候触发器会做一些手脚之前我们好几次没有认识到这个教训导致我们丢失了很多数据这些都是由触发器引起的这几乎让我们很是郁闷
)避免使用工具来自动生成你的模型
没错这些工具的使用可以节约时间(虽然我们发现了Dali有一个很严重的bug但是我们还是使用它)但是最后你不得不重新做很多的事情其实手动也花费不了你很多的时间当你亲自做的时候这可以让你有机会熟悉那些数据
) 尽量多的使用命名查询语句(NamedQueries)
虽然很容易写查询语句但是在许多的情况下使用NamedQueries会更好这会有助于你完成两件事情
a)它能更加重用因为被命名的查询语句通常在代码的重要地方
b)你的查询语句在开始的时候就是正确的那么在查询语句中的错误更加容易发现
要习惯这样做需要花一些时间但是这么做是值得的
)预期管理
对于任何一种框架技术甚至观念来说这是非常重要的要铭记在心由于某些原因人们倾向于专注某一个特征这些特征实际上或许不存在或许被夸大有时它很小很容易理解(举个例子理解一些实际的工作需要在Hibernate中映射)有时我也不知道他们是如何管理实现一些概念(如Hibernate是如何管理计划修正的)无论如何找到预期目标是什么然后管理它们是非常重要的如果你的团队认为Hibernate会使得数据库管理员没有用处把他们解雇那么你将会有一个潜在的问题存在
)使用富域模型(rich domain modeling)
我所遇到的一件很悲哀的事情就是在域对象仅仅是一个简单的数据容器的时候我要使用Hibernate而像Hibernate这样的工具让我们以面向对象的方式来使用数据简单的映射数据只是让我们停留在中途当我本能的想到使用富域模型(rich domain modeling)的时候我发现我们可以重用很多的代码我们的其它层变得不那么混乱了并且我们的代码更加容易测试