MyBatis的五种批量查询实例总结

 更新时间:2023年02月28日 10:00:46   作者:谁是黄黄  
为了提高代码的执行效率,我们有时需要采用批量查询的查询方法,下面这篇文章主要给大家介绍了关于MyBatis的五种批量查询的相关资料,需要的朋友可以参考下

一.直接循环插入

@RestController
@RequestMapping("/mybatis3/user")
@RequiredArgsConstructor
public class UserController {

    private final IUserService iUserService;

    @GetMapping("/one")
    public Long one(){
       return iUserService.add();
    }
}

  Long add();

@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    private final UserMapper userMapper;

    @Override
    public Long add() {

        long start = System.currentTimeMillis();
        for (int i = 0; i < 10000; i++) {
            User user = new User();
            user.setUsername("name"+i);
            user.setPassword("password"+i);
            userMapper.insertUsers(user);
        }
        long end = System.currentTimeMillis();
        System.out.println("耗时:"+( end - start ) + "ms");
        return (end-start);
    }
    }

 Integer insertUsers(User user);

 <insert id="insertUsers" >
        insert into user(username,password)
        values (#{username}, #{password})
    </insert>

最终耗时:14s多

二.关闭MySql自动提交,手动进行循环插入提交

@RestController
@RequestMapping("/mybatis3/user")
@RequiredArgsConstructor
public class UserController {

    private final IUserService iUserService;

        @GetMapping("/one")
    public Long one(){
       return iUserService.add();
    }
}

 Long add2();

@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    private final UserMapper userMapper;

//    手动开启sql的批量提交
    private final   SqlSessionTemplate sqlSessionTemplate;

    @Override
    public Long add2(){
        //关闭自动提交
        SqlSession sqlSession = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        long start = System.currentTimeMillis();
        for (int i = 0; i < 10000; i++) {
            User user = new User();
            user.setUsername("name"+i);
            user.setPassword("password"+i);
            mapper.insertUsers(user);
        }
        //自动提交SQL
        sqlSession.commit();
        long end = System.currentTimeMillis();
        System.out.println("耗时:"+( end - start ) + "ms");
        return (end-start);
    }
    }

平均:0.12s

第三种:用List集合的方式插入数据库(推荐)

@RestController
@RequestMapping("/mybatis3/user")
@RequiredArgsConstructor
public class UserController {

    private final IUserService iUserService;

       @GetMapping("/one3")
    public Long one3(){
        return iUserService.add3();
    }
}

  Long add3();

@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    private final UserMapper userMapper;

  @Override
    public Long add3(){
        long start = System.currentTimeMillis();
        List<User> userList = new ArrayList<>();
        User user;
        for (int i = 0; i < 10000; i++) {
            user = new User();
            user.setUsername("name"+i);
            user.setPassword("password"+i);
            userList.add(user);
        }
        userMapper.insertUsersThree(userList);
        long end = System.currentTimeMillis();
        System.out.println("耗时:"+( end - start ) + "ms");
        return (end-start);
    }
    }

 Integer insertUsersThree(List<User> userList);

