mapper批量插入

1.常规方式的批量插入

sql语句

int bathNorm(List<Teacher> teacherList);

<insert id="bathNorm" parameterType="Teacher">
        insert into teacher (tname,age) values
        <foreach collection="list" item="teacher" separator="," close=";">
            (#{teacher.tname},#{teacher.age})
        </foreach>
    </insert>

java代码

StudentDao studentDao=null;
    String[] tnameArr = new String[]{"火", "水", "金", "木", "土"};
public void setup(){
        teacherDao= MyBatisTools.getInstance().openSession().getMapper(TeacherDao.class);
         Random random = new Random();
         // 构造测试数据  插入一万条
         for(int i = 0; i < 10000; i++) {
             Teacher teacher = new Teacher();
             int idx = random.nextInt(tnameArr.length);
             teacher.setTname(tnameArr[idx] +"_"+ (i + 1));
             teacher.setAge(i+1);
             testData.add(teacher);
         }
     }

test类

@test
  public void testbathbrom(){
         long start =System.currentTimeMillis();
         int rows=teacherDao.bathNorm(testData);
        System.out.println("插入数据行数:"+rows+"耗时:"+(System.currentTimeMillis()-start));
    }

数据源

jdbc.url=jdbc:mysql://localhost:3306/tushu
jdbc.driver=com.mysql.jdbc.Driver
jdbc.user=root
jdbc.password=root
jdbc.characterEncoding=utf8

xml配置

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--    引入外部配置-->
    <properties resource="jdbc.properties" />
    <!--    类型别名是为 Java 类型设置一个短的名字。 它只和 XML 配置有关,存在的意义仅在于用来减少类完全限定名的冗余-->
    <typeAliases>
        <typeAlias type="com.lanou3g.mybaties.bean.Teacher" alias="Teacher" />
        <typeAlias type="com.lanou3g.mybaties.bean.Student" alias="Student"/>
     </typeAliases>
    <!-- 配置不同环境的参数 -->
    <environments default="development">
        <!-- 开发环境数据库、事务配置 -->
        <environment id="development">
            <!-- 事务管理使用JDBC的事务 -->
            <transactionManager type="MANAGED"/>
            <!-- 配置开发环境数据源 -->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.user}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <!-- 注解方式       -->
        <mapper resource="mapper/TeacherMapper.xml" />

    </mappers>
</configuration>

配置的类

public class MyBatisTools {

    private static ConcurrentHashMap<String, SqlSessionFactory> factoryMap = new MyConcurrentHashMap();

    private static MyBatisTools myBatisTools;

    private MyBatisTools() {}

    public static MyBatisTools getInstance() {
        if(myBatisTools == null) {
            synchronized (MyBatisTools.class) {
                if(myBatisTools == null) {
                    myBatisTools = new MyBatisTools();
                }
            }
        }
        log.debug("当前一共有: " + factoryMap.size() +"个SqlSessionFactory实例");
        log.debug("他们分别是: " + factoryMap);
        return myBatisTools;
    }

    public SqlSessionFactory getSessionFactory() {
        return getSessionFactory(null);
    }

    public SqlSessionFactory getSessionFactory(String env) {
        try {
            // 1. 读入配置文件
            InputStream in = Resources.getResourceAsStream("mybaties.xml");
            // 2. 构建SqlSessionFactory(用于获取sqlSession)
            SqlSessionFactory sessionFactory = null;
            synchronized (factoryMap) {
                if(factoryMap.containsKey(env)) {
                    return factoryMap.get(env);
                } else {
                    sessionFactory = new SqlSessionFactoryBuilder().build(in, env);
                    factoryMap.put(env, sessionFactory);
                }
            }
            return sessionFactory;
        } catch (Exception e) {
            log.error("初始化SqlSessionFactory失败", e);
            return null;
        }
    }

    public SqlSession openSession() {
        return getSessionFactory(null).openSession();
    }

    public SqlSession openSession(boolean autoCommit) {
        return getSessionFactory(null).openSession(autoCommit);
    }

