现在的位置: 首页 > 综合 > 正文

Hibernate 与 JDBC 性能测试

2011年11月02日 ⁄ 综合 ⁄ 共 11237字 ⁄ 字号 评论关闭

数据库持久层性能测试报告

1.    前言

本测试目的在于对比Hibernate数据库框架和传统的JDBC框架之间性能差异,并从性能方面证明在高性能、复杂系统开发中,传统JDBC框架比hibernate更具备优势。

2.    测试环境

Pentium® Dual-Core CPU E5300 @ 2.60GHz

2.59GHz, 2.00 GB内存

GhostXP_SP2电脑公司特别版 版本: 8.0

300G 硬盘

 

MySQL Ver 14.14 Distrib 5.1.48, for Win32 <ia32>

MyEclipse 6.6.0 Build id: 6.0.0-20081015

 

Java build 1.5.0_11-b03, mixed mode

Mysql-connector-java-5.1.13-bin.jar

 

3.    测试概述

Hibernate:

Hibernate是一个免费的开源Java包,它使得与关系数据库打交道变得十分轻松,就像您的数据库中包含每天使用的普通Java对象一样,同时不必考虑如何把它们从神秘的数据库表中取出(或放回到数据库表中)。

 

JDBCPure JDBC

JDBC 为工具/数据库开发人员提供了一个标准的 API,使他们能够用纯Java API 来编写数据库应用程序。

 

