mybatis的批量update

方法有三种:1.通过java代码batch方式,xml文件只需一条update语句。java代码繁琐

2.xml使用foreach,“;”分割多条update语句,要求:jdbc的url需加上allowMultiQueries=true。速度慢

3.xml使用foreach进行代码拼接,用了case...when...then...end,oracle好像不支持这种写法,mysql和sqlserver是可以的

xml文件:

<mapper namespace="com.dao.EmployeeDao">
    <!--可以通过改变实体类的字段来验证映射-->
    <update id="updateFirstWay">
        update employee set employee_name = #{employeeName},
        employee_gender = #{employeeGender},
        employee_salary = #{employeeSalary},
        dept_id = #{deptId}
        where employee_id = #{employeeId}
    </update>

    <update id="updateSecondWay">
        <foreach collection="list" item="emp" separator=";">
            update employee set employee_name = #{emp.employeeName},
            employee_gender = #{emp.employeeGender},
            employee_salary = #{emp.employeeSalary},
            dept_id = #{emp.deptId}
            where employee_id = #{emp.employeeId}
        </foreach>
    </update>

    <update id="updateThirdWay">
        update employee set
        employee_name= case employee_id
        <foreach collection="list" item="emp">
            when #{emp.employeeId} then #{emp.employeeName}
        </foreach>
        end, employee_gender= case employee_id
        <foreach collection="list" item="emp">
            when #{emp.employeeId} then #{emp.employeeGender}
        </foreach>
        end, employee_salary= case employee_id
        <foreach collection="list" item="emp">
            when #{emp.employeeId} then #{emp.employeeSalary}
        </foreach>
        end,dept_id= case employee_id
        <foreach collection="list" item="emp">
            when #{emp.employeeId} then #{emp.deptId}
        </foreach>
        end
        where
        <foreach collection="list" item="emp" separator="or">
            employee_id = #{emp.employeeId}
        </foreach>
    </update>
</mapper>

  实体类:

package com.entity;

import java.math.BigDecimal;

public class Employee {

    private Integer employeeId;
    private String employeeName;
    private int employeeGender;
    private BigDecimal employeeSalary;
    private Integer deptId;

    public Employee() {
    }

    public Employee(Integer employeeId, String employeeName, int employeeGender, BigDecimal employeeSalary, Integer deptId) {
        this.employeeId = employeeId;
        this.employeeName = employeeName;
        this.employeeGender = employeeGender;
        this.employeeSalary = employeeSalary;
        this.deptId = deptId;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "employeeId=" + employeeId +
                ", employeeName='" + employeeName + '\'' +
                ", employeeGender=" + employeeGender +
                ", employeeSalary=" + employeeSalary +
                ", deptId='" + deptId + '\'' +
                '}';
    }

    public Integer getEmployeeId() {
        return employeeId;
    }

    public void setEmployeeId(Integer employeeId) {
        this.employeeId = employeeId;
    }

    public String getEmployeeName() {
        return employeeName;
    }

    public void setEmployeeName(String employeeName) {
        this.employeeName = employeeName;
    }

    public int getEmployeeGender() {
        return employeeGender;
    }

    public void setEmployeeGender(int employeeGender) {
        this.employeeGender = employeeGender;
    }

    public BigDecimal getEmployeeSalary() {
        return employeeSalary;
    }

    public void setEmployeeSalary(BigDecimal employeeSalary) {
        this.employeeSalary = employeeSalary;
    }

    public Integer getDeptId() {
        return deptId;
    }

    public void setDeptId(Integer deptId) {
        this.deptId = deptId;
    }
}

  EmployeeDao.class:

void updateFirstWay(Employee employee);
    int updateSecondWay(List<Employee> employees);
    int updateThirdWay(List<Employee> employees);

  test代码:

@Test
    public void testUpdateFirstWay() {
        List<Employee> employees = new ArrayList<>();
        employees.add(new Employee(10,"傲慢", 1, new BigDecimal(9999), 1));
        employees.add(new Employee(11,"色欲", 0, new BigDecimal(8888), 2));
        employees.add(new Employee(12,"怠惰", 1, new BigDecimal(7777), 3));
        employees.add(new Employee(13,"贪婪", 1, new BigDecimal(6666), 4));
        employees.add(new Employee(14,"愤怒", 1, new BigDecimal(5555), 5));
        SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtil.getSqlSessionFactory();
        SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
        EmployeeDao mapper = sqlSession.getMapper(EmployeeDao.class);
        try {
            for (int i = 0; i < employees.size(); i ++) {
                mapper.updateFirstWay(employees.get(i));
                if (i % 2 == 0 || i == employees.size() - 1) {
                    sqlSession.commit();
                }
            }
        } catch (Exception e) {
            sqlSession.rollback();
        } finally {
            sqlSession.close();
        }
    }

    @Test
    public void testUpdateSecondWay() {
        List<Employee> employees = new ArrayList<>();
        employees.add(new Employee(15,"傲慢", 1, new BigDecimal(9999), 1));
        employees.add(new Employee(16,"色欲", 1, new BigDecimal(8888), 2));
        employees.add(new Employee(17,"怠惰", 1, new BigDecimal(7777), 3));
        employees.add(new Employee(18,"贪婪", 0, new BigDecimal(6666), 4));
        employees.add(new Employee(19,"愤怒", 1, new BigDecimal(5555), 5));
        EmployeeDao employeeDao = MapperFactory.generateMapper(EmployeeDao.class);
        employeeDao.updateSecondWay(employees);
    }

    @Test
    public void testUpdateThirdWay() {
        List<Employee> employees = new ArrayList<>();
        employees.add(new Employee(1,"傲慢", 1, new BigDecimal(9999), 1));
        employees.add(new Employee(2,"色欲", 1, new BigDecimal(8888), 2));
        EmployeeDao employeeDao = MapperFactory.generateMapper(EmployeeDao.class);
        employeeDao.updateThirdWay(employees);
    }

  总结:#{}里面写的是实体类的字段,已经测试过了。

最后:根据实际要求,每个字段是要判断是否为空的,例

<update id="updateFirstWay">
        update employee set
        <if test="b != null and b != ''">
            employee_name = #{b},
        </if>
         <if test="c != null and c != ''">
             employee_gender = #{c},
         </if>
          <if test="d != null and d != ''">
              employee_salary = #{d},
          </if>
          <if test="e != null and e !=''">
              dept_id = #{e}
          </if>
        where employee_id = #{a}
    </update>

  因为当只修改部分数据库的列的值,而不是全部列的时候,就需要将不要修改的字段跳过。上面的代码有漏洞,当所有列都不修改的时候会出错,修改代码的话以后再说,累了


有个bug:数据库的binary类型,实体类写的Integer,但是写在ongl里面判断x != null and x != '',如果是0的话,那么这句话会跳过,false

posted on 2019-10-11 21:18  我欲皆真  阅读(7157)  评论(1编辑  收藏  举报

导航