精华内容
下载资源
问答
  • 我们在写Mapper的时候,经常会通过注解的方式来写SQL语句,像下面这样。这要求我们传递的参数为一个具体的对象。 @Insert("INSERT INTO student (name, sex, addr) VALUES (#{name}, #{sex}, #{addr})") int ...

    本文代码地址:https://github.com/hawkingfoo/java-web

    一、概述

    我们在写Mapper的时候,经常会通过注解的方式来写SQL语句,像下面这样。这要求我们传递的参数为一个具体的对象。

    @Insert("INSERT INTO student (name, sex, addr) VALUES (#{name}, #{sex}, #{addr})")
    int insert(Student stu);
    

    但是,如果需要批量插入List<Student> studentList;不可能遍历studentList并依次执行插入语句,这样效率太差。
    还有一种是配置Mybatis的xml文件,反正题主觉得那个配置好复杂。有没有还是通过注解的方式,执行批量操作呢?

    二、批量执行

    我们回想下SQL语句,插入一条记录:

    INSERT INTO student (name, sex, addr) VALUES ("LiMing", 0, "Beijing");
    

    批量插入:

    INSERT INTO student (name, sex, addr) VALUES ("LiMing", 0, "Beijing"), ("LiNing", 0, "Shanghai");
    

    根据 id 删除一条记录:

    DELETE FROM student WHERE id = 1;
    

    根据ids批量删除:

    DELETE FROM student WHERE id IN (1, 2, 3);
    

    三、方法

    既然可以通过SQL语句批量执行,那我们可以修改注解。这里需要通过自定义Provider来实现。

    @Component
    @Mapper
    public interface StudentMapper {
        @Insert("INSERT INTO student (name, sex, addr) VALUES (#{name}, #{sex}, #{addr})")
        int insert(Student stu);
    
        @InsertProvider(type = Provider.class, method = "batchInsert")
        int batchInsert(List<Student> students);
    
        @Select("SELECT * FROM student WHERE id = #{id}")
        Student selectById(@Param("id") int id);
    
        @DeleteProvider(type = Provider.class, method = "batchDelete")
        int batchDelete(List<Student> students);
    
        @Select("SELECT * FROM student")
        List<Student> selectAll();
    
    
        class Provider {
            /* 批量插入 */
            public String batchInsert(Map map) {
                List<Student> students = (List<Student>) map.get("list");
                StringBuilder sb = new StringBuilder();
                sb.append("INSERT INTO student (name,sex,addr) VALUES ");
                MessageFormat mf = new MessageFormat(
                        "(#'{'list[{0}].name}, #'{'list[{0}].sex}, #'{'list[{0}].addr})"
                );
    
                for (int i = 0; i < students.size(); i++) {
                    sb.append(mf.format(new Object[] {i}));
                    if (i < students.size() - 1)
                        sb.append(",");
                }
                return sb.toString();
            }
    
            /* 批量删除 */
            public String batchDelete(Map map) {
                List<Student> students = (List<Student>) map.get("list");
                StringBuilder sb = new StringBuilder();
                sb.append("DELETE FROM student WHERE id IN (");
                for (int i = 0; i < students.size(); i++) {
                    sb.append("'").append(students.get(i).getId()).append("'");
                    if (i < students.size() - 1)
                        sb.append(",");
                }
                sb.append(")");
                return sb.toString();
            }
        }
    }

    也可以用如下定义(stackoverflow 中的回答我做了扩展): 

    批量插入:

       // 批量插入
        @Insert({
                "<script>",
                "insert into author(id, name)",
                "values ",
                "<foreach  collection='authorList' item='item' separator=','>",
                "( #{item.id,jdbcType=INTEGER},#{item.name,jdbcType=VARCHAR} )",
                "</foreach>",
                "</script>"
        })
        int insertBatch(@Param("authorList") List<Author> dmoList);
    
    

    调用使用:

    		// 批量插入
    List<Author> insertList = new ArrayList<>();
    Author a = new Author();
    a.setId( 4 );
    a.setName( "aa" );
    insertList.add( a );
    
    Author b = new Author();
    b.setId( 5 );
    b.setName( "bb" );
    insertList.add( b );
    
    authorMapper.insertBatch( insertList );

    这种方法有个好处,就是如果数据很大,因为mysql sqlserver等数据库sql 语句 1M 4M 的大小限制,mybatis本身没有这个限制,所以只要控制调用的地方就可以了, 分割 dmoList 为比如大于1000 大小 批量插入就可以了。     

    批量删除: 

       // 批量删除
        @Delete({
             "<script>" +
                     "delete from author where id in " +
                "<foreach item='eid' collection='idList' open='(' separator=',' close=')'>\n" +
                     "#{eid}\n" +
                     "</foreach>" +
                     "</script>"
        })
        int deleteBatch(@Param("idList") List< Integer > idList );

    调用:

    List<Integer> list = new ArrayList<>();
    Integer i = new Integer(3);
    Integer i2 = new Integer( 4 );
    list.add( i );
    list.add( i2 );
    
    authorMapper.deleteBatch( list );

    批量修改:

    spring.datasource.url=jdbc:mysql://localhost/yangzm?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true&allowMultiQueries=true

    要增加这个项,否则批量更新不能成功: &allowMultiQueries=true

        @Update({
                "<script>" +
                        "<foreach collection='authorList' item='item' separator=';' open='' close='\n'>\n" +
                        "    UPDATE author <set> name = #{item.name} </set>" +
                        "    WHERE  id = #{item.id}  \n" +
                        "</foreach></script>"
        })
        int updateBatch(@Param("authorList") List<Author> aList);

    调用:

    List<Author> aList = new ArrayList<>();
    Author a = new Author();
    a.setId(4);
    a.setName("change");
    aList.add(a);
    
    Author b = new Author();
    b.setId(5);
    b.setName("change2");
    aList.add(b);
    
    authorMapper.updateBatch(aList);

    现在这几种情况都可以运行了:(^ ^) 

     

     

    展开全文
  • mybatis用注解的方式批量插入数据

    千次阅读 2019-05-28 11:16:34
    批量插入的方式用两分钟左右,用时减少一半。插入一万条数据在12秒左右 CommodityController代码 package security.controller; import java.util.ArrayList; import java.util.Date; import java.uti...

    前言:我尝试过用for循环直接将10W数据插入mysql数据库,用时四分半左右。用批量插入的方式用两分钟左右,用时减少一半。插入一万条数据在12秒左右

     

    CommodityController代码

    package security.controller;
    
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    import cn.hutool.core.util.RandomUtil;
    import security.service.CommodityService;
    
    @Controller
    @RequestMapping("commodity")
    public class CommodityController {
    	private static Logger log =LoggerFactory.getLogger(CommodityController.class);
    	@Autowired
    	private CommodityService commodityService;
    	
    	@RequestMapping("add")
    	public void add() {
    		long systime = new Date().getTime();//当前系统时间
           
    		String sex = "a";
    		String money = "100";
    		int frequency = 12;
    		String chepai = "M12345";
    		String phone = "123456789";
    		List<Map<String, Object>> list = new ArrayList<Map<String,Object>>();
    		for(int i=0;i<10;i++) {
    			for(int j=0;j<10000;j++) {
    				String id = RandomUtil.randomUUID();
    				String username = "a"+j;
    				Map<String, Object> usermap = new HashMap<String, Object>();
    				usermap.put("sex", sex);
    				usermap.put("id", id);
    				usermap.put("username", username);
    				usermap.put("money", money);
    				usermap.put("chepai", chepai);
    				usermap.put("phone", phone);
    				usermap.put("frequency", frequency);
    				usermap.put("beizhu", "备注");
    				list.add(usermap);
    			}
    			log.debug("执行第: "+i+" 组数据,组内数据条数为:"+list.size()+" 条");
    			
    			commodityService.addservice(list);
    			list.clear();
    			log.debug("集合中数据后的数据条数为:"+list.size()+" 条");
    		}
    		 long oldtime = new Date().getTime();//相比较的时间
    	     Long time = (oldtime-systime);//相差毫秒数
    	     log.debug("用时:"+time);
    		
    	}
    }
    

    CommodityService代码

    注释掉的部分为用for循环传入参数插入数据库的传值

    package security.service;
    
    import java.util.List;
    import java.util.Map;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import security.mapper.CommodityMapper;
    
    @Service
    public class CommodityService {
    	
    	@Autowired
    	private CommodityMapper commodityMapper;
    	
    	/*
    	 * public int addservice(String id,String name,String phone, @Param("chepai")
    	 * String chepai, @Param("money") String money ,@Param("sex") String sex
    	 * ,@Param("beizhu") String beizhu) { return commodityMapper.add(id, name,
    	 * phone, chepai, money, sex, beizhu); }
    	 */
    	public int addservice(List<Map<String, Object>> list) {
    		return commodityMapper.add(list);
    	}
    }
    

    CommodityMapper代码

    注释掉的部分为用for循环传入参数插入数据库的传值及sql语句

     

    package security.mapper;
    
    import java.util.List;
    import java.util.Map;
    
    import org.apache.ibatis.annotations.Insert;
    import org.apache.ibatis.annotations.Param;
    
    public interface CommodityMapper {
    
    	/*
    	 * @Insert("INSERT INTO user(id,username,sex,frequency,money,chepai,phone,beizhu) VALUES(#{id},#{name},#{sex},0,#{money},#{chepai},#{phone},#{beizhu})"
    	 * ) int add(@Param("id") String id,@Param("name") String name,@Param("phone")
    	 * String phone, @Param("chepai") String chepai, @Param("money") String money
    	 * ,@Param("sex") String sex ,@Param("beizhu") String beizhu);
    	 */
    	 
    	 @Insert("<script>"  +
    		 "INSERT INTO user(id,username,sex,frequency,money,chepai,phone,beizhu) "
    	 		+ "VALUES <foreach collection=\"list\" item=\"usermap\" index=\"index\" separator=\",\">" + 
    	 		"(#{usermap.id},#{usermap.username},#{usermap.sex},#{usermap.frequency},#{usermap.money},#{usermap.chepai},#{usermap.phone},#{usermap.beizhu})" + 
    	 		" </foreach>"
    	 		+ "</script>")
    	 int add(@Param("list") List<Map<String, Object>> list);
    	 
    }
    

    @Insert()括号里面有的会加上{}(如下图查询语句所示),可是我加上后会导致拼接sql语句错误,具体原因没有分析出来。

    展开全文
  • 春季常用注解redis视频集合,看完这些别说不会redis1,批量插入<插入id =“ insertBatch”parameterType =“ java.util.List”>插入t_student(姓名,年龄,班级)价值观<foreachcollection =“列表”item ...

    3949fb5aebfe96c9d998640a4a0f8a7b.png
    • 春季常用注解
    • redis视频集合,看完这些别说不会redis

    1,批量插入

    <插入

    id =“ insertBatch”

    parameterType =“ java.util.List”>

    插入

    t_student(姓名,年龄,班级)

    价值观

    <foreach

    collection =“列表”

    item =“ item”

    index =“ index”

    spacer =“,”>

    #{item.name,jdbcType = VARCHAR},

    #{item.age,jdbcType = INTEGER},

    #{item.class,jdbcType = LONGVARCHAR}

    </ foreach>

    </ insert>

    2,批量更新

    方式一:

    <update id =“ updateBatch”>

    <foreach

    collection =“列表”

    spacer =“;”

    item =“ stud”>

    更新t_studetn集

    名称=#{stud.name},

    年龄=#{stud.age},

    class =#{stud.sex},

    其中id =#{stud.id}

    </ foreach>

    </ update>

    方式二:

    <更新

    id =“ updateBatch”

    parameterType =“ list”>

    更新t_student

    设置名称=案例ID

    <foreach

    collection =“列表”

    item =“ i”

    index =“ index”>

    当#{i.id}然后## i.name}

    </ foreach>

    结束,

    年龄=案件编号

    <foreach

    collection =“列表”

    item =“ i”

    index =“ index”>

    当#{i.id}然后## i.age

    </ foreach>

    结束

    在哪里

    <foreach

    collection =“列表”

    spacer =“ or”

    item =“ i”

    index =“ index”>

    id =#{i.id}

    </ foreach>

    </ update>

    3,批量删除

    <delete id =“ deleteBatchByParams”>

    从中删除

    学生

    哪里

    ID IN

    <foreach

    collection =“ ids”

    item =“ item”

    index =“ index”

    open =“(” close =“)”

    spacer =“,”>

    #{项目}

    </ foreach>

    </ delete>

    6a29045529759d39d6a9c2cd6f9b87dc.png
    展开全文
  • 我们在写Mapper的时候,经常会通过注解的方式来写SQL语句,像下面这样。这要求我们传递的参数为一个具体的对象。 @Insert("INSERT INTO student (name, sex, addr) VALUES (#{name}, #{sex}, #{addr})"...

    本文代码地址:https://github.com/hawkingfoo/java-web

    一、概述

    我们在写Mapper的时候,经常会通过注解的方式来写SQL语句,像下面这样。这要求我们传递的参数为一个具体的对象。

    @Insert("INSERT INTO student (name, sex, addr) VALUES (#{name}, #{sex}, #{addr})")
    int insert(Student stu);

    但是,如果需要批量插入List<Student> studentList;不可能遍历studentList并依次执行插入语句,这样效率太差。
    还有一种是配置Mybatis的xml文件,反正题主觉得那个配置好复杂。有没有还是通过注解的方式,执行批量操作呢?

    二、批量执行

    我们回想下SQL语句,插入一条记录:

    INSERT INTO student (name, sex, addr) VALUES ("LiMing", 0, "Beijing");

    批量插入:

    INSERT INTO student (name, sex, addr) VALUES ("LiMing", 0, "Beijing"), ("LiNing", 0, "Shanghai");

    根据 id 删除一条记录:

    DELETE FROM student WHERE id = 1;

    根据ids批量删除:

    DELETE FROM student WHERE id IN (1, 2, 3);

    三、方法

    既然可以通过SQL语句批量执行,那我们可以修改注解。这里需要通过自定义Provider来实现。

    @Component
    @Mapper
    public interface StudentMapper {
        @Insert("INSERT INTO student (name, sex, addr) VALUES (#{name}, #{sex}, #{addr})")
        int insert(Student stu);
    
        @InsertProvider(type = Provider.class, method = "batchInsert")
        int batchInsert(List<Student> students);
    
        @Select("SELECT * FROM student WHERE id = #{id}")
        Student selectById(@Param("id") int id);
    
        @DeleteProvider(type = Provider.class, method = "batchDelete")
        int batchDelete(List<Student> students);
    
        @Select("SELECT * FROM student")
        List<Student> selectAll();
    
    
        class Provider {
            /* 批量插入 */
            public String batchInsert(Map map) {
                List<Student> students = (List<Student>) map.get("list");
                StringBuilder sb = new StringBuilder();
                sb.append("INSERT INTO student (name,sex,addr) VALUES ");
                MessageFormat mf = new MessageFormat(
                        "(#'{'list[{0}].name}, #'{'list[{0}].sex}, #'{'list[{0}].addr})"
                );
    
                for (int i = 0; i < students.size(); i++) {
                    sb.append(mf.format(new Object[] {i}));
                    if (i < students.size() - 1)
                        sb.append(",");
                }
                return sb.toString();
            }
    
            /* 批量删除 */
            public String batchDelete(Map map) {
                List<Student> students = (List<Student>) map.get("list");
                StringBuilder sb = new StringBuilder();
                sb.append("DELETE FROM student WHERE id IN (");
                for (int i = 0; i < students.size(); i++) {
                    sb.append("'").append(students.get(i).getId()).append("'");
                    if (i < students.size() - 1)
                        sb.append(",");
                }
                sb.append(")");
                return sb.toString();
            }
        }
    }
    展开全文
  • 坑还是有点,特别是加spring事务,还有就是删除文件不稳定,还有接收参数时一些注解会造成误导,有些注解也是不能用 的,请慎重,只做参考(上传TXT文件)。 1.准备: <!-- ...
  • MyBatis批量插入List数据实现(MySQL)1. xml文件2. mapper--java3. 封装成对象 1. xml文件 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" ...
  • mybatis-3.2.2.jar、mybatis-spring-1.2.2.jar、mysql-connector-java-5.1.32.jar 2.Spring配置文件 [html] view plain copy  bean id="sqlSessionFactory" class="org.my
  • Mybatis 批量插入

    2019-11-18 18:12:20
    mapper接口 int addBatchFarmDevice(@Param("devices") List<... 注意:@Param(“devices”)注解不能省 mapper.xml <insert id="addBatchFarmDevice" parameterType="java.util.List"> ...
  • 春季常用注解redis视频集合,看完这些别说不会redis1,批量插入id =“ insertBatch”parameterType =“ java.util.List”>插入t_student(姓名,年龄,班级)价值观collection =“列表”item =“ item”index =“ ...
  • 1.使用到的jar包如下:mybatis-3.2.2.jar、mybatis-spring-1.2.2.jar、mysql-connector-java-5.1.32.jar2.Spring配置文件3.mapper.xml文件/p>PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"...
  • 1、升级Mybatis版本到3.3.1。官方在这个版本中加入了批量新增返回主键id的功能 2、在Dao中不能使用@param注解。...-- insertForeachWord 批量插入 --> <insert id="insertForeachWord" parameterType=".
  • MyBatis简介MyBatis是一个支持普通SQL查询...MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录。一、mybiats foreach标签forea...
  • MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录。 一、mybiats foreach标签 foreach的主要用在构建in条件中,它可以在...
  • 官方在这个版本中加入了批量新增返回主键id的功能 <insert>标签中添加 useGeneratedKeys="true" keyProperty="id" 在Dao中不能使用@param注解 Mapper.xml中使用list变量(parameterType=“java.util.List”)...
  • MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录。 一、mybiats foreach标签 foreach的主要用在构建in条件中,它可以在...
  • mybatis实现的两种批量插入数据

    千次阅读 2018-04-14 16:39:11
    什么是mbatis: mybatis是一个优秀的基于java的持久层框架,它...mybatis通过xml或注解的方式将要执行的各种statement配置起来,并通过java对象和statement中sql的动态参数进行映射生成最终执行的sql语句,最后由my
  • MyBatis简介MyBatis是一个支持普通SQL查询...MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录。一、mybiats foreach标签forea...
  • 相比以前可用,启动时加用了一个@postconstruct注解的方法,所以,这个类是通过主线程加载的,看main线程的堆栈信息足够了 堆栈信息 目前main线程处于waiting on condition Java Stack at sun.misc.Unsafe.park...
  • 通过简单的 XML 或注解来配置和映射 Java对象 到 数据库中的记录 官方地址:https://mybatis.org/mybatis-3/ 核心流程? 每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心 SqlSessionFactory 的...
  • 因为插件是本人兴之所至至所临时发布的项目(本人已近三年未做JAVA开发,代码水平请大家见谅),但基本插件都是在实际项目中经过检验的请大家放心使用,但因为项目总体主要数据库为MySQL,Mybatis实现使用Mapper.xml...
  • 自动生成PO和DAO的Java类,DAO支持分页查询,根据id查询,分割插入,批量插入,更新,替换删除,批量删除。 UserDao.java内容如下: @Mapper public interface UserDao extends BaseDao< UserDao> { /* * 分页...
  • 编写数据迁移的小工具,需要将大量整理好的对象数据插入不同的表中,按照原有的方式,工作量很大,因此考虑利用反射机制动态 + mybaits 实现动态生成Sql并批量入库 代码 利用 mybatis 注解 @InsertProvider 指定...
  • 精通Java Web整合开发(JSP+AJAX+Struts+Hibernate)(第2版)

    千次下载 热门讨论 2012-11-29 14:55:20
    10.6.1 批量插入437 10.6.2 批量更新438 10.6.3 批量删除439 10.7 hibernate的事务管理439 10.7.1 事务边界声明440 10.7.2 并发控制440 10.7.3 悲观锁441 10.7.4 乐观锁442 10.8 hibernate的缓存机制445 10.8.1 ...
  • Java开发实战1200例.第2卷.part3

    热门讨论 2013-05-08 22:46:34
    实例084 使用UNION ALL语句批量插入数据 156 实例085 更新指定记录 157 实例086 将数据表清空 159 第4章 SQL语句应用技术 160 4.1 聚集函数与日期查询 161 实例087 利用SUM函数实现数据汇总 161 实例088 利用AVG函数...
  • Java开发实战1200例.第2卷.part2

    热门讨论 2013-05-08 22:45:35
    实例084 使用UNION ALL语句批量插入数据 156 实例085 更新指定记录 157 实例086 将数据表清空 159 第4章 SQL语句应用技术 160 4.1 聚集函数与日期查询 161 实例087 利用SUM函数实现数据汇总 161 实例088 利用AVG函数...

空空如也

空空如也

1 2 3
收藏数 46
精华内容 18
关键字:

java批量插入注解

java 订阅