There are hidden dangers in using Mybatis-Plus, it’s so tricky!

Author: confused code
Link: https://juejin.cn/post/7156428078061895710

Foreword

MP has been controversial since its emergence. It feels like there have always been two voices.

like:

It is very convenient. Sql is automatically spliced through functions. There is no need to go to XML or use tags. The Sql written in one minute can now be written in one second. It is not too convenient.

dislike:

Intrusion into the Service layer, difficult to maintain, poor readability, code coupling, inefficiency, SQL optimization is difficult

Some seniors have said before that MP should be used sparingly because it is difficult to maintain. However, this thing is really convenient. As long as it is not forced to be used, I will still use it and it is stored in the collection. Recently, I did have some experience. Let’s look at MP from two angles.

Recommend an open source and free Spring Boot practical project:

https://github.com/javastacks/spring-boot-best-practice

Advantages

Simple operation

Let’s talk about the most commonly used additions, deletions, modifications and queries in our coding.

According to what we used to use Mybatis before, we have to create an XML file to write Sql statements. It is semi-automatic. We can directly control Sql statements, but it will be more troublesome. For many simple data queries, we have to write a label. This feels meaningless. The operation is still quite annoying, so how to implement it in MP.

The first one: The simplest is to use the provided method directly. We can do these operations very easily, but there is a problem with this.

nodeMapper.selectById(1);
nodeMapper.deleteById(2);
nodeMapper.updateById(new Node());
nodeMapper.insert(new Node());

Poor maintenance Take query as an example. The default method is to query all fields. We all know that the first optimization rule when writing Sql is not to use Select * because this writing method is very Low.

This is the result of the above selectById execution

SELECT Id,name,pid FROM node WHERE Id=?

This kind of Sql is definitely not good, so when we use MP, we try not to use the built-in shortcut query. We can use the constructor in it.

nodeMapper.selectOne(new QueryWrapper<Node>().eq("id",1).select("id"));

In this summary writing method, we can use the subsequent select() to specify the fields we need to query. Does this solve the above problem? But is this the end? There is another problem.

In development, we often talk about something called magic value

//This is the magic value
if ("Become Patrick".equals(node.getName())){
    System.out.println("magic value");
}

The reason why you don’t use magic values too much is for later maintenance. We recommend using enumerations or building a constant class and modifying them with Static final.

Does the above code have the same problem? Is "id" considered a magic value? The problem with this constructor is that it is not easy to maintain

Assume that our Node class is highly used and we write it everywhere

nodeMapper.selectOne(new QueryWrapper<Node>().eq("id",1).select("id"));

It was fine at first and we were happy. But what if I change the field name of Id?

I changed it to test (database synchronization modification). Now there is no such field in this entity class. Let’s look at our code again.

There is no response and no error message is given to me. What should I do if I run it at this time? Do I have to find the errors one by one? This is obviously very time-consuming.

This is indeed a problem, but it can also be solved

Node node = nodeMapper.selectOne(new LambdaQueryWrapper<Node>().eq(Node::getId, 1).select(Node::getId));

The above code can solve this problem. We can use this more when using it.

Once a field is modified, an error will be reported immediately

But is this all good? NO No NO What if we deal with slightly more complex statements? For example, if we sum the fields, this LambdaQueryWrapper still has limitations.

If we want to achieve this, how do we do it?

select SUM(price_count) from bla_order_data LIMIT 100

First of all, this way of writing is definitely not very good and the compilation will not pass.

Unless you use QueryWrapper

There is also a paging query

//Conditional query
LambdaQueryWrapper<UserInfo> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(UserInfo::getAge, 20);
//Paging object
Page<UserInfo> queryPage = new Page<>(page, limit);
// Paging query
IPage<UserInfo> iPage = userInfoMapper.selectPage(queryPage, queryWrapper);
//Total number of data
Long total = iPage.getTotal();
//Collect data
List<UserInfo> list = iPage.getRecords();

This is still very simple

Simple summary

MP can be used when doing some simple single-table queries, but it is better not to be used for some complex SQl operations.

1. For the problem of SQL invading Service, we can imitate Mybatis and build a package specifically to store MP queries.

2. Regarding maintainability, we can try to use LambdaQueryWrapper to construct

3. MP has a built-in primary key generation strategy

4. Built-in paging plug-in: Based on Mybatis physical paging, developers do not need to care about specific operations. After configuring the plug-in, writing paging is equivalent to ordinary List query.

Disadvantages

I would say that one of the biggest shortcomings is that the operability of complex Sql is very uncomfortable. For example, how do you write a multi-table query?

look at an example

Just pass

@Select annotation

Embed MP query conditions into it
${ew.customSqlSegment}

We are just a big question mark. Just write XML for joint tables. You really shouldn’t use this kind of thing. It’s too ugly.

Summary

There’s not too much stuff, it’s basically stuff I’ve seen recently.

1. It is not recommended to use MP for complex statements. It is best not to use MP if it can be used. It has poor readability and is difficult to maintain. It doesn’t feel good at the beginning. When the business expands later, it is really disgusting.

2. You can use paging in MP, which is more comfortable and it is also comfortable to gradually generate strategies.

3. Try not to use full table query methods such as selectById that comes with MP.

4. Try to use the writing form of LambdaQueryWrapper, which is at least easier to maintain.

5. MP can be used to simply repeat Sql. Don’t use complex SQL

I will add what I think of in the end. Colleagues who have other opinions can leave them in the comment area. I will add and correct them.

Recommended recent hot articles:

1.1,000+ Java interview questions and answers compiled (2022 latest version)

2. Explosive! Java coroutines are coming. . .

3. Spring Boot 2.x tutorial, so complete!

4. Stop filling the screen with explosive categories and try the decorator mode. This is the elegant way! !

5. “Java Development Manual (Songshan Edition)” is newly released, download it quickly!

If you think it’s good, don’t forget to like + retweet!