Mybatis-批量執行


一、使用動態SQL 中的 Foreach 批量插入

1.MySQL

// 實體類

public class MyUser {
    private Integer id;
    private String name;
    private Integer age;
    private Dept dept;


public class Dept {
    private Integer id;
    private String name;
    private List<MyUser> myUsers;

SQL

<!-- 一條 SQL -->
<!--public Boolean addMyUsers(@Param("users") List<MyUser> users);-->
<insert id="addMyUsers">
    insert into myuser(name,age,did) values
    <foreach collection="users" item="user" separator=",">
      (#{user.name},#{user.age},#{user.dept.id})
    </foreach>
</insert>

<!-- 多條 SQL -->
<!-- 一次執行多條 SQL 需在 JDBC 數據庫連接屬性添加 allowMultiQueries=true -->
<!--public Boolean addMyUsers(List<MyUser> users);-->
<insert id="addMyUsers">
    <foreach collection="list" item="user" separator=";">
        insert into myuser(name,age,did) values (#{user.name},#{user.age},#{user.dept.id})
    </foreach>
</insert>

測試代碼

/**
 * driver=com.mysql.cj.jdbc.Driver
 * url=jdbc:mysql://192.168.8.136:3306/mybatis?allowMultiQueries=true
 * username=root
 * password=root
 */
public static void main(String[] args) {
    SqlSession session = null;
    try {
        InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        session = sqlSessionFactory.openSession();

        MyUserMapper mapper = session.getMapper(MyUserMapper.class);

        Dept dept = new Dept(2,null);
        MyUser myUser1 = new MyUser(null,"xsa",34,dept);
        MyUser myUser2 = new MyUser(null,"fgb",24,dept);
        MyUser myUser3 = new MyUser(null,"wdx",18,dept);
        List<MyUser> list = new ArrayList<>();
        list.add(myUser1);
        list.add(myUser2);
        list.add(myUser3);
        mapper.addMyUsers(list);
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (session != null) {
            session.close();
        }
    }
}

2.Oracle

<!-- Oracle數據庫批量保存,Oracle不支持 values(),(),()
    1、多個insert放在begin - end里面
        begin
            insert into employees(employee_id,last_name,email)
            values(employees_seq.nextval,'test_001','test_001@atguigu.com');
            insert into employees(employee_id,last_name,email)
            values(employees_seq.nextval,'test_002','test_002@atguigu.com');
        end;
    2、利用中間表:
        insert into employees(employee_id,last_name,email)
           select employees_seq.nextval,lastName,email from(
                  select 'test_a_01' lastName,'test_a_e01' email from dual
                  union
                  select 'test_a_02' lastName,'test_a_e02' email from dual
                  union
                  select 'test_a_03' lastName,'test_a_e03' email from dual
           ) -->
<insert id="addEmps" databaseId="oracle">
    <!-- oracle第一種批量方式 -->
    <foreach collection="emps" item="emp" open="begin" close="end;">
        insert into employees(employee_id,last_name,email) values(employees_seq.nextval,#{emp.lastName},#{emp.email});
    </foreach>

    <!-- oracle第二種批量方式  -->
    insert into employees(employee_id,last_name,email)
    <foreach collection="emps" item="emp" separator="union" open="select employees_seq.nextval,lastName,email from(" close=")">
        select #{emp.lastName} lastName,#{emp.email} email from dual
    </foreach>
</insert>
<sql id="insertColumn">
    <if test="_databaseId=='oracle'">
        employee_id,last_name,email
    </if>
    <if test="_databaseId=='mysql'">
        last_name,email,gender,d_id
    </if>
</sql>

 

二、使用 Mybatis 的批量執行器

1.單獨使用

public static void main(String[] args) {
    SqlSession session = null;
    try {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        // 獲取批量執行器,設置不自動提交(默認 false)
        session = sqlSessionFactory.openSession(ExecutorType.BATCH,false);

        UserMapper mapper = session.getMapper(UserMapper.class);
        User user = new User();

        long start = System.currentTimeMillis();
        for (int i = 0; i < 1000; i++) {
            user.setName(UUID.randomUUID().toString());
            user.setAge(25);
            mapper.insertUser(user);
        }
        long end = System.currentTimeMillis();

        //批量:預編譯sql一次 ==> 設置參數(1000次)===> 執行(1次)===> 執行時長:889
        //非批量:(預編譯sql=設置參數=執行)(1000次) ===> 執行時長:8812
        System.out.println("執行時長:"+(end-start));

        // 使用 JDBC 事務需管理要手動提交事務
        session.commit();
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        if (session != null) {
            session.close();
        }
    }
}

 

2.在 SSM 中使用

首先給容器中添加一個可批量執行的 SqlSession,兩種方式

xml 方式

<!--配置一個可以進行批量執行的sqlSession  -->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
    <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactoryBean"></constructor-arg>
    <constructor-arg name="executorType" value="BATCH"></constructor-arg>
</bean>

代碼方式

/**
 * 配置一個可以進行批量執行的 sqlSession
 */
@Bean
public SqlSessionTemplate getSqlSessionTemplate(SqlSessionFactoryBean sqlSessionFactoryBean) throws Exception {
    /**
     * Simple Executor -- SIMPLE 普通的執行器,默認
     * Reuse Executor -執行器會重用預處理語句(prepared statements)
     * Batch Executor --批量執行器
     */
    SqlSessionTemplate sessionTemplate = new SqlSessionTemplate(sqlSessionFactoryBean.getObject(), ExecutorType.BATCH);
    return sessionTemplate;
}

使用批量執行,在 service 中注入即可

// @Autowired
// private SqlSessionTemplate sqlSessionTemplate;
@Autowired
private SqlSession sqlSession;

public List<Employee> getEmps(){
    EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
    return employeeMapper.getEmps();
}

 


https://www.cnblogs.com/jhxxb/p/10451387.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM