Mybatis vs hibernate, which performance is better?

Java technology stack 2021-09-15 10:02:26
mybatis vs hibernate performance better


author : Zheng muxing <br> source :https://zhuanlan.zhihu.com/p/21966051

Preface

Because the programming idea is different from the database design pattern , Some of them have been born ORM frame .

The core is to transform relational database and data into object type . The current popular solutions are Hibernate And myBatis.

Both have advantages and disadvantages . Competition is fierce , One of the more important considerations is performance .

So the author through various experiments , Two performance related indices under the same scenario are measured , For your reference .

Friendship tips : If you think the article is too long , You can pull to the end of the text to see the conclusion .

Test target

The following test needs to determine a few points :

Performance difference scenarios ;

Performance is not different in the same scenario ;

Find out the advantages and disadvantages of each frame , Performance in various situations , Applicable scenario .

Test ideas

The test population is divided into : Single table insert , Association insertion , Single table query , Multi-table query .

There are two rounds of testing , Do one round with the default parameters in the scene , A round of tuning and strengthening , This paper makes a comparative analysis of .

Ensure the consistency of input and output in the test .

The sample size should be as large as possible , achieve 10 Above 10000 level , Reduce statistical error .

Test outline

In specific scenarios

Insert the test 1:10 Ten thousand records are inserted into .

Query test 1:100 In ten thousand data, the single table passes through id Inquire about 100000 Time , No associated fields .

Query test 2:100 In ten thousand data, the single table passes through id Inquire about 100000 Time , Output associated object field .

Query test 3:100 ten thousand *50 Million linked data query 100000 Time , Both output the same fields .

Get ready

database :mysql 5.6

Form design :

twitter: twitter

CREATE TABLE `twitter` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`add_date` datetime DEFAULT NULL,
`modify_date` datetime DEFAULT NULL,
`ctx` varchar(255) NOT NULL,
`add_user_id` bigint(20) DEFAULT NULL,
`modify_user_id` bigint(20) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `UPDATE_USER_FORI` (`modify_user_id`),
KEY `ADD_USER_FORI` (`add_user_id`),
CONSTRAINT `ADD_USER_FORI` FOREIGN KEY (`add_user_id`) REFERENCES `user` (`id`) ON DELETE SET NULL,
CONSTRAINT `UPDATE_USER_FORI` FOREIGN KEY (`modify_user_id`) REFERENCES `user` (`id`) ON DELETE SET NULL
) ENGINE=InnoDB AUTO_INCREMENT=1048561 DEFAULT CHARSET=utf8

user: user

