Why are many people reluctant to use hibernate?

The debate about SQL vs ORM will never end, and I've been thinking about it. Recently, I reviewed the SSH framework, made a move, and had a deep discussion with the majority of ape friends. I was sprayed with five bodies, and I was full of emotions, so I have today's article.

Disclaimer: This article is just my humble opinion of the editor. If you don't like it, don't spray it.

Haste is not enough, if you want to be haste, is haste!

1. Advantages of hibernate

Hibernate lets you not need to write sql, which not only allows your application to be better ported to other databases, but also allows programmers to focus more on business logic, data relationships, and object relationships. Hibernate is very good at implementing one-to-many and many-to-many relationships. Crucially, it supports lazy, which allows your data to be loaded only when needed, which sounds perfect. Hibernate also has HQL, which is a query language that can completely map queries to your OO model. Compared with the mapping of mybatis, it is more convenient and powerful.

1. What is the @Lazy annotation?

The @Lazy annotation is used to identify whether the bean needs to be lazy loaded. The source code is as follows:

@Target({ElementType.TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Lazy {
    /**
     * Whether lazy initialization should occur.
     */
    boolean value() default true;
}

There is only one parameter, and the default is true, which means that as long as this annotation is added, it will be loaded lazily.

2. How to use the @Lazy annotation

The bean will be instantiated when the main container starts before the annotation is added, as follows:

AnnotationConfigApplicationContext applicationContext2 = new AnnotationConfigApplicationContext(MainConfig.class);

Create user instance

With the @Lazy annotation, it must be loaded on the first call as follows:

@Scope
@Lazy
@Bean(value="user0",name="user0",initMethod="initUser",destroyMethod="destroyUser")
public User getUser(){
    System.out.println("创建user实例");
    return new User("张三",26);
}
AnnotationConfigApplicationContext applicationContext2 = new AnnotationConfigApplicationContext(MainConfig.class);
User bean2 = applicationContext2.getBean(User.class);
创建user实例
实例1 === User [userName=张三, age=26]

The function of @Lazy annotation is mainly to reduce the loading time of springIOC container startup

Second, hibernate disadvantages

After reading the advantages, I feel that hibernate is omnipotent, and how lonely it is to be invincible. Network services that deal with large amounts of data or large concurrency do not feel very useful, so now let's talk about the problem of hibernate.

1. Difficult to use some functions of the database

Hibernate isolates the database from the developer. The developer does not need to pay attention to whether the database is Oracle or MySQL. Hibernate will help you generate the sql statement of the query, but the problem is, if you want to use a certain database-specific function, or let the query The sql is exactly what you want, which is difficult. If you use hibernate, although it can customize the generated query to a certain extent, it will be a bit of a scratch, and you will pay more for development. As for hibernate's support for native sql, it is quite perfect. This kind of native sql can also return non-managed entities without using hibernate's cache. The optimization is done, but if the whole project is so complete, then use mybatis.

Many times, we have a need: to get the current time of the database server. This is because the local time and the server time are different. Various databases provide functions to obtain, for example, mysql, you can use "select now()". Hibernate also provides a function current_timestamp (speaking of timestamp, I personally think that the timestamp of the database is very poor, it is actually an order of magnitude (accuracy) with datetime, how can this be used to represent the real stamp!). However, you can't use "select current_timestamp()" directly to get the current time of the server, you must also add a query table! For example, "select current_timestamp() from tbl_Good". Personally, I am very depressed. I just want to use this simple function. Why do I have to know the tables in the database? ? ? ? What's more, a mapping must be established. . . . . .

It's not that I don't understand, the world is too complicated. Every product is desperately complicated, and in fact, they ignore the fact that the average user only needs a small part of the function. The default function should be able to meet the common needs of ordinary users, so it can be regarded as a good product. I don't think hibernate does this.

2. Can not meet the needs of the program for cache

Many web services rely heavily on cache, and the cache that comes with hibernate is reasonably powerful, but it still cannot meet many needs.

3. High degree of coupling

Hibernate does save a lot of time during your project development, but it relies too much on your business logic model and database model. There is no problem in the short term, but as the project changes, these will change. When maintaining this only coupling relationship, you will find that your code is particularly fragile. If you change the schema of any database, the entire java project may need to be changed. dozens of times. And now the automatic mapping of mybatis is also doing very well, and it does not take long to develop. When the project enters the middle and late stages, when you need to customize and optimize a lot of queries, the development efficiency of mybatis will be more obvious.

4. It is difficult to debug

As a backend programmer, I prefer to know exactly what each line of code is doing. Especially in the code of database access, the bottleneck of the system often occurs in these places, and every line should not be underestimated. I have seen part of the code in the early version of hibernate, it is much more complex and powerful than I thought. There are indeed many places where Hibernate can powerfully solve many problems with only one line of code, but for example, what does an update() or save() do? There are both the logic of Hibernate itself and the logic of your application. If this line generates Question, how do you do it? I personally think this is difficult to do, it is better to use mybatis at the beginning.

As a programmer, I always insist that changing code is easier than changing configuration files.

5, hibernate updates large batches of data

(1) Hibernate batch updates the age field of all records greater than zero in the customers table:

Transaction transaction = session.beginTransaction();     
Iterator customers=session.find("from Customer c where c.age>0").iterator();     
while(customers.hasNext()){     
    Customer customer=(Customer)customers.next();     
    customer.setAge(customer.getAge()+1);     
}      
transaction.commit();     
session.close();  

If there are 10,000 records whose age is greater than zero in the customers table, the session's find() method will load 10,000 customer objects into memory at once. When the tx.commit() method is executed, the cache is cleared, and hibernate executes 10,000 update statements to update the customers table:

update CUSTOMERS set AGE=? …. where ID=i;     

(2) The above hibernate batch update method has two disadvantages

  • It takes up a lot of memory space and must load 10,000 customer objects into memory first, and then update them one by one.
  • The number of executed update statements is too large. Each update statement can only update one Customer object. Only 10,000 update statements can update 10,000 Customer objects. Frequent access to the database will greatly reduce the performance of the application.

(3) In order to quickly release the memory occupied by 10,000 Customer objects, after updating each Customer object, call the evict() method of the Session to release its memory immediately:

Transaction transaction = session.beginTransaction();     
Iterator customers=session.find("from Customer c where c.age>0").iterator();     
while(customers.hasNext()){     
    Customer customer=(Customer)customers.next();     
    customer.setAge(customer.getAge()+1);     
    session.flush();     
    session.evict(customer);     
}      
transaction.commit();     
session.close();  

In the above program, after modifying the age attribute of a Customer object, the flush() method and the evict() method of the Session are called immediately. The flush() method makes hibernate update the database synchronously according to the state change of the Customer object, so as to immediately Execute the relevant update() statement; the evict() method is used to clear the Customer object from the cache, thereby releasing the memory it occupies in time.

However, the evict() method can only slightly improve the performance of batch operations, because regardless of whether the evict() method is used, Hibernate must execute 10,000 update statements to update 10,000 Customer objects, which is an important factor affecting the performance of batch operations. factor. If Hibernate can directly execute the following SQL statement:

update CUSTOMERS set AGEAGE=AGE+1 where AGE>0;   

Then the above update statement can update 10,000 records in the CUSTOMERS table. But Hibernate does not directly provide an interface to execute such an update statement. The application must bypass the Hibernate API and execute the SQL statement directly through the JDBC API:

Transaction transaction = session.beginTransaction();     
Connection con=session.connection();     
PreparedStatement stmt=con.prepareStatement("update CUSTOMERS set AGEAGE=AGE+1 where AGE>0 ");     
stmt.executeUpdate();     
transaction.commit();  

The above program demonstrates the process of bypassing the Hibernate API and accessing the database directly through the JDBC API. The application obtains the database connection used by the Session through the connection() method of the Session, and then creates the PreparedStatement object through it and executes the SQL statement. It is worth noting that applications still declare transaction boundaries through Hibernate's Transaction interface. 
If the underlying database (such as Oracle) supports stored procedures, Hibernate batch updates can also be performed through stored procedures. Stored procedures run directly in the database and are much faster. In the Oracle database, a stored procedure named batchUpdateCustomer() can be defined with the following code:

create or replace procedure batchUpdateCustomer(p_age in number) as     
begin     
update CUSTOMERS set AGEAGE=AGE+1 where AGE>p_age;     
end;  

The above stored procedure has a parameter p_age, which represents the age of the customer. The application can call the stored procedure as follows:

Transaction transaction = session.beginTransaction();     
Connection con=session.connection();     
String procedure = "{call batchUpdateCustomer(?) }";     
CallableStatement cstmt = con.prepareCall(procedure);     
cstmt.setInt(1,0); //把年龄参数设为0     
cstmt.executeUpdate();     
transaction.commit();  

As can be seen from the above program, the application must also bypass the Hibernate API and call the stored procedure directly through the JDBC API. 

6. hibernate deletes large batches of data

The various overloads of the update() method of the Session can only update one object at a time, and some overloads of the delete() method allow HQL statements as parameters, for example:

session.delete("from Customer c where c.age>0");  

If there are 10,000 records with age greater than zero in the CUSTOMERS table, the above code can delete 10,000 records. But the delete() method of Session does not execute the following delete statement

delete from CUSTOMERS where AGE>0;  

The delete() method of Session first loads 10,000 Customer objects into memory through the following select statement:

select * from CUSTOMERS where AGE>0;  

Next, execute 10,000 delete statements to delete the Customer objects one by one:

delete from CUSTOMERS where ID=i;     
delete from CUSTOMERS where ID=j;     
delete from CUSTOMERS where ID=k;  

It can be seen that Hibernate batch update and Hibernate batch delete directly through Hibernate API are not recommended. Directly executing related SQL statements or calling stored procedures through the JDBC API is the best way for hibernate to batch update and delete batches.

Su Xiaonuan talks about Spring JdbcTemplate

3. The eyes of the masses are sharp, don't go against the sky

 

4. Some insights after being sprayed

It felt like a critique meeting. I deeply felt the helplessness of lack of talent and learning. I really just wanted to study hard. I hope that in a few years, I can still keep my original intention.

As a junior programmer, there is no need to spend too much time proving the uselessness of technology. I have not conducted in-depth research on the hibernate framework, but only some personal insights at a superficial level.

There is no right or wrong in the framework itself, only if it is suitable or not. Any framework has its own range of capabilities. Hibernate encapsulates a lot of useful APIs for us, which reduces the difficulty and complexity of operating the database, and also reduces the template code. However, hibernate leaves much less space for developers to operate than mybatis; the mybatis framework is more flexible to use, and developers can customize query statements, but it increases the amount of template code, and it seems that there is no hibernate boundary. The two frameworks have made trade-offs and compromises on the two indicators of convenience and flexibility, which cannot be said to be the fault of the frameworks. For a framework, it needs to have its own dedicated field and design vision, and it is impossible to cover everything, as the big brother said:

Using any kind of technical framework needs to fit the realistic business needs and its own technical capabilities. When you haven't deeply understood a technology or the current business requirements cannot fit with the framework, don't blindly criticize the quality of the framework.

 

This blogger has entered CSDN in an all-round way, I hope everyone will support me, thank you very much!

[CSDN] Why are many people reluctant to use hibernate?

 

 

{{o.name}}
{{m.name}}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324128668&siteId=291194637