IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 工作中遇到的问题(ZDYA) -> 正文阅读

[Java知识库]工作中遇到的问题(ZDYA)

关于mybatis的三种批量插入以及效率比较

1.表结构

CREATE TABLE `t_user` (
  `id` varchar(32) CHARACTER SET utf8 NOT NULL COMMENT '主键',
  `name` varchar(50) CHARACTER SET utf8 DEFAULT NULL COMMENT '用户名',
  `del_flag` char(1) CHARACTER SET utf8 DEFAULT NULL COMMENT '删除标示',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;

2.1 jdbc.properties配置

mysql.driver=com.mysql.jdbc.Driver
mysql.url=jdbc:mysql://127.0.0.1:3306/ssm
mysql.username=root
mysql.password=admin
#定义初始连接数
mysql.initialSize=1
#定义最大连接数
mysql.maxActive=20
#定义最大空闲
mysql.maxIdle=20
#定义最小空闲
mysql.minIdle=1
#定义最长等待时间
mysql.maxWait=60000

2.2 spring-mybatis.xml配置

<context:component-scan base-package="com.win.ssm"/>
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="${mysql.driver}"/>
    <property name="url" value="${mysql.url}"/>
    <property name="username" value="${mysql.username}"/>
    <property name="password" value="${mysql.password}"/>
    <!-- 初始化链接大小-->
<property name="initialSize" value="${mysql.initialSize}"/>
    <!-- 连接池最大数量-->
<property name="maxActive" value="${mysql.maxActive}"/>
    <!-- 连接池最大空闲-->
<property name="maxIdle" value="${mysql.maxIdle}"/>
    <!-- 连接池最小空闲 -->
<property name="minIdle" value="${mysql.minIdle}"></property>
    <!-- 获取连接最大等待时间-->
<property name="maxWait" value="${mysql.maxWait}"/>
</bean>
<!-- spring与mybatis整合类 -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource"/>
    <!-- 查找接口的别名 -->
<property name="typeAliasesPackage" value="com.win"/>
    <!-- 自动扫描mapping.xml文件-->
<property name="mapperLocations" value="classpath:/mapping/*.xml"/>
</bean>

<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
    <constructor-arg index="0" ref="sqlSessionFactory" />
    <!--<constructor-arg index="1" value="BATCH" />-->
</bean>

<!-- 扫描DAO接口 -->
<bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <property name="basePackage" value="com.win.ssm.dao"/>
    <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>
<!-- 事务管理 -->
<bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>

第一种:普通for循环插入

①junit类

@Test
public void testInsertBatch2() throws Exception {
    long start = System.currentTimeMillis();
    User user;
    SqlSession sqlSession = sqlSessionTemplate.getSqlSessionFactory().openSession(false);
    UserDao mapper = sqlSession.getMapper(UserDao.class);
    for (int i = 0; i < 500; i++) {
        user = new User();
        user.setId("test" + i);
        user.setName("name" + i);
        user.setDelFlag("0");
        mapper.insert(user);
    }
    sqlSession.commit();
    long end = System.currentTimeMillis();
    System.out.println("---------------" + (start - end) + "---------------");
}

②xml配置

<insert id="insert">
    INSERT INTO t_user (id, name, del_flag)
          VALUES(#{id}, #{name}, #{delFlag})
</insert>

第二种:mybatis BATCH模式插入

①junit类

@Test
public void testInsertBatch2() throws Exception {
    long start = System.currentTimeMillis();
    User user;
    SqlSession sqlSession = sqlSessionTemplate.getSqlSessionFactory().openSession(ExecutorType.BATCH, false);//跟上述sql区别
    UserDao mapper = sqlSession.getMapper(UserDao.class);
    for (int i = 0; i < 500; i++) {
        user = new User();
        user.setId("test" + i);
        user.setName("name" + i);
        user.setDelFlag("0");
        mapper.insert(user);
    }
    sqlSession.commit();
    long end = System.currentTimeMillis();
    System.out.println("---------------" + (start - end) + "---------------");
}

②xml配置与第一种②中使用相同

第三种:foreach方式插入

①junit类

@Test
public void testInsertBatch() throws Exception {
    long start = System.currentTimeMillis();
    List<User> list = new ArrayList<>();
    User user;
    for (int i = 0; i < 10000; i++) {
        user = new User();
        user.setId("test" + i);
        user.setName("name" + i);
        user.setDelFlag("0");
        list.add(user);
    }
    userService.insertBatch(list);
    long end = System.currentTimeMillis();
    System.out.println("---------------" + (start - end) + "---------------");
}

②xml配置

 <insert id="insertBatch">
    INSERT INTO t_user
            (id, name, del_flag)
    VALUES
    <foreach collection ="list" item="user" separator =",">
         (#{user.id}, #{user.name}, #{user.delFlag})
    </foreach >
</insert>

特别注意:mysql默认接受sql的大小是1048576(1M),即第三种方式若数据量超过1M会报如下异常:(可通过调整MySQL安装目录下的my.ini文件中[mysqld]段的"max_allowed_packet = 1M")

nested exception is com.mysql.jdbc.PacketTooBigException: Packet for query is too large (5677854 > 1048576).

You can change this value on the server by setting the max_allowed_packet' variable.

结果对比:

第一种第二种第二种
500条77427388622
1000条1529015078746
5000条780111773501172
10000条3974722011801205

项目实例:

service:

/**
 * DatePermission 表数据服务层接口
 */
public interface DatePermissionService {

    /**
     * 新增用户所具有的仓库
     */
    void save(Long userId,List<Long> list);

}

serviceimpl:

@Slf4j
@Service
public class DatePermissionServiceImpl implements DatePermissionService {

    @Autowired
    private DatePermissionMapper datePermissionMapper;

    @Override
    public void save(Long userId, List<Long> list) {

        List<DatePermissionEntity> entityList = new ArrayList<>();
        for (Long aLong : list) {
            DatePermissionEntity entity = new DatePermissionEntity();
            entity.setUserId(userId);
            entity.setWarehousesId(aLong);
            entityList.add(entity);
        }
        datePermissionMapper.insertBatch(entityList);
    }
}

mapper:

public interface DatePermissionMapper extends BaseMapper<DatePermissionEntity> {

    void insertBatch(List<DatePermissionEntity> list);
}

xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="xxx.DatePermissionMapper">

    <insert id="insertBatch">
        INSERT INTO user_warehouses
        (user_id, warehouses_id)
        VALUES
        <foreach collection ="list" item="datePermissionEntity" separator =",">
            (#{datePermissionEntity.userId}, #{datePermissionEntity.warehousesId})
        </foreach >
    </insert>

</mapper>

实体类:

@TableName(value = "user_warehouses")
public class DatePermissionEntity extends BaseEntity {

    @TableField(exist = false)
    private static final long serialVersionUID = 1L;

    /**
     * 主键
     */
    @TableId(type = IdType.AUTO)
    private Long id;

    /**
     * 用户Id
     */
    private Long userId;

    /**
     * 仓库Id
     */
    private Long warehousesId;

	get/set()

表字段:
在这里插入图片描述
测试结果:
在这里插入图片描述

关于分割字符串(按逗号分割字符串/字符串分割成数组)

分割字符串

List<Long> ids = Arrays.asList(roleIds.split(",")).stream().map(s -> 
Long.parseLong(s.trim())).collect(Collectors.toList());

项目实例:

 @PostMapping("delete")
    public JsonResult delete(String roleIds) {
        List<Long> ids = Arrays.asList(roleIds.split(",")).stream().map(s -> Long.parseLong(s.trim())).collect(Collectors.toList());
        for (Long id : ids) {
            MagGuserRoleEntity guserRoleEntity = new MagGuserRoleEntity();
            guserRoleEntity.setRoleId(id);
            MagStaffRoleEntity staffRoleEntity = new MagStaffRoleEntity();
            staffRoleEntity.setRoleId(id);
            Integer guserRoleCnt = magGuserRoleService.selectCount(guserRoleEntity);
            Integer staffRoleCnt = magStaffRoleService.selectCount(staffRoleEntity);
            if (guserRoleCnt > 0 || staffRoleCnt > 0) {
                MagRoleEntity role = magRoleService.selectById(id);
                return JsonResult.resultError("角色[" + role.getName() + "]已被使用,不可删除!");
            }
        }
        magRoleService.deleteBatchIds(ids);
        return JsonResult.resultSuccess("删除成功!");
    }

同样的组装字符串/拼接字符串

info.setPermissionIds(Joiner.on(",").join(permIds));

项目实例:

@RequestMapping("info")
    public JsonResult info(Long id) {
        PerFrontUserEntity entity = userSessionRedisUtil.getSessionUserObjInfo(request);
        if (id == null || id < 0) {
            return JsonResult.resultError("参数错误");
        }
        MagRoleEntity qo = new MagRoleEntity();
        qo.setId(id);
        qo.setTenId(entity.getTenId());
//		qo.setTenId(getTenId(entity.getTenId()));
        qo.setGuserId(entity.getGuserId());
        MagRoleEntity info = magRoleService.findInfo(qo);

        if (info != null) {
            //角色拥有的所有权限(包含子、父级)
            List<Long> permIds = magRolePermissionService.getPermIdsByRole(id);
            //角色拥有的父权限
            List<Long> pIds = new ArrayList<>();
            if (!CollectionUtils.isEmpty(permIds)) {
                for (int i = 0; i < permIds.size(); i++) {
                    MagPermissionEntity permissionEntity = magPermissionService.selectById(permIds.get(i));
                    //排除一级父权限
                    if (permissionEntity.getPid() != null) {
                        pIds.add(permissionEntity.getPid().longValue());
                    }
                }
                permIds.removeAll(pIds);
            }
            info.setPermissionIds(Joiner.on(",").join(permIds));
            return JsonResult.resultSuccess(info);
        }
        return JsonResult.resultError("该角色不存在");
    }
  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-03-22 20:22:50  更:2022-03-22 20:24:28 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 7:51:31-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码