Mybatis---- 批量操作sql語句

前言

業務中多條sql語句一起執行十分常見。今天我們介紹三種方式來完成批量操作sql語句。

1. 原生JDBC形式

在原生的JDBC中Statement,PreparedStatement可以通過addBatch() 添加多條sql語句,並通過executeBatch() 執行多條sql。
下面只是關於批量操作sql的代碼(完整使用JDBC操作數據庫的流程可以參考使用JDBC連接數據庫)

  //使用JDBC實現批量操作sql語句
    @Test
    public void TestBatch() throws Exception {
    	//數據庫的配置
    	String driver = "com.mysql.jdbc.Driver";
		String url = "jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8&allowMultiQueries=true";
 		String username = "root";
        
        Connection coon = null;
        Statement stm = null;

        // 1. 加載連接驅動
        Class.forName(driver);
        //2. 獲取數據庫連接
        coon = DriverManager.getConnection(url,username,"");
        //3.獲取sql執行對象
        stm = coon.createStatement();

        //4.編寫要批量執行的sql語句
        String sql1 = "insert into user1(name,pwd) values('b','bbb')";
        String sql2 = "insert into user1(name,pwd) values('c','ccc')";
        stm.addBatch(sql1);
        stm.addBatch(sql2);

        //5.執行要批量執行的sql語句(返回值爲每條sql語句影響的行數)
        int[] ints = stm.executeBatch();

        for (int anInt : ints) {
            System.out.println("影響的行數爲:"+anInt);
        }

        //6.關閉連接
        stm.close();
        coon.close();


    }

2.mybatis—通過forEach去動態拼接sql語句

說明:這裏會省略掉mybatis連接數據庫的操作,只是對forEach形式批量操作sql作說明。
[1] 編寫數據庫表user1對應的實體類
User.class (這裏使用了lombok插件)

package com.gs.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private int id;
    private String name;
    private String pwd;
}

[2] 編寫接口方法 insertUser
UserMapper.class

package com.gs.mapper;
import com.gs.pojo.User;
import java.util.List;

public interface UserMapper {
    /*批量sql操作*/
    public int insertUser(List<User> list);
}

[3] 編寫xml文件
sql語句執行的原型

inssert into user1 values(xx,xx),(xxx,xxxx)

UserMapper.xml
<1> collection表示傳入來的是一個List數組,item表示遍歷的實體項,separator表示中間以 , 進行分割

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.gs.mapper.UserMapper">
   
    <insert id="insertUser" useGeneratedKeys="true" >
        insert into user1(name,pwd)
        values
        <foreach collection="list" separator="," item="user">
        (
           #{user.name},
           #{user.pwd}
        )
        </foreach>
    </insert>

</mapper>

[4] 編寫測試方法
[1] MybatisUtil是自己編寫的獲取SqlSession 的工具類
[2] 通過list把兩個對象添加後進行傳參執行。

 @Test
    public void insertUser(){
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        User user1 = new User();
        user1.setName("ww");
        user1.setPwd("ww");

        User user2 = new User();
        user2.setName("zl");
        user2.setPwd("zl");

        List<User> list = new ArrayList<>();
        list.add(user1);
        list.add(user2);

        int i = mapper.insertUser(list);

        sqlSession.close();
    }

控制檯相關的日誌文件:
可以看到它只開啓一次連接,把兩個User對象拼裝成了一條sql語句後執行
在這裏插入圖片描述
補充說明:下面是關於自己編寫的獲取SqlSession的工具類(可自行跳過)
MybatisUtil.class

package com.gs.utils;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;


/**
 * @Auther: Gs
 * @Date: 2020/6/27
 * @Description: com.gs.utils
 * @version: 1.0
 */
public class MybatisUtil {

    private static SqlSessionFactory sqlSessionFactory;

    static {

        try {
        	//我們編寫的mybatis核心配置文件
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            //獲得sqlSessionFactory 對象
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //獲取sqlSession對象
    public static SqlSession getSqlSession(){
        //這裏可以實現自動提交
        return sqlSessionFactory.openSession(true);
    }
}

3. mybatis — 更改sqlSession的執行器

官方上對於執行器有如下述說(要完成業務我們可以使用BATCH形式)
在這裏插入圖片描述
[1] 更改sqlSession的執行器(這裏我以上面的工具類爲例子)
在獲取sqlSession的方法中,通過ExecutorType改變執行器。

//獲取sqlSession對象
public static SqlSession getSqlSession(){
      //開啓批量操作
      return sqlSessionFactory.openSession(ExecutorType.BATCH,true);
  }

[2] 編寫接口方法

/*ExecutorType層面上的批量操作*/
public int insertUser2(User user);

[3] 編寫xml文件

<insert id="insertUser2" useGeneratedKeys="true" parameterType="user">
	  insert into user1
	  <trim prefix="(" suffix=")" suffixOverrides=",">
	      <if test="name!=null">name,</if>
	      <if test="pwd!=null">pwd,</if>
	  </trim>
	  <trim prefix="value(" suffix=")" suffixOverrides=",">
	      <if test="name!=null">#{name},</if>
	      <if test="pwd!=null">#{pwd},</if>
	  </trim>
</insert>

[4] 編寫測試方法

 @Test
 public void insertUser2(){
      SqlSession sqlSession = MybatisUtil.getSqlSession();
      UserMapper mapper = sqlSession.getMapper(UserMapper.class);

      User user1 = new User();
      user1.setName("ww1");
      //user1.setPwd("ww2");
      mapper.insertUser2(user1);

       User user2 = new User();
      user2.setName("zl");
      user2.setPwd("zl");
      mapper.insertUser2(user2);

      sqlSession.commit();
      sqlSession.close();
  }

控制檯的日誌
解釋:這裏我們可以看出它執行了兩條sql語句後才關閉連接(若進行相關的debug調試,你會發現只有兩個User對象都插入後數據庫纔有相應的值出現)
在這裏插入圖片描述

補充說明:除了上面的方式外,我們還可以直接在xml映射的配置文件中直接寫多條sql語句在一個方法中進行實現。不過我們在編寫數據庫連接的url時得加上支持多條sql操作的參數 allowMultiQueries=true

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章