【发布时间】:2011-02-21 11:29:25
【问题描述】:
我们目前正在评估从手写持久层迁移到 ORM 的选项。
我们有一堆遗留的持久对象(约 200 个),它们实现了这样的简单接口:
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的问题是:
- 此代码中的大多数路径都经过充分测试并且很稳定。但是,一些很少使用的代码容易出现很难检测到的结果集和连接泄漏
- 我们目前正在通过向持久层添加缓存来提高性能,而在此设置中手动维护缓存对象是一个巨大的痛苦
- 在 DB 架构更改时支持此代码是一个大问题。
我正在寻找对我们来说可能是最佳替代方案的建议。据我所知,ORM 在过去 5 年中取得了进步,所以现在可能有一个可以提供可接受的性能。当我看到这个问题时,我们需要解决这些问题:
- 找到某种方法来重用至少部分编写的 SQL 来表达映射
- 无需手动分解结果即可发出原生 SQL 查询(即避免手动
rs.getInt(42),因为它们对架构更改非常敏感) - 添加非侵入式缓存层
- 保留性能数据。
您有什么可以推荐的 ORM 框架吗?
更新来感受一下我们在谈论什么样的性能数据:
- 后端数据库是 TimesTen,内存数据库,与 JVM 运行在同一台机器上
- 我们发现,将
rs.getInt("column1")更改为rs.getInt(42)会带来我们认为显着的性能提升。
【问题讨论】:
标签: java sql database performance orm