3.4.1性能优化

本文介绍了Hibernate性能优化的几个关键点,包括禁用自动表管理以提高启动性能,调整日志级别减少性能消耗,设置合适的JDBC批处理量,以及优化主键生成策略和关联映射以提升查询效率。

1、表结构管理

在Hibernate启动的时候,可以创建表、更新表结构。

在正式的生产环境,不要使用自动创建表、更新表,因为会导致启动性能下降、可能会引起数据库表结构混乱。

不要:<property name="hibernate.hbm2ddl.auto"value="update" />

改为:validate


2、 日志记录

在开发阶段,通常会使用DEBUG、TRACE这样日志输出更多的级别。

在大量的请求、访问的时候,会因为输出的信息太多,导致性能显著下级。所以在正式环境中,往往都是直接使用ERROR、WARN。

3、JDBC批处理量大小

如果需要批量插入、修改、删除等操作,合适的批处理大小,能够提高JDBC的性能。这个值不能固定的,不同的数据库环境、机器环境可能需要适当调整。

需要根据测试环境的结果,逐渐调整,通常在最开始的时候设置200~500之间。

<propertyname=”hibernate.jdbc.batch_size” value=”200”/>

4、映射

(1)主键

IDENTITY依赖数据库自动增长,主键的增长性能由数据库决定。这种是比较高性能的方式。

SEQUENCE 在Oracle的数据库里面,需要查询序列,才能得到下一个值。因为不需要修改序列,性能也是比较好,直接在数据库的内存里面获取下一个值。

TABLE 每当预分配的值已经用完,就需要update数据库表,产生数据的【行级锁】,在修改数据的时候,会锁定被修改的数据,直到提交事务。在三个主键生成器里面,性能最差。

UUID 完全由Java在内存里面生成的,不需要关心数据库,所以性能由应用服务器决定,并且不会对数据库造成压力。在分布式环境就选择UUID类似的;不是分布式环境往往选择IDENTITY。

(2)关联

在查询一个对象的时候,往往会有很多其他的对象关联。

如果都需要使用其他对象,那么一次性查询出来,效率最高(用EAGER);

如果只是需要其中的一部分数据,其他的关联数据用不上就造成损失(用LAZY)。

通常通过 @OneToOn、@OneToMany、@ManyToOne、@ManyToMany等注解,设置fetch属性,告诉JPA是否要一次性读取数据。

注意:双向关联,只能一EAGER,另外一端必须是LAZY

eg1:ArticleTypefetch=FetchType.LAZY的情况


public class Article{
……    
@ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="type_Code")
    private ArticleType type;
……
}
测试代码:
		// 多对一、一对一的时候,默认为EAGER
		// 如果是双向关联:只能一边有EAGER
		Article a = super.entityManager.find(Article.class, 2L);
		// 当fetch为LAZY的时候,商品类型不会加载
		// 当实际使用到ArticleType时,才到数据库查询
		System.out.println("-----------------------------------------");
		ArticleType type = a.getType();// 依然没有查询数据库

结果:从debug的sql语句来看,只是查询了Article,没有去查询ArticleType

此时增加以下代码,打印出ArticleType

System.out.println(type);
结果:查询了ArticleType

eg2:集合默认是fetch=FetchType.LAZY


public class Order{
        ……
	//一对多,在1端维护
	@OneToMany(mappedBy="order",cascade=CascadeType.PERSIST)	
	//一个订单对应多个订单明细:一对多关系
	Set<OrderItem> orderItems;
        ……
 }
测试代码:
		
Order order = super.entityManager.find(Order.class, 796L);
System.out.println("---------------------");

测试结果:只是查询了Order的其他属性



此时增加以下代码,打印出OrderItem

System.out.println(order.getOrderItems());
结果:查询了OrderItem


(3) 继承

a.单表(SINGLE_TABLE)

性能最好,但是子类的列,不能设置【非空】。

b.共用属性在一个表、差异在子类表(JOINED)

性能略差,每当查询子类的对象,都需要join查询关联子表。

c.每个类一个表(TABLE_PER_CLASS)

在通过父类查询的时候,无法得到所有子类的记录。

只能通过子类进行查询。

适合数据量特别大的情况。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值