Newcomers to Java are easy to make mistakes: when the modification encounters the only one (long text with 10,000 words)

written in front

Now is the era when there are many Java training institutions, and there are even 360 lines of rumors about switching to java. However, many of us blindly pursue the breadth of knowledge and tirelessly learn various new technologies.

A large number of blogs on the Internet are under the bright title of xxx management system, wow, free ones can be used for nothing, download, compile, and deploy quickly. Build a blog page, with types, additions, deletions, changes and queries of articles, various new technologies, boot, cloud, vue, I feel like I am a fortress.

However, we often neglect the exercise of business logic. No matter how good those projects are, no matter how gorgeous the pages are, they are nothing more than the simplest additions, deletions, modifications and queries, providing fertile soil for a large group of crud boys.

So, some people said, I want to jump out of my comfort zone and go to the volume algorithm.

Algorithms are meaningful for high-level programs, but more often than not, we mainly work on writing business codes.

It does not require how great your code is, but it requires that your code is of excellent quality, and that various bugs do not occur frequently and cause production accidents.

touchstone

Don't think this is a very simple matter, often a small function will bury countless pits.

Even you will feel stunned, I am a good crud expert, how come I accidentally jumped into the pit when I encountered such a simple requirement.

This is a matter of thinking, and business thinking cannot be upgraded with the number of cruds.

To me, for a novice entering the java industry, the best touchstone is the question of modifying the only data.

Prepare the environment

Let’s get the environment done first. For the sake of convenience, I directly used the code of the “Fresh Springboot Diary System” I wrote before, and added the test dependencies:

<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-test</artifactId>
</dependency>

Do it directly.

First come a Customer class:

@Data
@Builder
public class Customer {
    @TableId(type = IdType.AUTO)
    private Integer id;
    private String name;
    private String idno;
    private String isDel;
}

Corresponding table structure:

Test adding data

@Slf4j
@SpringBootTest(classes = {DiaryApplication.class})
@RunWith(SpringJUnit4ClassRunner.class)
public class MyTest {

    @Resource
    CustomerMapper customerMapper;

    @Test
    public void tt(){
        customerMapper.insert(Customer.builder().name("小火龙").idno("1").build());
        customerMapper.insert(Customer.builder().name("杰尼龟").idno("2").build());
        customerMapper.insert(Customer.builder().name("妙蛙种子").idno("3").build());
    }
}

get

At this point, the environment is ready.

Unique ID number

The requirement is very simple, the ID number must be unique.

We know that id is automatically incremented, this is no problem. The ID number is unique, and it is nothing more than judging when it is added or modified.

Add a unique judgment

This is simple, nothing more than judging whether there is an idno when adding a new one. You've written code in no time, and you're checkIdnoproud of yourself for encapsulating the method:

/**
 * 测试新增
 */
@Test
public void insert(){
    //模拟前台传过来的Req
    Customer customerDto = Customer.builder().name("火球鼠").idno("1").build();
    //先检查身份证号是否存在于数据库中
    checkIdno(customerDto.getIdno());
    //正常入库
    customerMapper.insert(customerDto);
}

private void checkIdno(String idno) {
    LambdaQueryWrapper<Customer> lambdaQueryWrapper = new LambdaQueryWrapper<>();
    Customer one = customerMapper.selectOne(lambdaQueryWrapper.eq(Customer::getIdno, idno));
    //不是空,说明有这个idno的数据
    if(one != null){
        throw new WrongArgumentException("身份证重复!");
    }
}

Test, an error is reported, and the business is correct.

Editorial Judgment Unique

The new addition has already made a good start, and the next step is the editor. As a newcomer who has just graduated and entered the company, he is typing on the keyboard with great interest.

Well, when you modify it, you can just reuse checkIdnothe method you just encapsulated.

/**
 * 测试修改
 */
@Test
public void edit(){
    //模拟前台传过来的Req
    Customer customerReq = Customer.builder().id(1).idno("2").build();
    //先检查身份证号是否存在于数据库中
    checkIdno(customerReq.getIdno());
    //根据id查询数据库的数据
    Customer customerDto = getById(customerReq.getId());
    //更新idno
    customerDto.setIdno(customerReq.getIdno());
    //入库
    customerMapper.updateById(customerDto);
}

private Customer getById(Integer id) {
    return customerMapper.selectById(id);
}

Encapsulation, encapsulation, this is taught by the teacher in the training class, if it can be encapsulated, it will be encapsulated. Well, I encapsulated another getById method, which is a badge of honor and a proof of my technical strength!

The above code test modified Charmander and changed the ID from 1 to 2, which conflicted with the Squirtle.

Come on, test it.

( •̀ ω •́ )yeah!

Call it a day, the comments are perfect, the code is complete, and I even encapsulated it!

The next step is promotion and salary increase, marrying Bai Fumei, and walking to the pinnacle of life from now on.

