mysql与mybatis-plus有关autoResultMap的事儿

遇到的问题:

一开始是这样写的,images和appendixes在数据库中都是blob类型,想要通过重写set方法来获取正确的值,但是问题是中文会乱码,很奇怪。。。

@Data
@Builder
@TableName(value = "task_comment", autoResultMap = true)
public class TaskComment  implements Serializable {

    /**
     * ID
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;

    @JsonProperty("task_instance_id")
    private Long taskInstanceId;

    private String operator;

    @JsonProperty("operator_name")
    private String operatorName;

    private Integer type;

    /**
     * 图片连接
     */
    private String images;

    public void setImages(Object images) {
        if(images instanceof byte[]){
            this.images =  new String((byte[]) images);
        } else if (images instanceof List) {
            this.images = CollectionUtils.isNotEmpty((List<String>)images) ? JSONObject.toJSONString(images) : org.apache.commons.lang3.StringUtils.EMPTY;
        } else {
            this.images = (String) images;
        }
    }

    /**
     * 附件连接
     */
    private String appendixes;

    public void setAppendixes(Object appendixes) {
        if(appendixes instanceof byte[]){
            this.appendixes =  new String((byte[]) appendixes);
        } else if (appendixes instanceof List) {
            this.appendixes = CollectionUtils.isNotEmpty((List<String>)appendixes) ? JSONObject.toJSONString(appendixes) : org.apache.commons.lang3.StringUtils.EMPTY;
        } else {
            this.appendixes = (String) appendixes;
        }
    }
}

问题排查:

首先猜测是不是并没有调用我重写的set方法导致的乱码,debug发现确实调用了,但是得到的值并不是byte类型的。当时这也是照着公司以后的代码模仿的,就疑问为什么他得到的是byte类型,为什么我这边获取的不是,而是String类型,中文值还是乱码。后来查阅资料发现,是因为@TableName注解的属性autoResultMap我设置为true导致的。有关于这个属性的讲解可以看这位兄弟的文章,我就不重新叙述了。
简单的说,如果要想用重写set方法来获取值的话,那么这个属性就要是false。这里多说一句,对于blob类型的数据,在往数据库里面写的时候,这个java bean字段可以是String,但是在读取的时候如果不做处理,直接赋值到String字段上会出错。

优化:

由于images和appendixes字段存储的都是json字符串,后来我发现mysql中也有这种类型:json,json类型本质上还是blob类型。我就想着这两种类型是不是可以有什么方法映射呢,结果果然是可以的,当然也是和autoResultMap这个属性有关系的。
如果数据库是json类型的字段,同时autoResultMap=true,那么在select的时候,数据库json字段对应的实体类字段可以直接映射,该字段类型可以是某个类,也可以是List。
优化后的代码:

@Data
@Builder
@TableName(value = "task_comment", autoResultMap = true)
public class TaskComment  implements Serializable {

    /**
     * ID
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;

    @JsonProperty("task_instance_id")
    private Long taskInstanceId;

    private String operator;

    @JsonProperty("operator_name")
    private String operatorName;

    private Integer type;

    /**
     * 图片连接
     */
    private List<String> images;

    /**
     * 附件连接
     */
    private List<String> appendixes;
}

原来知道的越多,就可以自己写的越少了啊!!!芜湖~

你可能感兴趣的:(阿涛的踩坑日记,java,mybatis,数据库)