<insert id="insertUsersThree">
        insert into user(username,password)
        values
        <foreach collection="userList" item="user" separator=",">
            (#{user.username},#{user.password})
        </foreach>
    </insert>

第四种: MyBatis-Plus提供的SaveBatch方法

@RestController
@RequestMapping("/mybatis3/user")
@RequiredArgsConstructor
public class UserController {

    private final IUserService iUserService;

@GetMapping("/one4")
    public Long one4(){
        return iUserService.add4();
    }
}

  Long add4();

@Service
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {

    private final UserMapper userMapper;

@Override
    public Long add4() {
        long start = System.currentTimeMillis();

        List<User> userList= new ArrayList<>();
        User user ;
        for (int i = 0; i < 10000; i++) {
            user = new User();
            user.setUsername("name"+i);
            user.setPassword("password"+i);
            userList.add(user);
        }

        saveBatch(userList);
        long end = System.currentTimeMillis();
        System.out.println("耗时:"+( end - start ) + "ms");
        return (end-start);
    }
    }

直接报错:

看报错信息:

长串:Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.DataIntegrityViolationException: com.huang.mybatis3.mapper.UserMapper.insert (batch index #1) failed. Cause: java.sql.BatchUpdateException: Data truncation: Out of range value for column ‘id’ at row 1
; Data truncation: Out of range value for column ‘id’ at row 1; nested exception is java.sql.BatchUpdateException: Data truncation: Out of range value for column ‘id’ at row 1] with root cause

短串:Data truncation: Out of range value for column ‘id’ at row 1

翻译一下:

可以发现就是我们的id超出范围:

int类型改为bigint即可

故此我们可以得出一个结论:设置数据库id的时候设置为bigint还是蛮好的哈

平均时间:0.2s

第五种 MyBatis-Plus提供的InsertBatchSomeColumn方法(推荐)

InsertBatchSomeColumn方法了解

这个类的注解就写的很明白

扩展这个InsertBatchSomeColumn方法

@Slf4j
public class EasySqlInjector extends DefaultSqlInjector {

    @Override
    public List<AbstractMethod> getMethodList(Class<?> mapperClass, TableInfo tableInfo) {
        // 注意:此SQL注入器继承了DefaultSqlInjector(默认注入器),调用了DefaultSqlInjector的getMethodList方法,保留了mybatis-plus的自带方法
        List<AbstractMethod> methodList = super.getMethodList(mapperClass, tableInfo);
        methodList.add(new InsertBatchSomeColumn(i -> i.getFieldFill() != FieldFill.UPDATE));
        log.info("扩展的getMethodList方法被框架调用了");
        return methodList;
    }
}

扩展的方法注入bean容器

/**
 * @author Stone
 * @date 2023/1/3
 * @apiNote
 */
@Configuration
public class MybatisPlusConfig {
    @Bean
    public  EasySqlInjector sqlInjector(){
        return new EasySqlInjector();
    }
}

创建一个Mapper去实现我们的扩展的飞方法

public interface EasySqlInjectMapper<T> extends BaseMapper<T> {
    /**
     * 批量插入 仅适用于mysql
     *
     * @param entityList 实体列表
     * @return 影响行数
     */
    Integer insertBatchSomeColumn(Collection<T> entityList);
}

业务层

@Override
    public Long add5() {
        long start = System.currentTimeMillis();

        List<User> userList= new ArrayList<>();
        User user ;
        for (int i = 0; i < 10000; i++) {
            user = new User();
            user.setUsername("name"+i);
            user.setPassword("password"+i);
            userList.add(user);
        }

        userMapper.insertBatchSomeColumn(userList);
        long end = System.currentTimeMillis();
        System.out.println("耗时:"+( end - start ) + "ms");
        return (end-start);
    }

耗时: 0.2 s

总结 

到此这篇关于MyBatis的五种批量查询的文章就介绍到这了,更多相关MyBatis批量查询内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringBoot+阿里云OSS实现在线视频播放的示例

    SpringBoot+阿里云OSS实现在线视频播放的示例

    这篇文章主要介绍了SpringBoot+阿里云OSS实现在线视频播放的示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • springboot配置logback日志管理过程详解

    springboot配置logback日志管理过程详解

    这篇文章主要介绍了springboot配置logback日志管理过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-09-09
  • java 单例模式容易忽略的细节

    java 单例模式容易忽略的细节

    这篇文章主要介绍了java 单例模式容易忽略的细节,帮助大家更好的理解和使用java 单例模式,感兴趣的朋友可以了解下
    2020-12-12
  • Java中PageHelper分页后对list操作导致分页无效

    Java中PageHelper分页后对list操作导致分页无效

    在项目中使用分页插件的时候发现PageHelper插件失效了,本文就来介绍一下Java中PageHelper分页后对list操作导致分页无效的解决方法,感兴趣的可以了解一下
    2021-05-05
  • Java基础之反射详解

    Java基础之反射详解

    这篇文章主要介绍了教你怎么通过IDEA设置堆内存空间,文中有非常详细的代码示例,对正在使用IDEA的小伙伴们很有帮助哟,需要的朋友可以参考下
    2021-05-05
  • java中ThreadLocal的基本原理

    java中ThreadLocal的基本原理

    本文讲解了java中ThreadLocal的一些基本原理,文中关于ThreadLocal的原理讲解的非常详细,感兴趣的朋友一起看看吧
    2021-08-08
  • Springboot 全局时间格式化三种方式示例详解

    Springboot 全局时间格式化三种方式示例详解

    时间格式化在项目中使用频率是非常高的,当我们的 API​ 接口返回结果,需要对其中某一个 date​ 字段属性进行特殊的格式化处理,通常会用到 SimpleDateFormat​ 工具处理,这篇文章主要介绍了3 种 Springboot 全局时间格式化方式,需要的朋友可以参考下
    2024-01-01
  • Spring复杂对象创建的方式小结

    Spring复杂对象创建的方式小结

    这篇文章主要介绍了Spring复杂对象创建的三种方式,现在使用Spring如何创建这种类型的对象?Spring中提供了三种方法来创建复杂对象,需要的朋友可以参考下
    2022-01-01
  • 一文带你搞懂什么是BIO

    一文带你搞懂什么是BIO

    BIO英文全名是 blocking IO,也叫做 阻塞IO,是最容易理解、最容易实现的IO工作方式,本文就来通过一些简单的示例为大家讲讲什么是BIO吧
    2023-06-06
  • Spring Cloud 系列之服务调用 OpenFeign的实现

    Spring Cloud 系列之服务调用 OpenFeign的实现

    这篇文章主要介绍了Spring Cloud 系列之服务调用 OpenFeign的实现,需要的朋友可以参考下
    2020-11-11

最新评论