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

我们有一堆旧的持久性对象(约200个),它们实现了如下所示的简单接口(interface):

interface JDBC {
    public long getId();
    public void setId(long id);
    public void retrieve();
    public void setDataSource(DataSource ds);
}

调用retrieve()时,对象通过使用在setter中接收到的ID向提供的连接发出手写的SQL查询来填充自身(该参数通常是查询的唯一参数)。它自己管理其语句,结果集等。一些对象具有retrive()方法的特殊风格,例如retrieveByName(),在这种情况下,将发出不同的SQL。

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

这样做的原因是性能。我们对速度有非常严格的要求,而回溯到2005年(编写此代码时),性能测试表明,主流的ORM都没有像手写SQL那样快。

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

  • 我正在寻找对我们来说最好的替代方案的建议。据我所知,ORM在过去5年中已经取得了进步,所以现在可能有一种提供可接受的性能。在我看到此问题时,我们需要解决以下问题:
  • 找到某种方法来重用至少一些已编写的SQL来表达映射
  • 可以发出 native SQL查询,而无需手动分解其结果(即避免使用手动rs.getInt(42),因为它们对模式更改非常敏感)
  • 添加非侵入式缓存层
  • 保留性能数据。

  • 您是否可以就此建议任何ORM框架?

    更新来感受一下我们在谈论哪种性能指标:
  • 后端数据库是TimesTen内存数据库,它与JVM
  • 在同一台计算机上运行
  • 我们发现将rs.getInt("column1")更改为rs.getInt(42)会带来我们认为显着的性能提升。
  • 最佳答案

    您真的需要迁移吗?是什么迫使您移动?这里是否有真正的需求,或者只是有人发明了作品(“宇航员建筑师”)?

    不过,我同意上述答案-如果您必须搬家-Hibernate或iBatis是不错的选择。 iBatis尤其是如果您想与SQL保持“紧密联系”。

    09-11 19:17
    查看更多