[Look at how Muzi sees a daily income of 1,000+, a detailed explanation of the whole process of building the latest small program for film and television] Comparison of the three batch insertion methods of MyBatis!

Video programs are very popular. The main monetization method is to monetize the traffic. If you do it well, you will earn thousands of dollars a day, and if you do it well, the monthly income of 1w is normal.

If you can think about it, you can think about how to draw inferences from one another and make more money by doing the same operation in the same way. If you can think of it, congratulations on your qualification.

It’s not expensive to charge 1,000 for this technology, after all, you have to charge several hundred for building a small program for others. After sharing the technical process, how to make money depends on your own abilities!
Insert picture description here
Insert picture description here
Insert picture description here
Insert picture description here
Insert picture description here
Insert picture description here
Insert picture description here
Insert picture description here
Insert picture description here
Insert picture description here
Insert picture description here
Insert picture description here
Insert picture description here
Insert picture description here
Insert picture description here
Insert picture description here
The database uses sqlserver, JDK version 1.8, and runs in the SpringBoot environment to compare three available methods:

1. Repeatedly execute a single insert statement
2. xml splicing sql
3. Batch execution
Let me start with the conclusion: Please use repeated insertion of a single piece of data for a small amount of insertion, which is convenient. For larger quantities, please use batch processing. (You can consider the amount of inserted data that is required to be 20 or so as the boundary. In my test and database environment, the time consumption is 100 milliseconds, and convenience is the most important). Do not use xml splicing sql at any time.
Code

The xmlnewId() of splicing SQL is a function of sqlserver to generate UUID, which has nothing to do with the content of this article

<insert id="insertByBatch" parameterType="java.util.List">
    INSERT INTO tb_item VALUES
    <foreach collection="list" item="item" index="index" separator=",">
        (newId(),#{
    
    item.uniqueCode},#{
    
    item.projectId},#{
    
    item.name},#{
    
    item.type},#{
    
    item.packageUnique},
        #{
    
    item.isPackage},#{
    
    item.factoryId},#{
    
    item.projectName},#{
    
    item.spec},#{
    
    item.length},#{
    
    item.weight},
        #{
    
    item.material},#{
    
    item.setupPosition},#{
    
    item.areaPosition},#{
    
    item.bottomHeight},#{
    
    item.topHeight},
        #{
    
    item.serialNumber},#{
    
    item.createTime}</foreach>
</insert>

Mapper interface Mapper is the interface of mybatis plug-in tk.Mapper, which has little to do with the content of this article

public interface ItemMapper extends Mapper<Item> {
    
    
    int insertByBatch(List<Item> itemList);
}

Service class

@Service
public class ItemService {
    
    
    @Autowired
    private ItemMapper itemMapper;
    @Autowired
    private SqlSessionFactory sqlSessionFactory;
    //批处理
    @Transactional
    public void add(List<Item> itemList) {
    
    
        SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH,false);
        ItemMapper mapper = session.getMapper(ItemMapper.class);
        for (int i = 0; i < itemList.size(); i++) {
    
    
            mapper.insertSelective(itemList.get(i));
            if(i%1000==999){
    
    //每1000条提交一次防止内存溢出
                session.commit();
                session.clearCache();
            }
        }
        session.commit();
        session.clearCache();
    }
    //拼接sql
    @Transactional
    public void add1(List<Item> itemList) {
    
    
        itemList.insertByBatch(itemMapper::insertSelective);
    }
    //循环插入
    @Transactional
    public void add2(List<Item> itemList) {
    
    
        itemList.forEach(itemMapper::insertSelective);
    }
}

Test class

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, classes = ApplicationBoot.class)
public class ItemServiceTest {
    
    
    @Autowired
    ItemService itemService;

    private List<Item> itemList = new ArrayList<>();
    //生成测试List
    @Before 
    public void createList(){
    
    
        String json ="{\n" +
                "        \"areaPosition\": \"TEST\",\n" +
                "        \"bottomHeight\": 5,\n" +
                "        \"factoryId\": \"0\",\n" +
                "        \"length\": 233.233,\n" +
                "        \"material\": \"Q345B\",\n" +
                "        \"name\": \"TEST\",\n" +
                "        \"package\": false,\n" +
                "        \"packageUnique\": \"45f8a0ba0bf048839df85f32ebe5bb81\",\n" +
                "        \"projectId\": \"094b5eb5e0384bb1aaa822880a428b6d\",\n" +
                "        \"projectName\": \"项目_TEST1\",\n" +
                "        \"serialNumber\": \"1/2\",\n" +
                "        \"setupPosition\": \"1B柱\",\n" +
                "        \"spec\": \"200X200X200\",\n" +
                "        \"topHeight\": 10,\n" +
                "        \"type\": \"Steel\",\n" +
                "        \"uniqueCode\": \"12344312\",\n" +
                "        \"weight\": 100\n" +
                "    }";
        Item test1 = JSON.parseObject(json,Item.class);
        test1.setCreateTime(new Date());
        for (int i = 0; i < 1000; i++) {
    
    //测试会修改此数量
            itemList.add(test1);
        }
    }
     //批处理
    @Test
    @Transactional
    public void tesInsert() {
    
    
        itemService.add(itemList);
    }
    //拼接字符串
    @Test
    @Transactional
    public void testInsert1(){
    
    
        itemService.add1(itemList);
    }
    //循环插入
    @Test
    @Transactional
    public void testInsert2(){
    
    
        itemService.add2(itemList);
    }
}

Test Results:

10 25 data insertions have been tested for many times, and the volatility is large, but they are basically at the level of 100 milliseconds.
Insert picture description here
The splicing SQL method reports errors when inserting 500 and 1000 data (it seems to be because the SQL statement is too long. This is related to the database type. Related, no other database testing): com.microsoft.sqlserver.jdbc.SQLServerException: The incoming tabular data stream (TDS) remote procedure call (RPC) protocol stream is incorrect. Too many parameters were provided in this RPC request. Should be at most 2100

it can be discovered

1. The time complexity of cyclic insertion is O(n), and the constant C is very large.
2. The time complexity of splicing SQL insertion (should) is O(logn), but the number of successful completions is not many, not sure
3. Batch processing The time complexity of the efficiency is O(logn), and the constant C is also relatively small

in conclusion

Although the efficiency of circularly inserting a single piece of data is extremely low, the amount of code is very small. In the case of using the tk.Mapper plug-in, only the code is required:

@Transactional
public void add1(List<Item> itemList) {
    
    
    itemList.forEach(itemMapper::insertSelective);
}

Therefore, it must be used when the amount of data to be inserted is small.

xml splicing sql is the least recommended way. There are a lot of xml and sql statements to write when using, it is easy to make mistakes and work efficiency is very low. The more important point is that although the efficiency is acceptable, when you really need efficiency, you hang up. What use do you want?

Batch execution is the recommended practice when inserting large amounts of data, and it is also more convenient to use.

Guess you like

Origin blog.csdn.net/ncw8080/article/details/113863439