从手写的持久层迁移到ORM

Ser*_*nov 9 java sql database performance orm

我们目前正在评估从手写持久层迁移到ORM的选项.

我们有一堆遗留持久对象(~200),它实现了这样的简单接口:

interface JDBC {
    public long getId();
    public void setId(long id);
    public void retrieve();
    public void setDataSource(DataSource ds);
}
Run Code Online (Sandbox Code Playgroud)

retrieve()被调用时,对象通过发出手写SQL查询来提供的连接使用它在设定器接收到的ID(这通常是对查询的唯一参数)填充本身.它管理自己的语句,结果集等.某些对象具有特殊的retrive()方法,例如retrieveByName(),在这种情况下会发出不同的SQL.

查询可能非常复杂,我们经常连接几个表来填充表示与其他对象的关系的集合,有时连接查询是在特定的getter(延迟加载)中按需发出的.基本上,我们手动实现了大部分ORM的功能.

原因就是表现.我们对速度有很强的要求,早在2005年(编写此代码时)性能测试表明,主流ORM都没有像手写SQL一样快.

我们现在面临的让我们想到ORM的问题是:

  • 此代码中的大多数路径都经过了充分测试并且稳定.但是,一些很少使用的代码很容易出现结果集和连接泄漏,而这些泄漏很难检测到
  • 我们正在通过向持久层添加缓存来挤压一些额外的性能,并且在此设置中手动维护缓存对象是一个巨大的痛苦
  • 数据库架构更改时支持此代码是一个大问题.

我正在寻找有关什么可能是我们最好的选择的建议.据我所知,ORMs在过去5年中已经取得了进展,所以可能现在有一个提供可接受性能的ORM.在我看到这个问题时,我们需要解决这些问题:

  • 找到一种方法来重用至少一些书面SQL来表达映射
  • 有可能发出本机SQL查询而无需手动分解其结果(即避免手动,rs.getInt(42)因为它们对模式更改非常敏感)
  • 添加非侵入式缓存层
  • 保持性能数据.

你有没有可以推荐的ORM框架?

更新要了解我们正在谈论的性能数据:

  • 后端数据库是TimesTen,内存数据库,与JVM在同一台机器上运行
  • 我们发现,改变rs.getInt("column1")rs.getInt(42)带来我们认为重要的性能提升.

Bar*_*ett 5

如果需要允许发出本机SQL查询的标准持久层,请考虑使用iBATIS.它是您的对象和SQL之间相当薄的映射.http://ibatis.apache.org/

对于缓存和延迟连接,Hibernate可能是更好的选择.我没有将iBATIS用于这些目的.

Hibernate提供了很大的灵活性,允许您在遍历对象图时指定延迟加载的某些默认值,还可以在需要更好的已知加载时间时使用SQL或HQL查询预先获取数据到您的内容.但是,转换工作对您来说会很复杂,因为它在学习和配置方面具有相当高的入门条件.注释使我更容易.

您没有提到关于切换到标准框架的两个好处:(1)当您拥有大量站点和论坛来支持您时,减少错误变得更容易.(2)新员工更便宜,更容易,更快捷.

祝您解决性能和可用性问题.你指出的权衡是非常普遍的.对不起,如果我传福音.


kel*_*yfj 2

你真的需要迁移吗?是什么迫使你搬家?这里是否有真正的需要,或者有人只是在发明工作(“宇航员建筑师”)?

不过,我同意上面的答案 - 如果你必须搬家 - Hibernate 或 iBatis 是不错的选择。iBatis 特别是如果您想“更接近”SQL。

  • 我认为切换到 ORM 来获得性能提升是一种有很多风险的策略 - 即使你通过缓存获得了一些东西,诸如急切/延迟加载之类的东西以及 ORM 实现的变幻莫测可能会反过来咬你一口 -另外,ORM 可能无法提供最佳查询。我建议继续替换一些 JDBC DAO - 一些简单,一些复杂,看看它如何适合和有帮助。在解决所有 200 个问题之前先进行试点。 (3认同)