封装的JDBC框架(JDBC Framework

Java提供的JDBC基础上进一步封装,对数据库表结构进行通用建模,并提供了连接池设计;方便了SQL拼接、数据表的增删改查。

 

多线程操作(MULTI THREAD

建立多条线程同时对数据库操作

 

批量操作(BATCH)

开启数据库的事务功能,批量写入、更新操作数据库。仅针对数据库的更新、插入操作。

 

自增主键

使用数据库管理主键值自增。

 

自定义主键:

使用java提供的UUID自定义表的主键值。

 

测试对象包括:

Hibernate

JDBC

封装的JDBC框架

 

其他测试说明:

除查询,其他测试每次测试前,首先清空数据库,在零数据量的条件下进行测试。

不同测试项目在不同的java进程中执行,而不会在相同进程中执行,防止相互影响。

 


 

4.    测试内容

4.1   测试表结构设计

自增主键表结构:

Table      Create Table                                

--------- ---------------------------------------------

tc_autopk CREATE TABLE `tc_autopk` (                  

             `COL_PK` char(36) NOT NULL,               

             `COL_VARCHAR1` varchar(255) DEFAULT NULL, 

             `COL_VARCHAR2` varchar(255) DEFAULT NULL, 

             `COL_VARCHAR3` varchar(255) DEFAULT NULL, 

             `COL_VARCHAR4` varchar(255) DEFAULT NULL, 

             `COL_DATETIME1` datetime DEFAULT NULL,    

             `COL_DATETIME2` datetime DEFAULT NULL,    

             `COL_INT1` int(11) DEFAULT NULL,          

             `COL_INT2` int(11) DEFAULT NULL,          

             `COL_DOUBLE1` double DEFAULT NULL,        

             `COL_DOUBLE2` double DEFAULT NULL,        

             `COL_BLOB` blob,                          

             `COL_INDEX` varchar(255) DEFAULT NULL,    

             PRIMARY KEY (`COL_PK`),                   

             KEY `NewIndex1` (`COL_INDEX`)              

           ) ENGINE=InnoDB DEFAULT CHARSET=utf8   

 

自定义主键表结构:

Table        Create Table                                

----------- ---------------------------------------------

tc_manualpk CREATE TABLE `tc_manualpk` (                

               `COL_PK` int(11) NOT NULL AUTO_INCREMENT, 

               `COL_VARCHAR1` varchar(255) DEFAULT NULL, 

               `COL_VARCHAR2` varchar(255) DEFAULT NULL, 

               `COL_VARCHAR3` varchar(255) DEFAULT NULL, 

               `COL_VARCHAR4` varchar(255) DEFAULT NULL, 

               `COL_DATETIME1` datetime DEFAULT NULL,    

               `COL_DATETIME2` datetime DEFAULT NULL,    

               `COL_INT1` int(11) DEFAULT NULL,          

               `COL_INT2` int(11) DEFAULT NULL,          

               `COL_DOUBLE1` double DEFAULT NULL,        

               `COL_DOUBLE2` double DEFAULT NULL,        

               `COL_BLOB` blob,                          

               `COL_INDEX` varchar(255) DEFAULT NULL,    

               PRIMARY KEY (`COL_PK`),                   

               KEY `NewIndex1` (`COL_INDEX`)             

             ) ENGINE=InnoDB DEFAULT CHARSET=utf8       

 

外键表结构:

Table                 Create Table                                                                                                

-------------------- ------------------------------------------------------------------------------------------------------------

tc_manual_foreignkey CREATE TABLE `tc_manual_foreignkey` (                                                                       

                        `COL_PK` char(36) NOT NULL,                                                                              

                        `COL_VARCHAR1` varchar(255) DEFAULT NULL,                                                                

                        `COL_VARCHAR2` varchar(255) DEFAULT NULL,                                                                

                        `COL_VARCHAR3` varchar(255) DEFAULT NULL,                                                                

                        `COL_VARCHAR4` varchar(255) DEFAULT NULL,                                                                 

                        `COL_DATETIME1` datetime DEFAULT NULL,                                                                   

                        `COL_DATETIME2` datetime DEFAULT NULL,                                                                    

                        `COL_INT1` int(11) DEFAULT NULL,                                                                         

                        `COL_INT2` int(11) DEFAULT NULL,                                                                          

                        `COL_DOUBLE1` double DEFAULT NULL,                                                                       

                        `COL_DOUBLE2` double DEFAULT NULL,                                                                        

                        `COL_BLOB` blob,                                                                                         

                        `COL_FK_TO_INDEX` varchar(255) DEFAULT NULL,                                                              

                        `COL_FK_TO_NONINDEX` varchar(255) DEFAULT NULL,                                                          

                        PRIMARY KEY (`COL_PK`),                                                                                   

                        KEY `FK_tc_auto_foreignkey2` (`COL_FK_TO_INDEX`),                                                        

                        CONSTRAINT `FK_tc_manual_foreignkey` FOREIGN KEY (`COL_FK_TO_INDEX`) REFERENCES `tc_manualpk` (`COL_PK`) 

                      ) ENGINE=InnoDB DEFAULT CHARSET=utf8

 

4.2   单表插入测试

 

自定义主键插入测试

数据压力(条)

Hibernate

Pure JDBC

JDBC Framework BATCH

100

1742.2

1698.4

53.4

300

5065.6

5092.2

107.6

500

8487.5

8450

145.5

1000

17131.3

17132.8

233

时间:毫秒

 

自增主键插入测试

数据压力(条)

Hibernate

Pure JDBC

JDBC Framework BATCH

100

1734.4

1767.2

59.4

300

5034.4

5061

90.6

500

8556.3

8454.7

139.1

1000

16896.8

17278.2

257.7

时间:毫秒

 

4.3   单表更新测试

说明:

表更新仅对一条记录进行更新,查看性能。

循环次数为1000次。

 

单表更新测试

更新条目数

Hibernate

JDBC Framework

JDBC Framework BATCH

1000

17356.2

17128.2

315.6

时间:毫秒

 

4.4   单表查询测试

测试说明:

数据库初始化数据量=1000条数据

除主键查询外,其余查询返回记录量 等于 数据库初始化的数据量(即等于全查询)

主键查询:指定主键值查询(WHERE PK = :PK

字段查询:指定非索引字段值,使用等号查询(WHERE COLUMN = :COLUMN

范围查询:指定非索引字段值,使用大于号、小于号查询(WHERE DATETIME > :DATETIME)

 

单表查询测试

查询策略

Hibernate

JDBC

JDBC Framework

JDBC Framework MULTI THREAD

主键查询

153

437.6

71.8

78.2

字段查询

6478.2

4903

4484.2

2772

范围查询

6384.4

4843.8

4412.8

2381

时间:毫秒

 

4.5   自定义连表查询测试

测试说明:

hibernate使用HQL操作连接表查询

select tcManualForeignkey from TcManualForeignkey tcManualForeignkey,TcManualpk tcManualpk where tcManualpk.colPk = tcManualForeignkey.colFkToNonindex

 

JDBC使用inner join操作连接表查询

SELECT TC_MANUAL_FOREIGNKEY.* FROM TC_MANUAL_FOREIGNKEY INNER JOIN TC_MANUALPK ON TC_MANUAL_FOREIGNKEY.COL_FK_TO_NONINDEX = TC_MANUALPK.COL_PK

 

多表查询测试

查询次数

Hibernate

JDBC

JDBC Framework

100

6378.2

5375

446.8

时间:毫秒

5.    附录

5.1   Hibernate代码概述

测试代码使用Hibernate + Spring的架构。要点包括:

数据库设计完毕后,使用MyEclipseDBBrowser自动生成Hibernatexml配置文件和实体类

配置Hibernate-daos.xml,让spring加载hibernate

使用继承了HibernateDaoSupport实现对实体类的增删改查操作。

Spring关于hibernate配置如下,具体请看测试代码:

<?xml version="1.0" encoding="utf-8"?>

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd             http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd             http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">

 <bean id="SpringContextUtil" class="com.xtar.common.tool.SpringContextUtil" scope="singleton" lazy-init="false" />

 <!--start 数据库配置 -->

 <bean id="dataSource" class="org.logicalcobwebs.proxool.ProxoolDataSource">

    <property name="driver">

      <value>com.mysql.jdbc.Driver</value>

    </property>

    <property name="driverUrl">

     <value>jdbc:mysql://${baseService.database.ip}:${baseService.database.port}/${baseService.database.instance}?useUnicode=true&amp;characterEncoding=utf-8</value>

    </property>

    <property name="user">

      <value>${baseService.database.username}</value>

    </property>

    <property name="password">

      <value>${baseService.database.password}</value>

    </property>

    <property name="alias">

      <value>spring</value>

    </property>

    <property name="prototypeCount">

      <value>5</value>

    </property>

    <property name="minimumConnectionCount">

      <value>5</value>

    </property>

    <property name="maximumConnectionCount">

      <value>10</value>

    </property>

    <property name="maximumActiveTime">

      <value>60000</value>

    </property>

    <property name="houseKeepingTestSql">

      <value>select 1</value>

    </property>

    <property name="houseKeepingSleepTime">

      <value>60000</value>

    </property>

    <property name="simultaneousBuildThrottle">

      <value>100</value>

    </property>

 </bean>

 <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">

    <property name="dataSource" ref="dataSource" />

    <property name="mappingResources">

      <list>

        <value>com/xtar/biz/domain/CityBuilding.hbm.xml</value>

        <value>com/xtar/biz/domain/CityBuildingSetting.hbm.xml</value>

        <value>com/xtar/biz/domain/MysqlAutopk.hbm.xml</value>

        <value>com/xtar/biz/domain/MysqlBinarytype.hbm.xml</value>

        <value>com/xtar/biz/domain/MysqlBlobtype.hbm.xml</value>

        <value>com/xtar/biz/domain/MysqlDatetype.hbm.xml</value>

        <value>com/xtar/biz/domain/MysqlPrimarykey.hbm.xml</value>

        <value>com/xtar/biz/domain/MysqlSchema.hbm.xml</value>

        <value>com/xtar/biz/domain/MysqlValuetype.hbm.xml</value>

        <value>com/xtar/biz/domain/UsrBuilding.hbm.xml</value>

        <value>com/xtar/biz/domain/UsrBuildingStatus.hbm.xml</value>

        <value>com/xtar/biz/domain/UsrProfile.hbm.xml</value>

        <value>com/xtar/biz/domain/UsrQueue.hbm.xml</value>

        <value>com/xtar/biz/domain/UsrTrigger.hbm.xml</value>

        <value>com/xtar/biz/domain/VipSetting.hbm.xml</value>

      </list>

    </property>

    <property name="hibernateProperties">

      <props>

        <!--设置数据库方言(不同的数据库不一样) -->

        <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>

        <!--是否在(控制台)显示SQL语句(可以查看hibernate生成的sql) -->

        <prop key="hibernate.show_sql">false</prop>

        <!--hibernate的统计信息-->

        <prop key="hibernate.generate_statistics">false</prop>

        <!--

        JDBC Statement一次提取的记录数量(貌似hibernate不支持)

        <prop key="hibernate.jdbc.fetch_size">50</prop>

         批量insert、update、delete时的批量大小

        <prop key="hibernate.jdbc.batch_size">50</prop>

         -->

        <prop key="hibernate.jdbc.use_streams_for_binary">true</prop>

        <prop key="hibernate.max_fetch_depth">1</prop>

        <prop key="hibernate.cache.use_query_cache">true</prop>

        <prop key="hibernate.cache.use_second_level_cache">true</prop>

        <prop key="hibernate.cache.provider_class">net.sf.ehcache.hibernate.EhCacheProvider</prop>

        <prop key="net.sf.ehcache.configurationResourceName">classpath:ehcache.xml</prop>

        <prop key="hibernate.cglib.use_reflection_optimizer">false</prop>

      </props>

    </property>

 </bean>

 <!--end 数据库配置 -->

</beans>

 

5.2   封装JDBC代码设计概述

封装的jDBC框架仅仅在SQL拼接方面提高编程效率,其余的直接使用原始JDBC类,要点包括:

使用自定义的数据结构DataTable映射数据库实体(本质是键值对,映射数据库字段和值关系)。

操作过程根据DataTable的结构自动生成对应的SQL

默认自动更新的SQL是在当前表主键的条件下对所有字段进行更新。

默认自动删除的SQL是在当前表主键的条件下删除数据。

内置了数据连接池,对事务链接和普通链接区分对待。

【上篇】
【下篇】

抱歉!评论已关闭.