CREATE TABLE `user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=524281 DEFAULT CHARSET=utf8

Test data preparation :

Table 1 :twitter

No data .

Table two :user

50 10000 random user names .

Random content tweets (material_twitter)

nothing id, Only random string content , common 10 Ten thousand .

Used to insert control tweet table .

Generate data code , relation 100 Users :

insert into twitter(ctx,add_user_id,modify_user_id,add_date,modify_date)
SELECT name,ROUND(RAND()*100)+1,ROUND(RAND()*100)+1,'2016-12-31','2016-12-31'
from MATERIAL

Generate data code , relation 500000 Users :

insert into twitter(ctx,add_user_id,modify_user_id,add_date,modify_date)
SELECT name,ROUND(RAND()*500000)+1,ROUND(RAND()*500000)+1,'2016-12-31','2016-12-31'
from MATERIAL

Entity code

@Entity
@Table(name = "twitter")
public class Twitter implements java.io.Serializable{
private Long id;
private Date add_date;
private Date modify_date;
private String ctx;
private User add_user;
private User modify_user;
private String createUserName;
@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name = "id", unique = true, nullable = false)
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
@Temporal(TemporalType.DATE)
@Column(name = "add_date")
public Date getAddDate() {
return add_date;
}
public void setAddDate(Date add_date) {
this.add_date = add_date;
}
@Temporal(TemporalType.DATE)
@Column(name = "modify_date")
public Date getModifyDate() {
return modify_date;
}
public void setModifyDate(Date modify_date) {
this.modify_date = modify_date;
}
@Column(name = "ctx")
public String getCtx() {
return ctx;
}
public void setCtx(String ctx) {
this.ctx = ctx;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "add_user_id")
public User getAddUser() {
return add_user;
}
public void setAddUser(User add_user) {
this.add_user = add_user;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "modify_user_id")
public User getModifyUser() {
return modify_user;
}
public void setModifyUser(User modify_user) {
this.modify_user = modify_user;
}
@Transient
public String getCreateUserName() {
return createUserName;
}
public void setCreateUserName(String createUserName) {
this.createUserName = createUserName;
}
}

Start

Insert the test 1

Code operation :

Load random content twitter table data into memory , And then, one by one, they add to the twitter list , common 10 Ten thousand .

Key code :

hibernate:

Session session = factory.openSession();
session.beginTransaction();
Twitter t = null;
Date now = new Date();
for(String materialTwitter : materialTwitters){
// System.out.println("materialTwitter="+materialTwitter);
t = new Twitter();
t.setCtx(materialTwitter);
t.setAddDate(now);
t.setModifyDate(now);
t.setAddUser(null);
t.setModifyUser(null);
session.save(t);
}
session.getTransaction().commit();

mybatis:

Twitter t = null;
Date now = new Date();
for(String materialTwitter : materialTwitters){
// System.out.println("materialTwitter="+materialTwitter);
t = new Twitter();
t.setCtx(materialTwitter);
t.setAddDate(now);
t.setModifyDate(now);
t.setAddUser(null);
t.setModifyUser(null);
msession.insert("insertTwitter", t);
}
msession.commit();

TwitterMapper.xml, Insert code snippet :

<insert id="insertTwitter" keyProperty="id" parameterType="org.pushio.test.show1.entity.Twitter" useGeneratedKeys="true">
insert into twitter(ctx, add_date,modify_date) values (#{ctx},#{add_date},#{modify_date})
</insert>

Query test 1

adopt id from 1 Increase to 10 Wan queries twitter content in turn , Only output microblog content .

Key code :

hibernate:

long cnt = 100000;
for(long i = 1; i <= cnt; ++i){
Twitter t = (Twitter)session.get(Twitter.class, i);
//System.out.println("t.getCtx="+ t.getCtx() + " t.getUser.getName=" + t.getAddUser().getName());
}

mybatis:

long cnt = 100000;
for(long i = 1; i <= cnt; ++i){
Twitter t = (Twitter)msession.selectOne("getTwitter", i);
//System.out.println("t.getCtx="+ t.getCtx() + " t.getUser.getName=" + t.getAddUser().getName());
}

Query test 2

And query testing 1 The whole thing is the same , Add the creator name field of microblog , Here we need to associate .

The corresponding microblog is 10 Million users . Maybe some users repeat . The corresponding number of users here may be the same as hibernate The configuration of lazy loading has an impact on .

This shows hibernate A convenient place for , You can go directly through getAddUser() You can get user Related fields .

However myBatis You need to write a new vo, So testing batis When it comes to Twitter Add the name of the creator to the entity (createUserName).

here hibernate Will test for lazy loading respectively , No lazy loading .

mybatis Will test both default and cache conditions .

among mybatis It is difficult to configure the cache mechanism of , Not for real business ( There may be dirty data ), This is for reference only .

When testing , There are two scenarios for the number of users associated with twitter , One is that Twitter is associated with 100 Users , It's different tweets, which are in 100 Within users , The correlation here is generated randomly .

The other is that Twitter is associated with 50 Million users , Basically 50 The information of each user will be found out .

Above “ Get ready ” You can see how the associated data is generated in .

Key code :

hibernate:

long cnt = 100000;
for(long i = 1; i <= cnt; ++i){
Twitter t = (Twitter)session.get(Twitter.class, i);
t.getAddUser().getName();// Load the corresponding fields 
//System.out.println("t.getCtx="+ t.getCtx() + " t.getUser.getName=" + t.getAddUser().getName());
}

Load configuration changes quickly ,Twitter.java:

@ManyToOne(fetch = FetchType.EAGER)// Emergency loading 
//@ManyToOne(fetch = FetchType.LAZY)// Lazy loading 
@JoinColumn(name = "add_user_id")
public User getAddUser() {
return add_user;
}

mybatis:

for(long i = 1; i <= cnt; ++i){
Twitter t = (Twitter)msession.selectOne("getTwitterHasUser", i);
// System.out.println("t.getCtx="+ t.getCtx() + " t.getUser.getName=" + t.getCreateUserName());
}

TwitterMapper.xml To configure :

<select id="getTwitterHasUser" parameterType="long" resultType="org.pushio.test.show1.entity.Twitter">
select twitter.*,user.name as creteUserName from twitter,user
where twitter.id=#{id}
AND twitter.add_user_id=user.id
</select>

test result

Test and analysis

The test is divided into inserts , Single table query , Relational query . Association query hibernate Configure it in three situations .

In the associated field query ,hibernate In two cases , There is a big difference in performance . In the case of lazy loading , If Twitter has more users , Then the performance is better than just mapping 100 The situation of individual users is much worse .

In other words , If the number of users is small ( Total number of associated users ) when , In other words, the same user will be queried repeatedly , You don't need to do too many queries on the user table .

After querying the document , Prove that when using lazy loading , The object will be id by key Do the cache , That is to say, to inquire about 100 After users , Subsequent user information is cached , Make the performance have fundamental improvement . Even better than myBatis Higher .

If it's a connection 50 Million users , be hibernate Need to check 50 Ten thousand user information , And assemble this 50 Million users , At this point, the performance is better than myBatis Poor performance , But the difference is not big , Less than 1ms, Indicates acceptable .

among hibernate In the case of non lazy loading, and myBatis The performance difference is also larger than other tests , The average is less than 1ms.

The main reason for this difference is ,myBatis The loaded fields are clean , There are not too many extra fields , Directly reflected in the Association . take the reverse into consideration hibernate Then the word of the whole table will be loaded into the object , It also includes related user Field .

hibernate There are good and bad in this situation , It depends on the specific scene , For the management platform , There's more information to show , When concurrency requirements are not high ,hibernate Comparative advantage .

However, in some small activities , Internet sites , High concurrency ,hibernate It's not very suitable for ,myBatis+VO Is the preferred .

in addition , Official account Java Technology stack , Reply in the background : interview , I can get the MyBatis A series of interview questions and answers , Very complete .

Test summary

The overall view ,myBatis In all cases , Especially insert and single table query , Will be slightly better than hibernate. But the difference is not obvious , You can basically ignore the difference .

The big difference is when the association query ,hibernate In order to ensure POJO Data integrity , The associated data needs to be loaded , More data needs to be queried additionally . here hibernate It doesn't provide the corresponding flexibility .

A big difference in association is the lazy loading feature . among hibernate You can make special use of POJO Integrity to cache , You can save objects in the first and second level caches , If there are more queries on a single object , There will be obvious performance benefits .

When it comes to single object association , The performance can be improved by lazy loading and secondary caching .

Last , Performance and query of data orm The framework doesn't matter much , because orm It mainly helps developers transform relational data into object data model , On the deep analysis of the code ,hibernate Designed to be more heavyweight , For development, it can be regarded as redevelopment of a database , Don't let developers care too much about database features , Directly in hibernate On the basis of development , Execution is divided into sql Generate , Data encapsulation, etc , It took a lot of time here . However myBatis It's more direct than , It is mainly to do a mapping between association and output fields . among sql It's basically written , You can replace it directly , No need to be like hibernate That's how to dynamically generate the whole sql sentence .

Fortunately hibernate At this stage, it has been optimized better , There's nothing like myBatis There are too many differences in performance , But in terms of development efficiency , Scalability is relative to myBatis It's too much to say .

Last, last , About myBatis cache ,hibernate Wait a minute , I'll do a special test later .

About cache configuration

myBatis relative Hibernate And the package is more tight ORM In terms of implementation , because hibernate The operation of data objects is tightly encapsulated , It can guarantee the cache synchronization within its scope , and ibatis What is provided is a semi enclosed encapsulation implementation , Therefore, it is difficult to synchronize the cache automatically .

The above cache configuration test is only for performance analysis , There's no usability case , because myBatis If you configure the cache directly , Dirty data may appear ,.

In the case of associated query data ,hiberntae It's a better solution to load lazily with L2 cache ( No dirty data ), Also with myBatis Compared with the obvious advantages . In this situation , Performance and myBatis flat .

In the real world ,myBatis Caching may not be configured on this site , There will be dirty data , So it's very likely that hibernate Performance will be better .

Recent hot article recommends :

1.1,000+ Avenue Java Arrangement of interview questions and answers (2021 The latest version )

2. Don't fill the screen again if/ else 了 , Try strategy mode , It's delicious !!

3. Oh my god !Java Medium xx ≠ null What is the new grammar ?

4.Spring Boot 2.5 Blockbuster released , Dark mode is too explosive !

5.《Java Development Manual ( Song Mountain version )》 The latest release , Download it quickly !

I think it's good , Don't forget to like it + Forward !

版权声明
本文为[Java technology stack]所创,转载请带上原文链接,感谢
https://javamana.com/2021/09/20210909145631902o.html

  1. L'arrivée de marchandises sèches, l'entretien d'emploi Java 12 grandes usines ont réussi à changer d'emploi,
  2. Multiple postures for handling container time in k8s environment
  3. Echarts remove left Gap, Blank
  4. Hotspot Weekly | zoom $100 million, docker fees, $38 billion Data bricks
  5. JsonMappingException: No serializer found for class org.apache.ibatis.executor.loader.javassist.JavassistProxyFactory...
  6. Java. Security. Securerandom source code analysis Java. Security. EGD = file: / dev /. / urandom
  7. When using IntelliJ idea, jump directly and quickly from the mapper interface to mapper.xml
  8. When idea writes SQL in mybatis XML, the solution to the problems of table name, field and red reporting
  9. Spring cloud integrates Nacos
  10. 应届毕业生Java笔试题目,2021大厂Java社招最全面试题,
  11. Liver explosion! Take you to understand Hadoop serialization
  12. linux系列之:告诉他,他根本不懂kill
  13. java版gRPC实战之三:服务端流
  14. RabbitMQ核心知识总结!
  15. linux系列之:告诉他,他根本不懂kill
  16. java版gRPC实战之三:服务端流
  17. RabbitMQ核心知识总结!
  18. 10天拿到字节跳动Java岗位offer,学习Java开发的步骤
  19. 10天拿到字节跳动Java岗位offer,Java知识点思维导图
  20. Résumé des connaissances de base de rabbitmq!
  21. 10天拿到字節跳動Java崗比特offer,Java知識點思維導圖
  22. 10 jours pour obtenir un Byte Jump Java post offer, Java Knowledge point Mind Map
  23. 10 jours pour obtenir l'octet Jump Java post offer, apprendre les étapes du développement Java
  24. Java version of gppc Reality Three: server side stream
  25. Linux Series: Dites - lui qu'il ne connaît pas kill du tout
  26. "Data structure and algorithm" of front end -- binary search
  27. 2020-2021京东Java面试真题解析,如何才能通过一线互联网公司面试
  28. 13 SpringBoot整合RocketMQ实现过滤消息-根据SQL表达式过滤消息
  29. 12 SpringBoot整合RocketMQ实现过滤消息-根据TAG方式过滤消息
  30. 11 SpringBoot整合RocketMQ实现事务消息
  31. 11 springboot Consolidated rocketmq Implementation transaction message
  32. 12 springboot Consolidated rocketmq Implements Filtering messages - Filtering messages according to tag method
  33. 13 springboot Consolidated rocketmq Implementation Filtering messages - Filtering messages according to SQL expressions
  34. linux系列之:告诉他,他根本不懂kill
  35. (1)java Spring Cloud+Spring boot企业快速开发架构之微服务是什么?它的优缺点有哪些?
  36. Oracle 检查 DATE 列 RANGE 分区表已有分区的最大日期时间
  37. ConcurrentHashMap--原理
  38. 2020 - 2021 JD Java interview Real question Analysis, How can interview through First - Line Internet Company
  39. Concurrenthashmap - - Principes
  40. Oracle vérifie l'heure de date maximale d'une partition existante dans la colonne date
  41. Docker Compose 实践及梳理
  42. Qu'est - ce qu'un microservice pour Java Spring Cloud + Spring Boot Enterprise Quick Development architecture?Quels sont ses avantages et ses inconvénients?
  43. Plus sign interview knowledge points in Java
  44. Pratique et organisation de la composition des dockers
  45. Linux Series: Dites - lui qu'il ne connaît pas kill du tout
  46. Convenient CSS and jQuery drop-down menu solution
  47. Linux analog packet loss rate
  48. Redis:我是如何与客户端进行通信的
  49. 15 useful cron work examples commonly used by Senior Linux system administrators
  50. 24个 JavaScript 循环遍历方法,你都知道吗?
  51. Reading notes of JavaScript advanced programming (3rd Edition) 4
  52. 30分钟学会Docker里面开启k8s(Kubernetes)登录仪表盘(图文讲解)
  53. 24 méthodes de traversée de boucle Javascript, vous savez?
  54. 30 minutes pour apprendre à ouvrir le tableau de bord k8s (kubernets) dans le docker (explication graphique)
  55. Redis: comment je communique avec les clients
  56. Wsl2: Windows native Linux subsystem
  57. 30分钟学会Docker里面开启k8s(Kubernetes)登录仪表盘(图文讲解)
  58. Python高级用法总结(8)-函数式编程
  59. 261页前端面试题宝典,JavaScript变量声明提升
  60. The performance of JVM and Java applications of the same version differs by 30% on X86 and aarch64 platforms. Why?