    public SqlSession openSession(ExecutorType executorType, boolean autoCommit) {
        return getSessionFactory(null).openSession(executorType, autoCommit);
    }
}

/**
 * 继承原生ConcurrentHashMap,处理null key问题
 */
class MyConcurrentHashMap extends ConcurrentHashMap {
    @Override
    public Object put(Object key, Object value) {
        if(key == null) {
            key = "null";
        }
        return super.put(key, value);
    }

    @Override
    public boolean containsKey(Object key) {
        if(key == null) {
            key = "null";
        }
        return super.containsKey(key);
    }

    @Override
    public Object get(Object key) {
        if(key == null) {
            key = "null";
        }
        return super.get(key);
    }
}

teacher类

public class Teacher {
    private Integer id;
    private String tname;
    private Integer age;

    public Teacher() {
    }

    public Teacher(String tname) {
        this.tname = tname;
    }

    @Override
    public String toString() {
        return "Teacher{" +
                "id=" + id +
                ", tname='" + tname + '\'' +
                ", age=" + age +
                "}\n";
    }
}

这种方式比较快,但是数据库默认上传数据是4M,超过就要修改数据库的默认值,比较有局限性。

2.使用ExecutorType.BATCH方式执行批量操作

配置如上
sql语句

<insert id="insertTeacher" parameterType="Teacher">
       insert into teacher(tname) values (#{tname});
    </insert>

java类

 @Test
    public void testBatchInsertByExecutorType() {
        SqlSessionFactory factory=MyBatisTools.getInstance().getSessionFactory();
        SqlSession sqlSession = factory.openSession(ExecutorType.BATCH, false);
        TeacherDao teacherDao = sqlSession.getMapper(TeacherDao.class);
        long start = System.currentTimeMillis();
        int rows = 0;
        int batchSize = 100;
        int count = 0;
        for(Teacher teacher : testData) {
            rows += teacherDao.insertTeacher(teacher);
            count ++;
            if(count % batchSize == 0) {
                sqlSession.flushStatements();
            }
        }
        sqlSession.flushStatements();
        sqlSession.commit();
        sqlSession.close();
        System.out.println(("插入数据行数: " + rows+", 耗时: " + (System.currentTimeMillis() - start)));
    }

这种插入的量没有限制,但是插入的比常规方式的慢。

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Java 中,如果你使用 MyBatis 框架,可以通过 Mapper 接口和 XML 配置文件实现批量插入数据。 首先,你需要在 Mapper 接口中定义一个方法,用于批量插入数据。例如: ```java import java.util.List; public interface YourMapper { void batchInsert(List<YourObject> objects); } ``` 接下来,在对应的 XML 配置文件中,实现该方法的 SQL 语句。例如: ```xml <!-- your-mapper.xml --> <mapper namespace="com.example.YourMapper"> <insert id="batchInsert" parameterType="java.util.List"> INSERT INTO your_table (column1, column2, ...) VALUES <foreach collection="list" item="item" separator=","> (#{item.property1}, #{item.property2}, ...) </foreach> </insert> </mapper> ``` 在上述示例中,`batchInsert` 方法接受一个 `List<YourObject>` 参数,其中 `YourObject` 是你要插入的对象类型。XML 配置文件中的 SQL 语句使用了 MyBatis 的 foreach 标签,遍历传入的对象列表,并将属性值插入到数据库表中。 最后,你可以在 Service 层调用 Mapper批量插入方法。例如: ```java import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class YourService { private final YourMapper mapper; @Autowired public YourService(YourMapper mapper) { this.mapper = mapper; } public void saveObjects(List<YourObject> objects) { mapper.batchInsert(objects); } } ``` 在上述示例中,`YourService` 类注入了 `YourMapper` 对象,然后在 `saveObjects` 方法中调用了 Mapper批量插入方法。 请注意,上述示例中的表名、列名以及对象的属性名需要根据你的实际情况进行修改。同时,需要配置正确的 MyBatis 配置文件和相关依赖,以使其能够正确运行。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值