What if the idno is not changed?

Life is always ups and downs, both ups and downs, it is impossible to have only sweetness.

Until one day, the test lady found you, why did I change my name and report an error?

You are directly confused, and immediately open the postman self-test, and found that there is really a problem.

@Test
public void edit(){
    //模拟前台传过来的Req
    Customer customerReq = Customer.builder().id(1).name("喷火龙").idno("1").build();
    //先检查身份证号是否存在于数据库中
    checkIdno(customerReq.getIdno());
    //根据id查询数据库的数据
    Customer customerDto = getById(customerReq.getId());
    //更新name
    customerDto.setName(customerReq.getName());
    //入库
    customerMapper.updateById(customerDto);
}

The idno is still 1, but it was sent over. Charmander’s original idno was 1, but due to the weight checking logic, an error was reported.

You suddenly panicked, why is there so many twists and turns for such a simple small demand?

solution

One of the simplest ideas is, when you edit, must there be an id passed in, after all, I need to update according to this id.

Then, I can also use this id to query the corresponding idno, whether it is the same as the idno sent in this time.

If it is inconsistent with the original idno, it means that you changed the idno this time, and I will check to see if your modified idno is duplicated with the idno corresponding to other data.

The method is to check with the modified idno. If it is found out, it means that there is a duplicate, otherwise it is the only one, and modification is allowed.

For testing convenience, add parameters to the edit method.

public void edit(Customer customerReq){

    //根据id查询数据库是否有这条数据
    Customer customer = customerMapper.selectById(customerReq.getId());
    //如果不存在或者跟原来的idno不一致,才进行校验
    Boolean isNeedCheck = true;
    if(customer != null && customer.getIdno().equals(customerReq.getIdno())){
        isNeedCheck = false;
    }

    //检查身份证号是否存在于数据库中
    if(isNeedCheck) {
        checkIdno(customerReq.getIdno());
    }
    //根据id查询数据库的数据
    Customer customerDto = getById(customerReq.getId());
    //更新name
    customerDto.setName(customerReq.getName());
    //更新idno
    customerDto.setIdno(customerReq.getIdno());
    //入库
    customerMapper.updateById(customerDto);
}

And then the test case:

//测试编辑功能,修改其他字段但idno不变
@Test
public void testEdit01(){
    //模拟前台传过来的Req => 只改姓名不改身份证
    Customer customerReq = Customer.builder().id(1).name("喷火龙").idno("1").build();
    edit(customerReq);
}

//测试编辑功能,修改idno但是和其他数据的idno一样
@Test
public void testEdit02(){
    //模拟前台传过来的Req => 只改姓名不改身份证
    Customer customerReq = Customer.builder().id(1).name("喷火龙").idno("2").build();
    edit(customerReq);
}

//测试编辑功能,修改idno但是和其他数据的idno都不一样
@Test
public void testEdit03(){
    Customer customerReq = Customer.builder().id(1).name("喷火龙").idno("8").build();
    edit(customerReq);
}

The first test is normal because the idno has not been changed. The second test reported an error, which also met expectations. The third is a positive example, and the result is still no problem.

Scenario 2

The above logic is fine, and the code is very readable, but not concise enough. In actual development, I have also seen some people handle it this way.

Directly on the code, the comments are very detailed.

public void edit2(Customer customerReq){

    /**
     * 直接根据idno查询,无非有两种情况
     *  1.查出来为null,说明没有这个idno,安全
     *  2.查出来有一条数据,又分两种情况
     *      2.1 这条数据就是要编辑的原数据:说明我们修改这条记录并且没改idno,安全
     *      2.2 这条数据不是要编辑的原数据:说明我们修改这条记录并且改了idno,还和别的记录的idno重复了,不安全
     *  总结:如果查出来有数据并且id和要编辑数据的id不同,才不安全
     */
    LambdaQueryWrapper<Customer> lambdaQueryWrapper = new LambdaQueryWrapper<>();
    Customer one = customerMapper.selectOne(lambdaQueryWrapper.eq(Customer::getIdno, customerReq.getIdno()));
    if(Objects.nonNull(one) && !Objects.equals(one.getId(),customerReq.getId())){
        throw new WrongArgumentException("身份证重复!");
    }

    //根据id查询数据库的数据
    Customer customerDto = getById(customerReq.getId());
    //更新name
    customerDto.setName(customerReq.getName());
    //更新idno
    customerDto.setIdno(customerReq.getIdno());
    //入库
    customerMapper.updateById(customerDto);
}

The idea is to check directly through idno, nothing more than these four situations.

Directly query based on idno, there are two situations:

1. It is found to be null, indicating that there is no such idno, which is safe.

2. If there is a piece of data found, there are two situations.

2.1 This data is the original data to be edited: it means that we modify this record without changing the idno, which is safe.

2.2 This data is not the original data to be edited: it means that we modify this record and change the idno, and it is also the same as the idno of other records, which is not safe.

