1. 程式人生 > >mybatis學習之路----mysql批量新增資料

mybatis學習之路----mysql批量新增資料

mybatis學習之路----批量更新資料

接下來兩節要探討的是批量插入批量更新,因為這兩種操作在企業中也經常用到。

    mysql新增語句  

insert into 表名(欄位,欄位。。。) values ( 值,值 。。。);此種適合單條插入。

批量插入,

一種可以在程式碼中迴圈著執行上面的語句,但是這種效率太差,下面會有對比,看看它有多差。

另一種,可以用mysql支援的批量插入語句,

insert into 表名(欄位,欄位。。。) values ( 值,值 。。。),( 值,值 。。。),( 值,值 。。。)....

這種方式相比起來,更高效。

下面開始來實現。

    <!-- 跟普通的insert沒有什麼不同的地方 ,主要用來跟下面的批量插入做對比。-->
    <insert id="insert" parameterType="com.soft.mybatis.model.Customer">
        <!-- 跟自增主鍵方式相比,這裡的不同之處只有兩點
                    1  insert語句需要寫id欄位了,並且 values裡面也不能省略
                    2 selectKey 的order屬性需要寫成BEFORE 因為這樣才能將生成的uuid主鍵放入到model中,
                    這樣後面的insert的values裡面的id才不會獲取為空
              跟自增主鍵相比就這點區別,當然了這裡的獲取主鍵id的方式為 select uuid()
              當然也可以另寫別生成函式。-->
        <selectKey keyProperty="id" order="BEFORE" resultType="String">
            select uuid()
        </selectKey>
        insert into t_customer (id,c_name,c_sex,c_ceroNo,c_ceroType,c_age)
        values (#{id},#{name},#{sex},#{ceroNo},#{ceroType},#{age})
    </insert>

    <!-- 批量插入, -->
    <insert id="batchInsert" parameterType="java.util.Map">
        <!-- 這裡只做演示用,真正專案中不會寫的這麼簡單。 -->
        insert into
          t_customer (id,c_name,c_sex,c_ceroNo,c_ceroType,c_age)
        values
        <!-- foreach mybatis迴圈集合用的
              collection="list" 接收的map集合中的key 用以迴圈key對應的屬性
                 separator=","  表示每次迴圈完畢,在sql後面放一個逗號
                 item="cus" 每次迴圈的實體物件 名稱隨意-->
        <foreach collection="list" separator="," item="cus">
            <!-- 組裝values物件,因為這張表的主鍵為非自增主鍵,所以這裡 (select uuid()) 用於生成id的值-->
            ((select uuid()),#{cus.name},#{cus.sex},#{cus.ceroNo},#{cus.ceroType},#{cus.age})
        </foreach>
    </insert>

實體model物件

package com.soft.mybatis.model;

/**
 * Created by xuweiwei on 2017/9/10.
 */
public class Customer {

    private String id;
    private String name;
    private Integer age;
    private Integer sex;
    private String ceroNo;
    private Integer ceroType;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Integer getSex() {
        return sex;
    }

    public void setSex(Integer sex) {
        this.sex = sex;
    }

    public String getCeroNo() {
        return ceroNo;
    }

    public void setCeroNo(String ceroNo) {
        this.ceroNo = ceroNo;
    }

    public Integer getCeroType() {
        return ceroType;
    }

    public void setCeroType(Integer ceroType) {
        this.ceroType = ceroType;
    }

    @Override
    public String toString() {
        return "Customer{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", sex=" + sex +
                ", ceroNo='" + ceroNo + '\'' +
                ", ceroType='" + ceroType + '\'' +
                '}';
    }
}

介面

    int add(Customer customer);

    int batchInsert(Map<String,Object> param);

實現
   /**
     * 新增資料
     * @param customer
     * @return
     */
    public int add(Customer customer) {
        return insert("customer.insert", customer);
    }

    /**
     * 批量插入資料
     * @param param
     * @return
     */
    public int batchInsert(Map<String,Object> param) {
        return insert("customer.batchInsert", param);
    }

    /**
     * 公共部分
     * @param statementId
     * @param obj
     * @return
     */
    private int insert(String statementId, Object obj){
        SqlSession sqlSession = null;
        try {
            sqlSession = SqlsessionUtil.getSqlSession();
            int key =  sqlSession.insert(statementId, obj);
            // commit
            sqlSession.commit();
            return key;
        } catch (Exception e) {
            sqlSession.rollback();
            e.printStackTrace();
        } finally {
            SqlsessionUtil.closeSession(sqlSession);
        }
        return 0;
    }
測試類
    @Test
    public void add() throws Exception {
        Long start = System.currentTimeMillis();
        for(int i=0;i<1000;i++){
            Customer customer = new Customer();
            customer.setName("普通一條條插入 "+ i);
            customer.setAge(15);
            customer.setCeroNo("000000000000"+ i);
            customer.setCeroType(2);
            customer.setSex(1);
            int result = customerDao.add(customer);
        }
        System.out.println("耗時 : "+(System.currentTimeMillis() - start));
    }

    @Test
    public void batchInsert() throws Exception {
        Map<String,Object> param = new HashMap<String,Object>();
        List<Customer> list = new ArrayList<Customer>();
        for(int i=0;i<1000;i++){
            Customer customer = new Customer();
            customer.setName("批量插入" + i);
            customer.setAge(15);
            customer.setCeroNo("111111111111"+i);
            customer.setCeroType(2);
            customer.setSex(1);
            list.add(customer);
        }
        param.put("list",list);
        Long start = System.currentTimeMillis();
        int result = customerDao.batchInsert(param);
        System.out.println("耗時 : "+(System.currentTimeMillis() - start));
    }

兩種都進行插入1000條測試

由於我沒有用連線池等等原因,在插入了700多條的時候 junit直接掛了,

Cause: org.apache.ibatis.executor.ExecutorException: Error selecting key or setting result to parameter object.

Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException:

Data source rejected establishment of connection,  message from server: "Too many connections"



資料庫插入結果:


但是第二種僅僅用了2秒多就ok了。可見這種效率很高。


資料庫結果


這裡寫了兩個,其實第一種僅僅是做對比效率用。

批量新增資料記錄完畢。