MyBatis(Plus) 枚举数组的映射

MyBatisPlus中枚举数组的映射技巧
本文介绍了如何在MyBatisPlus中处理数据库字段与Java枚举数组的映射问题。在PostgreSQL等支持数组类型的数据库中,可以直接映射,但无法直接映射枚举类型的数组。为解决这一问题,文章提出了一种扩展方法,通过自定义转换,实现了枚举类型数组的自动映射,使得映射过程得以顺利进行。

背景

我们都知道用MyBatis的EnumTypeHandler可以将数据库里的字段直接映射成Java里的枚举, 以下是MybatisPlus的示例代码:

public enum Sex {
	MAN, WOMAN
}

@Data
@TableName("student")
public class Student {
    private String stuId;
    private Sex sex;
}

另外,像PostgrelSql这种数据库,是支持数组类型的,这时候可以用ArrayTypeHandler去和Java里面的数组做映射:

@Data
@TableName("student")
public class Student {
    private String stuId;
    private Sex sex;
    @TableField(value="hobbies", typeHandler = ArrayTypeHandler.class)
    private String[] hobbies;
}

public enum Hobby {
	READ, SPORT, MUSIC,
}

但是如果想将字符串数组想映射成一个枚举类型的数组,是没有办法直接映射的, 以下代码不会成功:

public enum Hobby {
	READ, SPORT, MUSIC,
}

@Data
@TableName("student")
public class Student {
    private String stuId;
    private Sex sex;
    @TableField(value="hobbies", typeHandler = ArrayTypeHandler.class)
    private Hobby[] hobbies;
}

解决方法

可以扩展ArrayTypeHandler,针对枚举类型的数组做自动转换:


import org.apache.ibatis.type.ArrayTypeHandler;
import org.apache.ibatis.type.JdbcType;

import java.sql.Array;

/**
 * 扩展 ArrayTypeHandler
 */
public class ArrayTypeHandlerX extends ArrayTypeHandler {
    private final Class<?> type;

    public ArrayTypeHandlerX(Class<?> type) {
        if (type == null) {
            throw new IllegalArgumentException("Type argument cannot be null");
        }
        this.type = type;
    }
    
    @Override
    protected Object extractArray(Array array) throws SQLException {
        // 判断数据类型是否是枚举
        Class<?> componentType = this.type.getComponentType();
        if (!componentType.isEnum()) {
            return super.extractArray(array);
        }
        // 获取原有的数组值
        Object[] objects = (Object[]) super.extractArray(array);
        if (null == objects) {
            return null;
        }
        // 枚举值转换
        Object[] resultArray = (Object[]) java.lang.reflect.Array.newInstance(componentType, objects.length);
        for (int i = 0; i < objects.length; i++) {
            resultArray[i] = Enum.valueOf((Class<? extends Enum>) componentType, objects[i].toString());
        }
        return resultArray;
    }
}

使用

public enum Hobby {
	READ, SPORT, MUSIC,
}

@Data
@TableName("student")
public class Student {
    private String stuId;
    private Sex sex;
    @TableField(value="hobbies", typeHandler = ArrayTypeHandlerX.class)
    private Hobby[] hobbies;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值