mybatis中批量操作的汇总整理

在我们实际开发过程中,免不了会碰到要批量操作数据的情况,如果在代码中进行循环操作的话,由于跟数据库连接次数过多会导致效率低下,影响性能,这个时候应用mybatis进行批量操作就很重要了,这篇文章的目的主要为了对mybatis中的批量操作做一个整理,包括删除,更新,插入。

目录

  1.批量删除,插入

  2.批量更新


测试建表,插入数据如下:

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for ins_orbit_point
-- ----------------------------
DROP TABLE IF EXISTS `ins_orbit_point`;
CREATE TABLE `ins_orbit_point`  (
  `point_id` bigint(20) NOT NULL COMMENT '巡查点id',
  `orbit_id` bigint(20) NOT NULL COMMENT '巡查轨迹id',
  `point_type` int(2) NOT NULL COMMENT '巡查点类型(1开始点,2中间点,3结束点)',
  `point_sort` int(10) NOT NULL COMMENT '巡查点在轨迹中的实际顺序'
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '巡查轨迹与巡查点关联表' ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of ins_orbit_point
-- ----------------------------
INSERT INTO `ins_orbit_point` VALUES (359, 1, 1, 1);
INSERT INTO `ins_orbit_point` VALUES (360, 1, 2, 2);
INSERT INTO `ins_orbit_point` VALUES (361, 1, 3, 3);
INSERT INTO `ins_orbit_point` VALUES (362, 2, 1, 1);
INSERT INTO `ins_orbit_point` VALUES (363, 2, 2, 2);
INSERT INTO `ins_orbit_point` VALUES (364, 2, 2, 3);
INSERT INTO `ins_orbit_point` VALUES (366, 2, 2, 4);
INSERT INTO `ins_orbit_point` VALUES (366, 2, 3, 5);
INSERT INTO `ins_orbit_point` VALUES (359, 11, 3, 1);

SET FOREIGN_KEY_CHECKS = 1;
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for ins_orbit
-- ----------------------------
DROP TABLE IF EXISTS `ins_orbit`;
CREATE TABLE `ins_orbit`  (
  `orbit_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键,自增',
  `start_point_id` bigint(20) NOT NULL COMMENT '轨迹开始点id',
  `end_point_id` bigint(20) NULL DEFAULT NULL COMMENT '轨迹结束点id',
  `is_end` int(2) NOT NULL COMMENT '是否结束(1是,0否)',
  `ins_date` date NOT NULL COMMENT '巡查日期',
  `insor_id` varchar(32) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '巡查人id',
  `ins_orb_distance` decimal(5, 3) NULL DEFAULT NULL COMMENT '里程,单位km',
  `ins_orb_spending` decimal(5, 3) NULL DEFAULT NULL COMMENT '花费时间,单位小时',
  `ins_orb_speed` decimal(5, 3) NULL DEFAULT NULL COMMENT '速度,单位km/h',
  `start_time` timestamp(0) NULL DEFAULT NULL COMMENT '开始时间',
  `end_time` timestamp(0) NULL DEFAULT NULL COMMENT '结束时间',
  `park_id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '项目id',
  `dept_id` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '部门id',
  PRIMARY KEY (`orbit_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 12 CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '巡查轨迹表' ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of ins_orbit
-- ----------------------------
INSERT INTO `ins_orbit` VALUES (1, 359, 361, 1, '2018-11-09', '2e636fc47624493aa1056c6ed9e8f168', 10.000, 6.000, 1.650, '2018-11-08 09:22:54', '2018-11-08 15:23:11', 'af98a32c9b4d490297cadc2d85faf797', '74c6071187dd44d68eac5b7a295f65fd');
INSERT INTO `ins_orbit` VALUES (2, 362, 366, 0, '2018-11-09', '2e636fc47624493aa1056c6ed9e8f168', 10.000, 7.000, 2.000, '2018-11-08 08:25:26', '2018-11-08 15:25:35', 'af98a32c9b4d490297cadc2d85faf797', '74c6071187dd44d68eac5b7a295f65fd');
INSERT INTO `ins_orbit` VALUES (11, 359, 359, 0, '2018-11-09', '11111', 12.000, 22.000, 22.000, '2018-11-09 15:44:44', '2018-11-09 15:44:47', '111', '1111');

SET FOREIGN_KEY_CHECKS = 1;

        1.批量删除,插入

批量插入跟批量插入的原理是一样的,主要用到的就是foreach循环处理。

foreach的主要用在构建in条件中,它可以在SQL语句中进行迭代一个集合。foreach元素的属性主要有item,index,collection,open,separator,close。item表示集合中每一个元素进行迭代时的别名,index指 定一个名字,用于表示在迭代过程中,每次迭代到的位置,open表示该语句以什么开始,separator表示在每次进行迭代之间以什么符号作为分隔 符,close表示以什么结束,在使用foreach的时候最关键的也是最容易出错的就是collection属性,该属性是必须指定的,但是在不同情况 下,该属性的值是不一样的,主要有一下3种情况: 
1. 如果传入的是单参数且参数类型是一个List的时候,collection属性值为list 
2. 如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array 
3. 如果传入的参数是多个的时候,我们就需要把它们封装成一个Map了,当然单参数也可以封装成map,实际上如果你在传入参数的时候,在breast里面也 是会把它封装成一个Map的,map的key就是参数名,所以这个时候collection属性值就是传入的List或array对象在自己封装的map 里面的key

以上面的轨迹表为例,批量删除跟插入的代码如下:

批量插入:

​
 <insert id="insert" parameterType="com.pcos.inspection.insorbit.entity.InsOrbit">
        insert into ins_orbit (orbit_id, start_point_id, end_point_id,
        is_end, ins_date, insor_id,
        ins_orb_distance, ins_orb_spending, ins_orb_speed,
        start_time, end_time, park_id, dept_id
        )
        values
        <foreach collection="list" item="item" separator=",">
            (
            #{item.orbitId,jdbcType=BIGINT},
            #{item.startPointId,jdbcType=BIGINT},
            #{item.endPointId,jdbcType=BIGINT},
            #{item.isEnd,jdbcType=INTEGER},
            #{item.insDate,jdbcType=DATE},
            #{item.insorId,jdbcType=VARCHAR},
            #{item.insOrbDistance,jdbcType=DECIMAL},
            #{item.insOrbSpending,jdbcType=DECIMAL},
            #{item.insOrbSpeed,jdbcType=DECIMAL},
            #{item.startTime,jdbcType=TIMESTAMP},
            #{item.endTime,jdbcType=TIMESTAMP},
            #{item.parkId,jdbcType=VARCHAR},
            #{item.deptId,jdbcType=VARCHAR}
            )
        </foreach>
    </insert>

​

转换为sql如下:

INSERT INTO ins_orbit ( 
						orbit_id, 
						start_point_id, end_point_id, 
						is_end, ins_date, insor_id, ins_orb_distance,
						ins_orb_spending, ins_orb_speed, start_time,
						end_time, park_id, dept_id )
VALUES
	( ?,?,?,?,?,?,?,?,?,?,?,?,? ),
	( ?,?,?,?,?,?,?,?,?,?,?,?,? ),
	( ?,?,?,?,?,?,?,?,?,?,?,?,? )

 可以看到,实际上mybatis就是做了字符串的拼接。批量删除跟插入的代码差不多,就是将插入语句改成了删除语句而已

 在了解了批量插入后,我们可以反过来推断批量删除的mybatis写法。

首先,如果要我们在数据库中一次删除多条数据我们会怎么写呢?为了方便,我们以主键为基准进行删除,sql如下:

	DELETE from ins_orbit where orbit_id in (2,1,11);

现在问题就很简单了,只要用foreach拼接成in后面这个字符串就行了,很明显前缀open = "(",后缀close=")",分隔符=","

如下:

<delete id="deleteBatch">
        delete from ins_orbit where
        orbit_id
        in
        <foreach collection="list" separator="," open="(" close=")" item="item">
            #{item}
        </foreach>
    </delete>

  2.批量更新

  由于作者这里表数据比较复杂,推荐一个批量更新链接https://blog.csdn.net/xyjawq1/article/details/74129316

批量更新比插入及删除要稍微麻烦一些,这里我先将需求说一下,还是上面那两站表,我需要批量更新数据,将ins_prbit中is_end为0的数据改为1,同时需要将ins_orbit_point表中对应数据(一条轨迹上会有多个点),也就是轨迹上的最后一个点置为结束点(point_type = 3)。

批量更新轨迹表(ins_orbit)如下:

<update id="updateBatch">
        update ins_orbit
        set
        is_end = 1
        where orbit_id in
        <foreach collection="list" item="item" separator="," open="(" close=")">
            #{item.orbitId,jdbcType=BIGINT}
        </foreach>
    </update>

批量更新轨迹途径点表如下:

  <update id="updateBatch">
        update ins_orbit_point t1
        set
        point_type = 3
        <where>
            t1.orbit_id in
            <foreach collection="list" item="item" separator="," open="(" close=")">
                #{item.orbitId,jdbcType=BIGINT}
            </foreach>
            and
            <foreach collection="list" item="item" separator="  " open="case orbit_id" close="end">
                when #{item.orbitId,jdbcType=BIGINT}
                then t1.point_id = #{item.pointId,jdbcType=BIGINT}
            </foreach>
            and
            <foreach collection="list" item="item" separator="  " open="case orbit_id" close="end">
                when #{item.orbitId,jdbcType=BIGINT}
                then t1.point_sort = (select t3.sort from
                (select max(point_sort) as sort from ins_orbit_point t2 where t2.orbit_id = #{item.orbitId,jdbcType=BIGINT})
                t3)
            </foreach>
        </where>
    </update>

dao层代码如下:

public interface InsOrbitPointDao  {

    /**
     * 批量更新
     *
     * @param insOrbitPoints
     */
    void updateBatch(List<InsOrbitPoint> insOrbitPoints);
}
public interface InsOrbitDao extends OVUBaseDao<InsOrbit, Long> {

    /**
     * 批量更新
     *
     * @param list
     */
    void updateBatch(List<InsOrbit> list);
}

实体类如下:

public class InsOrbit {
    /**
     * 主键,自增
     */
    private Long orbitId;

    /**
     * 轨迹开始点id
     */
    private Long startPointId;

    /**
     * 轨迹结束点id
     */
    private Long endPointId;

    /**
     * 是否结束(1是,0否)
     */
    private Integer isEnd;

    /**
     * 巡查日期
     */
    private Date insDate;

    /**
     * 巡查人id
     */
    private String insorId;

    /**
     * 里程,单位km
     */
    private BigDecimal insOrbDistance;

    /**
     * 花费时间,单位小时
     */
    private BigDecimal insOrbSpending;

    /**
     * 速度,单位km/h
     */
    private BigDecimal insOrbSpeed;

    /**
     * 开始时间
     */
    private Date startTime;

    /**
     * 结束时间
     */
    private Date endTime;

    /**
     * 项目id
     */
    private String parkId;

    /**
     * 部门id
     */
    private String deptId;

    public String getDeptId() {
        return deptId;
    }

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

    public Long getOrbitId() {
        return orbitId;
    }

    public void setOrbitId(Long orbitId) {
        this.orbitId = orbitId;
    }

    public Long getStartPointId() {
        return startPointId;
    }

    public void setStartPointId(Long startPointId) {
        this.startPointId = startPointId;
    }

    public Long getEndPointId() {
        return endPointId;
    }

    public void setEndPointId(Long endPointId) {
        this.endPointId = endPointId;
    }

    public Integer getIsEnd() {
        return isEnd;
    }

    public void setIsEnd(Integer isEnd) {
        this.isEnd = isEnd;
    }

    public Date getInsDate() {
        return insDate;
    }

    public void setInsDate(Date insDate) {
        this.insDate = insDate;
    }

    public String getInsorId() {
        return insorId;
    }

    public void setInsorId(String insorId) {
        this.insorId = insorId;
    }

    public BigDecimal getInsOrbDistance() {
        return insOrbDistance;
    }

    public void setInsOrbDistance(BigDecimal insOrbDistance) {
        this.insOrbDistance = insOrbDistance;
    }

    public BigDecimal getInsOrbSpending() {
        return insOrbSpending;
    }

    public void setInsOrbSpending(BigDecimal insOrbSpending) {
        this.insOrbSpending = insOrbSpending;
    }

    public BigDecimal getInsOrbSpeed() {
        return insOrbSpeed;
    }

    public void setInsOrbSpeed(BigDecimal insOrbSpeed) {
        this.insOrbSpeed = insOrbSpeed;
    }

    public Date getStartTime() {
        return startTime;
    }

    public void setStartTime(Date startTime) {
        this.startTime = startTime;
    }

    public Date getEndTime() {
        return endTime;
    }

    public void setEndTime(Date endTime) {
        this.endTime = endTime;
    }

    public String getParkId() {
        return parkId;
    }

    public void setParkId(String parkId) {
        this.parkId = parkId;
    }
}
public class InsOrbitPoint {
    /**
     * 巡查点id
     */
    private Long pointId;

    /**
     * 巡查轨迹id
     */
    private Long orbitId;

    /**
     * 巡查点类型(1开始点,2中间点,3结束点)
     */
    private Integer pointType;

    /**
     * 巡查点在轨迹中的实际顺序
     */
    private Integer pointSort;



    public Long getPointId() {
        return pointId;
    }

    public void setPointId(Long pointId) {
        this.pointId = pointId;
    }

    public Long getOrbitId() {
        return orbitId;
    }

    public void setOrbitId(Long orbitId) {
        this.orbitId = orbitId;
    }

    public Integer getPointType() {
        return pointType;
    }

    public void setPointType(Integer pointType) {
        this.pointType = pointType;
    }

    public Integer getPointSort() {
        return pointSort;
    }

    public void setPointSort(Integer pointSort) {
        this.pointSort = pointSort;
    }

}

猜你喜欢

转载自blog.csdn.net/qq_41907991/article/details/83957309