Summary: If it is found that there is data and the id is different from the id of the data to be edited, it is not safe.

It may seem difficult to understand at first glance, but once we sort out all the situations, it is still very clear.

This plan is indeed very simple, and the ingenuity lies in its ingenuity. It also includes the newly added situation unconsciously.

If it is a new addition, then customerReq has no id, then getId is null, which must not match the getId of one. You can also walk into this logic:

LambdaQueryWrapper<Customer> lambdaQueryWrapper = new LambdaQueryWrapper<>();
Customer one = customerMapper.selectOne(lambdaQueryWrapper.eq(Customer::getIdno, customerReq.getIdno()));
if(Objects.nonNull(one) && !Objects.equals(one.getId(),customerReq.getId())){
    throw new WrongArgumentException("身份证重复!");
}

We might as well extract this logic and encapsulate it into a method.

private void checkIdnoNew(Customer customerReq) {
    /**
     * 直接根据idno查询,无非有两种情况
     *  1.查出来为null,说明没有这个idno,安全
     *  2.查出来有一条数据,又分两种情况
     *      2.1 这条数据就是要编辑的原数据:说明我们修改这条记录并且没改idno,安全
     *      2.2 这条数据不是要编辑的元数据:说明我们修改这条记录并且改了idno,还和别的记录的idno重复了,不安全
     *  总结:如果查出来有数据并且id和要编辑数据的id不同,才不安全
     */
    LambdaQueryWrapper<Customer> lambdaQueryWrapper = new LambdaQueryWrapper<>();
    Customer one = customerMapper.selectOne(lambdaQueryWrapper.eq(Customer::getIdno, customerReq.getIdno()));
    if(Objects.nonNull(one) && !Objects.equals(one.getId(),customerReq.getId())){
        throw new WrongArgumentException("身份证重复!");
    }
}

The edit method becomes this:

public void edit2(Customer customerReq){

    checkIdnoNew(customerReq);

    //根据id查询数据库的数据
    Customer customerDto = getById(customerReq.getId());
    //更新name
    customerDto.setName(customerReq.getName());
    //更新idno
    customerDto.setIdno(customerReq.getIdno());
    //入库
    customerMapper.updateById(customerDto);
}

The new method is also modified:

@Test
public void insert(){
    //模拟前台传过来的Req
    Customer customerReq = Customer.builder().name("火球鼠").idno("6").build();
    //先检查身份证号是否存在于数据库中
    checkIdnoNew(customerReq);
    //正常入库
    customerMapper.insert(customerReq);
}

Compared with the previous method:

//根据id查询数据库是否有这条数据
Customer customer = customerMapper.selectById(customerReq.getId());
//如果不存在或者跟原来的idno不一致,才进行校验
Boolean isNeedCheck = true;
if(customer != null && customer.getIdno().equals(customerReq.getIdno())){
    isNeedCheck = false;
}

//检查身份证号是否存在于数据库中
if(isNeedCheck) {
    checkIdno(customerReq.getIdno());
}

Isn't it much more concise? This is the charm of business thinking.

It is really not easy to write this article. It should be one of the rare blogs on the Internet that teaches people how to manage business logic. It seems to be a small function, but there are so many twists and turns in it, haha, I didn't expect it.

Nowadays, many tutorials, including many video courses, are arranged for you with a lot of technologies, such as malls, redis, ES, etc., all for you. After studying for a long time, it seems that I have learned a lot, but I am often not very good, and I have become a small expert in the whole stack of Hello World.

A lot of people complained to me why I learned so much, signed up for a lot of messy courses, and made a lot of shopping mall systems. How can I still be dropped by the interviewer? Got fired?

That's because you still haven't developed a real business thinking, and your thinking is still in your student days. You want others to chew and feed you, and you lack the spirit to take the initiative to study. To put it bluntly, I have too little project experience, so I don't know what the factory wants me to do? Don't think that you can use MybatisPlus to generate a Crud code, and you can say that you are proficient in simple get/set with redis. In the era of industry involution, how can it be so simple.

But you may say, if I am not allowed to join the job, how can I accumulate project experience?

Look, it's a deadlock problem again.

These problems have been exposed, which may be caused by many factors of anxiety about selling on the Internet, and there may also be reasons for the general environment.

But no matter what, we should maintain a normal mind, watch more, practice more, don't blindly be greedy for more, there is no need to achieve various helloworld achievements.

Look at the beautiful blogging system with various scaffolding on the current video website, the number of favorites and likes are scary.

But I personally feel that these are not very helpful to really improve my coding ability.

In a word, really, don't be led astray.

The above are all my personal complaints, and only represent my own views. Welcome to exchange and discuss together. This article is also mainly aimed at the cute new Xiaobai who are new to the industry, and the big guys lightly spray.

Guess you like

Origin blog.csdn.net/weixin_39570751/article/details/129614717