mybatis如何实现saveOrUpdate

 更新时间:2023年02月08日 08:39:40   作者:分享心得  
这篇文章主要介绍了mybatis如何实现saveOrUpdate问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

1. selectKey标签查询

DDL

CREATE TABLE `luck_reward_info` (
  `id` int NOT NULL AUTO_INCREMENT COMMENT 'id',
  `activity_id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '活动id',
  `reward_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '奖品名',
  `reward_level` int DEFAULT NULL COMMENT '奖品等级',
  `num` int DEFAULT NULL COMMENT '奖品数量',
  `dis_number` int DEFAULT '0' COMMENT '已发奖品数量',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `update_time` datetime DEFAULT NULL COMMENT '修改时间',
  `field` varchar(255) DEFAULT NULL COMMENT '备注',
  PRIMARY KEY (`id`,`activity_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC COMMENT='奖品信息表';

RewardInfoMapper接口

@Mapper
public interface RewardInfoMapper{
   int saveOrUpdate(RewardInfo rewardInfo);
}

使用selectKey

<insert id="saveOrUpdate" >
  <selectKey keyProperty="count" resultType="int" order="BEFORE">
    select count(*) from luck_reward_info where id = #{id}
  </selectKey>
  <if test="count > 0">
        UPDATE luck_reward_info
        <set>
            <if test='activityId != null and activityId != "" '>activity_id=#{activityId},</if>
            <if test='rewardName != null and rewardName != "" '>reward_name=#{rewardName},</if>
            <if test='rewardLevel != null '>reward_level=#{rewardLevel},</if>
            <if test='num != null '>num=#{num},</if>
            <if test='disNumber != null '>dis_number=#{disNumber},</if>
            update_time=now(),
            <if test='field != null and field != "" '>field=#{field},</if>
        </set>
        WHERE id=#{id}
  </if>
  <if test="count==0">
    INSERT INTO luck_reward_info(
            id,activity_id,reward_name,reward_level,number,create_time,field
            )
            VALUES (
            (select id from (select (ifnull(max(id), 0)) + 1 as id from luck_reward_info)t), #{activityId},#{rewardName},#{rewardLevel},#{number},now(),#{field}
            )
  </if>
</insert>

报错:

org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.executor.ExecutorException: No setter found for the keyProperty ‘count’ in com.cmbchina.ssm.entity.RewardInfo.

原因:RewardInfo内必须有count属性,来接收count值,否则报错

优化:接口使用Map,实体类不需要再新增count字段了

//RewardInfoMapper.java
int saveOrUpdate(Map<String, Object> map);

2. 主键自增或者累加的,不使用selectKey

根据id是否为空,空新增,不为空修改

<insert id="saveOrUpdate" keyProperty="id" useGeneratedKeys="true">
        <if test="id == null">
            INSERT INTO luck_reward_info(
                id,activity_id,reward_name,reward_level,num,create_time,field
            )
            VALUES (
                (select id from (select (ifnull(max(id), 0)) + 1 as id from luck_reward_info)t), #{activityId},#{rewardName},#{rewardLevel},#{num},now(),#{field}
            )
        </if>
        <if test="id != null">
            UPDATE luck_reward_info
            <set>
                <if test='activityId != null and activityId != "" '>activity_id=#{activityId},</if>
                <if test='rewardName != null and rewardName != "" '>reward_name=#{rewardName},</if>
                <if test='rewardLevel != null '>reward_level=#{rewardLevel},</if>
                <if test='num!= null '>num=#{num},</if>
                <if test='disNumber != null '>dis_number=#{disNumber},</if>
                update_time=now(),
                <if test='field != null and field != "" '>field=#{field},</if>
            </set>
            WHERE id=#{id}
        </if>
    </insert>

3. 主键为varchar的使用ON DUPLICATE KEY UPDATE

DDL

CREATE TABLE `luck_activity_info` (
  `id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'id',
  `title` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '标题',
  `start_time` datetime DEFAULT NULL COMMENT '开始时间',
  `end_time` datetime DEFAULT NULL COMMENT '结束时间',
  `sap_id` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci DEFAULT NULL COMMENT '操作员工编号',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `update_time` datetime DEFAULT NULL COMMENT '修改时间',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ROW_FORMAT=DYNAMIC COMMENT='抽奖活动表';

条数 新增返回1,修改返回2

<insert id="saveOrUpdate">
        INSERT INTO luck_activity_info(
            id,title,start_time,end_time,sap_id,create_time
        )
        VALUES (
            #{id},#{title},#{startTime},#{endTime},#{sapId},now()
        )
        ON DUPLICATE KEY UPDATE
            <if test='title != null and title != "" '>title=#{title},</if>
            <if test='startTime != null '>start_time=#{startTime},</if>
            <if test='endTime != null '>end_time=#{endTime},</if>
            <if test='sapId != null and sapId != "" '>sap_id=#{sapId},</if>
            update_time=now()
    </insert>

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • Spring之ShutDown Hook死锁现象解读

    Spring之ShutDown Hook死锁现象解读

    这篇文章主要介绍了Spring之ShutDown Hook死锁现象解读,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-04-04
  • Java微服务Filter过滤器集成Sentinel实现网关限流过程详解

    Java微服务Filter过滤器集成Sentinel实现网关限流过程详解

    这篇文章主要介绍了Java微服务Filter过滤器集成Sentinel实现网关限流过程,首先Sentinel规则的存储默认是存储在内存的,应用重启之后规则会丢失。因此我们通过配置中心Nacos保存规则,然后通过定时拉取Nacos数据来获取规则配置,可以做到动态实时的刷新规则
    2023-02-02
  • Spring源码解密之自定义标签与解析

    Spring源码解密之自定义标签与解析

    这篇文章主要给大家介绍了关于Spring源码解密之自定义标签与解析的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参借鉴,下面随着小编来一起学习学习吧。
    2018-01-01
  • 解决执行Junit单元测试报错java.lang.ClassNotFoundException问题

    解决执行Junit单元测试报错java.lang.ClassNotFoundException问题

    这篇文章主要介绍了解决执行Junit单元测试报错java.lang.ClassNotFoundException问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11
  • IDEA整合jeesite4.x及安装教程

    IDEA整合jeesite4.x及安装教程

    本文给大家介绍IDEA整合jeesite4.x及安装教程,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-07-07
  • Spring Boot @Conditional注解使用示例详解

    Spring Boot @Conditional注解使用示例详解

    在SpringBoot中,@Conditional注解用于条件性地注册bean,根据某些条件决定是否创建特定bean,可以实现Condition接口并重写matches方法来定义条件,本文介绍Spring Boot @Conditional注解的相关知识,感兴趣的朋友一起看看吧
    2024-12-12
  • Java实现微信支付的签名算法示例

    Java实现微信支付的签名算法示例

    这篇文章主要为大家介绍了Java实现微信支付的签名算法实现示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12
  • Java中使用异或运算符实现加密字符串

    Java中使用异或运算符实现加密字符串

    这篇文章主要介绍了Java中使用异或运算符实现加密字符串,本文直接给出实现代码,以及运算结果加密实例,需要的朋友可以参考下
    2015-06-06
  • Java中遍历ConcurrentHashMap的四种方式详解

    Java中遍历ConcurrentHashMap的四种方式详解

    这篇文章主要介绍了Java中遍历ConcurrentHashMap的四种方式详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-10-10
  • java实现纸牌游戏之小猫钓鱼算法

    java实现纸牌游戏之小猫钓鱼算法

    这篇文章主要为大家详细介绍了java实现纸牌游戏之小猫钓鱼算法,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-01-01

最新评论