前言由于编程思想和数据库设计模式的不同,诞生了一些ORM框架。核心是将关系数据库和数据转换为对象类型。目前流行的解决方案包括Hibernate和myBatis。两者各有利弊。竞争是激烈的,更重要的考虑因素之一是性能。因此,笔者通过各种实验,在同一场景下测得了两个性能相关的指标,供大家参考。测试目标下面的测试需要确定几个点:有性能差异的场景;不同场景下的性能差异;找出各个框架的优缺点,各种情况下的表现,以及适用场景。测试思路整体测试分为:单表插入、关联插入、单表查询、多表查询。测试分为两轮,一轮同场景默认参数,一轮调优强化,横向纵向对比分析。测试时保证输入输出的一致性。样本量应尽可能大,在100,000个级别以上,以减少统计误差。在测试大纲的具体场景中插入测试1:插入10万条记录。查询测试一:100万条数据,单表通过id查询10万次,没有关联字段。查询测试2:100万条数据,单表通过id查询10万次,输出关联的object字段。查询测试3:在100万*50万条关联数据中查询10万次,都输出相同的字段。准备数据库:mysql5.6表设计:twitter:twitterCREATETABLE`twitter`(`id`bigint(20)NOTNULLAUTO_INCREMENT,`add_date`datetimeDEFAULTNULL,`modify_date`datetimeDEFAULTNULL,`ctx`varchar(255)NOTNULL,`add_user_id`bigint(20)DEFAULTNULL,`modify_user_id`bigint(20)DEFAULTNULL,PRIMARYKEY(`id`),KEY`UPDATE_USER_FORI`(`modify_user_id`),KEY`ADD_USER_FORI`(`add_user_id`),CONSTRAINT`ADD_USER_FORI`FOREIGNKEY(`add_user_id`)REFERENCES`user`(`id`)ONDELETESETNULL,CONSTRAINT`UPDATE_USER_FORI`FOREIGNKEY(`modify_user_id`)REFERENCES`user`(`id`)ONDELETESETNULL)ENGINE=InnoDBAUTO_INCREMENT=1048561DEFAULTCHARSET=utf8user:UserCREATETABLE`bigint`(`id`(20)NOTNULLAUTO_INCREMENT,`name`varchar(255)DEFAULTNULL,PRIMARYKEY(`id`))ENGINE=InnoDBAUTO_INCREMENT=524281DEFAULTCHARSET=utf8测试数据准备:表1:twitter没有数据。表2:user500,000个随机用户名。随机内容推特表(material_twitter)没有id,只有随机字符串内容,共10万条。用于插入到twitter表中。生成数据代码,关联100个用户:insertintotwitter(ctx,add_user_id,modify_user_id,add_date,modify_date)SELECTname,ROUND(RAND()*100)+1,ROUND(RAND()*100)+1,'2016-12-31','2016-12-31'来自MATERIAL生成数据代码,关联500000个用户:insertintotwitter(ctx,add_user_id,modify_user_id,add_date,modify_date)SELECTname,ROUND(RAND()*500000)+1,ROUND(RAND()*500000)+1,'2016-12-31','2016-12-31'fromMATERIAL实体代码@Entity@Table(name="twitter")publicclassTwitterimplementsjava.io.Serializable{privateLongid;privateDateadd_date;privateDatemodify_date;privateStringctx;privateUseradd_user;privateUsermodify_user;privateStringcreateUserName;@Id@GeneratedValue(strategy=IDENTITY)@Column(name="id",unique=true,nullable=false)publicLonggetId(){returnid;}publicvoidsetId(Longid){this.id=id;}@Temporal(TemporalType.DATE)@Column(name="add_date")publicDategetAddDate(){returnadd_date;}publicvoidsetAddDate(Dateadd_date){this.add_date=add_date;}@Temporal(TemporalType.DATE)@Column(name="modify_date")publicDategetModifyDate(){returnmodify_date;}publicvoidsetModifyDate(Datemodify_date){this.modify_date=modify_date;}@Column(name="ctx")publicStringgetCtx(){returnctx;}publicvoidsetCtx(Stringctx){this.ctx=ctx;@ManyToOne(fetch=FetchType.LAZY)@JoinColumn(name="add_user_id")publicUsergetAddUser(){returnadd_user;}publicvoidsetAddUser(Useradd_user){this.add_user=add_user;}@ManyToOne(fetch=FetchType.LAZY)@JoinColumn(name="modify_user_id")publicUsergetModifyUser(){returnmodify_user;}publicvoidsetModifyUser(Usermodify_user){this.modify_user=modify_user;}@TransientpublicStringgetCreateUserName(){returncreateUserName;}publicvoidsetCreateUserName(StringcreateUserName){this.createUserName=createUserName;}}开始插入测试1代码操作:将随机内容推特表的数据加载到内存中,然后对推特表逐一添加,共100000条关键代码:hibernate:Sessionsession=factory.openSession();session.beginTransaction();Twitter=null;Datenow=newDate();for(StringmaterialTwitter:materialTwitters){//System.out.println("materialTwitter="+materialTwitter);t=newTwitter();t.setCtx(materialTwitter);t.setAddDate(现在);t.setModifyDate(现在);t.setAddUser(null);t.setModifyUser(null);session.save(t);}session.getTransaction().commit();mybatis:Twitter=null;Datenow=newDate();for(StringmaterialTwitter:materialTwitters){//System.out.println("materialTwitter="+materialTwitter);t=newTwitter();t.setCtx(materialTwitter);t.setAddDate(now);t.setModifyDate(now);t.setAddUser(null);t.setModifyUser(null);msession.insert("insertTwitter",t);}msession.commit();TwitterMapper.xml,插入代码片段:
