问题描述
在MyBatis的xml配置文件中,默认情况下枚举类型的属性与字符串类型的值是无法比较的,这和Date日期类型不能和""空字符串比较是一样的,会报错:
### Error querying database.
Cause: java.lang.IllegalArgumentException:
invalid comparison: com.constant.StatusEnum and java.lang.String
解决方式
类型定义
SysUser系统用户
例如,现在有一个Gender性别为枚举类型的SysUser类,
package com.example.soil_backend.model.entity;
import com.baomidou.mybatisplus.annotation.*;
import java.io.IOException;
import java.time.LocalDateTime;
import java.io.Serializable;
import com.example.soil_backend.common.Validator;
import com.example.soil_backend.enums.GenderEnum;
import com.example.soil_backend.enums.RoleEnum;
import com.example.soil_backend.model.TbBase;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import org.apache.ibatis.type.ByteArrayTypeHandler;
import org.springframework.web.multipart.MultipartFile;
/**
* SysUser
*
* @author XiMumu
* @since 2024-02-18
*/
@Data
@EqualsAndHashCode(callSuper = true)
@Accessors(chain = true)
@TableName("sys_user")
public class SysUser extends TbBase implements Serializable {
private static final long serialVersionUID = -6472629353385247605L;
/**
* 用户编码ID;自增
*/
@TableId(value = "user_id", type = IdType.AUTO)
private Integer userId;
/**
* 账户名-必须为邮箱号
*/
private String userName;
/**
* 账户密码
*/
@JsonIgnore //标记在属性或者方法上,返回的json数据即不包含该属性
private String passWord;
/**
* 昵称
*/
private String nickName;
/**
* 手机号
*/
private String telPhone;
/**
* 性别:1-男;2-女;3-未知
*/
private GenderEnum gender;
/**
* 用户头像URL
*/
@TableField(value = "photo_url",typeHandler = ByteArrayTypeHandler.class)
private byte[] photoUrl;
/**
* 是否删除:1-使用中;2-已删除
*/
@JsonIgnore //标记在属性或者方法上,返回的json数据即不包含该属性
private Integer delFlag;
/**
* 用户角色[管理员:ADMIN;普通用户:COMMON]
*/
private RoleEnum userRole;
}
Gender枚举类型
package com.example.soil_backend.enums;
import com.baomidou.mybatisplus.annotation.EnumValue;
import com.fasterxml.jackson.annotation.JsonValue;
import lombok.Getter;
/**
* 管理员:ADMIN;普通用户:COMMON
*/
@Getter
public enum RoleEnum {
ADMIN("ADMIN","管理员"),
COMMON("COMMON","普通用户");
//编码
@EnumValue
@JsonValue //规定返回前端的为1/2
private final String code;
//描述信息
private final String desc;
RoleEnum(String code, String desc) {
this.code = code;
this.desc = desc;
}
public static boolean isValidEnum(String code){
for (RoleEnum roleEnum : RoleEnum.values()) {
if (roleEnum.getCode().equals(code)){
return true;
}
}
return false;
}
@Override
public String toString() {
return "RoleEnum{" +
"code=" + code +
", desc='" + desc + '\'' +
'}';
}
}
错误写法
如下为原始的写法,会报错,
<update id="insertUserByResetDelFlag">
UPDATE sys_user
<set>
...
<if test="sysUser.gender != null and sysUser.gender != ''">
gender = #{sysUser.gender},
</if>
...
</set>
</update>
测试可用的写法
形式1:通过枚举字段的方法进行比较
<update id="insertUserByResetDelFlag">
UPDATE sys_user
<set>
...
<if test="sysUser.gender != null and sysUser.gender != ''">
gender = #{sysUser.gender},
</if>
...
</set>
</update>
需要改为以下的书写方式,
<update id="insertUserByResetDelFlag">
UPDATE sys_user
<set>
...
<if test="sysUser.gender != null and sysUser.gender.getCode() == 1">
gender = 1,
</if>
<if test="sysUser.gender != null and sysUser.gender.getCode() == 2">
gender = 2,
</if>
<if test="sysUser.gender != null and sysUser.gender.getCode() == 3">
gender = 3,
</if>
...
</set>
</update>
形式2:通过枚举常量的方法进行比较
<update id="insertUserByResetDelFlag">
UPDATE sys_user
<set>
...
<if test="sysUser.gender != null and sysUser.gender.toString() == @com.example.soil_backend.enums.GenderEnum.MALE.toString()">
gender = 1,
</if>
<if test="sysUser.gender != null and sysUser.gender.toString() == @com.example.soil_backend.enums.GenderEnum.FEMALE.toString()">
gender = 2,
</if>
<if test="sysUser.gender != null and sysUser.gender.toString() == @com.example.soil_backend.enums.GenderEnum.UNKNOWN.toString()">
gender = 3,
</if>
...
</set>
</update>