最近测试发现个IBatis 有个比较严重的性能问题, 描述如下:
1. define a bean class
public class Bean {
private int id;
private String desc;
private long price;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public long getPrice() {
return price;
}
public void setPrice(long price) {
this.price = price;
}
}2. 如果在这个Bean定义中,存在一个属性没有 Getter方法 在运行过程中, IBatis 会表现为把 class Bean 确定成一个ComplexAccessPlan的对象。那么, IBatis对Bean对象填充SQL执行后的返回结果会造成比较严重的性能问题。 复杂对象填充Bean的结果在性能上表现比较差一点。 这个性能差异随着需要设置属性数量的增加, 性能成正比的下降。 目前我测试的结果是10个属性情况下影响大约 5-6%的执行时间, 如果属性增加到 84个(中文站的offer对象),他的性能会导致超过30%的下降。 具体的原因, 我会如下解释:
com.ibatis.sqlmap.engine.accessplan.AccessPlanFactory Line 60
if (bytecodeEnhancementEnabled) {
try {
plan = new EnhancedPropertyAccessPlan(clazz, propertyNames);
} catch (Throwable t) {
try {
plan = new PropertyAccessPlan(clazz, propertyNames);
} catch (Throwable t2) {
plan = new ComplexAccessPlan(clazz, propertyNames);
}
}
}
com.ibatis.common.beans.ClassInfo Line256
public Method getGetter(String propertyName) {
Method method = (Method) getMethods.get(propertyName);
if (method == null) {
throw new ProbeException("There is no READABLE property named '" + propertyName + "' in class '" + className + "'");
}
return method;
}class EnhancedPropertyAccessPlan/PropertyAccessPlan call com.ibatis.common.beans.ClassInfo.getGetter(String) that cause an exception when a bean have no Getter method, AccessPlan object choose ComplexAccessPlan.
3. 根据以上的代码, 我们还可以得出如下结论(这是我给IBATIS开发团队的邮件部分, 不翻译:)):
IBtatis automatic decide a simple bean that property have no Getter method to be Complex type. IBatis does not prompt any warning enhancementEnable option will be skipped. I think these ibatis exception handling is not smooth. and If user's bean loose some Getter method, a common user does not know why ibatis performance become bad.
就是一个对象由于Getter方法的缺失, IBatis把这个对象的当做复杂对象, 从而, 导致enhancementEnable=true(bean对象字节增加功能, 有兴趣的同学可以看看CGLIB中BulkBean的使用)的定义失去了任何作用, 进一步导致IBATIS的性能下降。
针对我们发现的问题, 我们建议如下解决问题:
1. 任何被IBatis 使用的对象属性必须定义完整的Setter/Getter方法
2. 避免使用自定义类型的对象属性
3. 如果部分属性需要被适当处理后才能使用的, 比如表中有一个字段price, 但是我们需要使用的是Money对象, 请按如下方式使用。primitivePrice作为数据库使用的属性, price作为应用程序使用的属性。
public class Bean {
private Money price = null;
private long primitivePrice;
public Money getPrice() {
if (price == null) {
this.price = new Money(0, 0);
this.price.setCent(primitivePrice);
}
return price;
}
public void setPrice(Money price) {
if (price == null) {
this.price = new Money(0, 0);
} else {
this.price = price;
}
this.primitivePrice = price.getCent();
}
public void setPrimitivePrice(long price) {
this.primitivePrice = price;
}
public long getPrimitivePrice() {
return this.primitivePrice ;
}
}
分享到:
相关推荐
8. **性能优化**:提供一些关于提高iBATIS性能的建议,如合理设计SQL、使用批处理等。 《ibatis.pdf》可能是iBATIS的官方文档或综合指南,可能包含更广泛的内容,如最佳实践、高级特性、与其他框架的集成等。 ...
Struts2是Apache软件基金会的开源项目,它是Struts1的升级版,提供更强大的功能和更好的性能。Struts2的核心是Action类,它接收HTTP请求并调用业务逻辑,然后将结果传递给视图进行展示。Struts2通过Interceptor...
在iBATIS DAO 2中,引入了动态SQL的概念,这使得SQL语句可以根据不同的条件动态生成,增加了代码的灵活性。例如,`DynamicSqlMapClient`类支持动态SQL Map的执行,它可以根据传入的参数动态修改SQL语句,避免了大量...
深入研究这些源代码,我们可以了解到iBatis如何处理SQL映射文件、动态SQL、事务管理、结果映射等功能的具体实现,这对于定制化开发或优化性能具有极大的价值。 "doc"目录则提供了相关的文档资料,包括API参考、用户...
6. **性能优化**: - 减少网络传输开销,尽可能减少与数据库服务器之间的交互次数。 - 合理设置批处理的大小,过大过小都会影响性能。 - 对于非常大的数据集,考虑分批次进行批量更新。 通过上述步骤,我们可以...
8. **最佳实践**:文档通常会包含一些使用iBATIS的最佳实践,比如如何设计映射文件、优化SQL性能、避免内存泄漏等。 9. **与其他框架的集成**:iBATIS可以与Spring、Struts等框架无缝集成,文档会说明如何在这些...
3. 细粒度优化:iBATIS允许开发者进行更细致的SQL优化,例如针对特定场景编写高效的更新或查询语句。 4. 维护性:由于iBATIS的SQL存储在独立的XML文件中,相较于Hibernate在Java代码中混合SQL的情况,其可维护性更好...
然而,这提供了更大的灵活性,特别是对于复杂或特定性能优化的SQL。 2. 细粒度优化:iBATIS允许对SQL进行更细致的优化,如直接指定更新单个字段的语句,或选择性地获取表的部分内容。 3. 可维护性:由于SQL保存在...
7. 执行性能:提供优化建议,如批处理、缓存使用等,以提升应用程序的运行效率。 总之,Ibatis是一个强大且灵活的Java持久层框架,其API、文档和说明文档为开发者提供了全面的工具和指导,帮助他们高效地进行数据库...
总结来说,iBATIS3提供了更高的开发效率和易用性,而JDBC则在性能优化和灵活性上有优势。选择哪个取决于项目需求,例如,对于快速开发和维护的小型项目,iBATIS3可能是更好的选择;而对于性能要求极高,且需要深度...
2. **性能优化**:对于频繁执行的 SQL 语句,可以考虑缓存 SQL 语句或者使用其他性能优化措施。 3. **异常处理**:增加异常处理机制,确保程序的健壮性。 4. **代码复用**:封装常用的 SQL 动态构建逻辑,减少重复...
总的来说,"ibatis_with_memcached"项目提供了一个实用的参考,展示了如何在实际开发中利用Ibatis与Memcached集成来优化数据访问,对于提升Java Web应用的性能具有很大的指导价值。开发者可以通过该项目学习到缓存...
- **性能优化与缓存**:了解如何利用iBATIS的缓存机制来提高应用性能,减少数据库访问次数。 - **数据访问对象(DAO)模式**:深入研究iBATIS如何支持DAO模式,简化数据访问逻辑,实现业务逻辑与数据访问的分离。 - ...
- **复杂查询**:面对复杂的SQL查询或需要手动优化的情况,ibatis的灵活性使其成为理想的选择。 - **性能敏感的应用**:在某些高性能要求的应用场景下,ibatis的高效性得到了很好的体现。 通过上述知识点的介绍,...
通过《ibatis-sqlmaps-2_cn》,你不仅可以学习到如何使用IBATIS进行数据库操作,还能了解如何优化和调试IBATIS相关的代码,从而提高开发效率。对于初学者,这是一份非常实用的学习资料;对于有经验的开发者,它可以...
同时,这份教程可能还涵盖了异常处理、事务管理以及性能优化等相关内容。 **iBATIS存储过程调用** 在iBATIS中调用存储过程通常涉及以下几个步骤: 1. **配置存储过程**:在SQL映射文件中定义存储过程的标签,指定...
总的来说,Ibatis 2.3.4的实例和jar包为你提供了一个学习和实践的平台,通过深入理解Ibatis的核心机制,你可以更好地设计和优化你的数据访问层,提升项目性能。在实践中不断探索,你会发现Ibatis是一个强大且灵活的...
**八、性能优化** 通过合理的缓存策略、批处理和预编译SQL等手段,IBatis可以在不影响灵活性的同时提供良好的性能。 总结,IBatis .NET为.NET开发者提供了一种直观、灵活的方式来处理数据库操作。通过学习这个实例...
2. **优化性能**:通过源码,可以找出可能的性能瓶颈,并针对性地进行优化。 3. **定制化开发**:对于有特殊需求的项目,可以直接在源码基础上进行二次开发,添加自定义功能。 4. **提升技能**:深入源码有助于...
12. **最佳实践**:提供iBatis在实际项目中的应用建议,包括代码组织结构、性能优化、异常处理等方面。 13. **案例分析**:通过实际案例展示iBatis在不同场景下的应用,如CRUD操作、复杂查询、批量处理等。 14. **...