枚举映射

10/22/2024

Mybatis是支持枚举映射:

  • 对于查询SQL,如果需要将字段映射为枚举类型,需要在 ResultMap 中添加 TypeHandler
  • 对于插入SQL,如果需要将枚举类型映射为字段值,需要在插入参数(#{gender, typeHandler=com.king.im.GenderTypeHandler})中添加 TypeHandler

# mybatis内的枚举映射

以一个用户表为例子,该表中有一个性别类型,实体类中存储的是一个枚举类型,其中 1-男性, 2-女性

@Getter
public enum GenderEnum {

    MALE(1, "男性"),

    FEMALE(2, "女性");

    private final Integer value;

    private final String desc;

    GenderEnum(Integer value, String desc) {
        this.value = value;
        this.desc = desc;
    }

    public static GenderEnum getByValue(Integer value) {
        for (GenderEnum genderEnum : GenderEnum.values()) {
            if (genderEnum.getValue().equals(value)) {
                return genderEnum;
            }
        }
        return null;
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
@Data
public class User {

    @TableId(type = IdType.AUTO)
    private Long id;

    private String nickName;

    private GenderEnum gender;
}
1
2
3
4
5
6
7
8
9
10

自定一个TypeHandler, 其实现 org.apache.ibatis.type.TypeHandler 接口,该接口包含4个方法,4个方法都需要实现;

public class GenderTypeHandler implements TypeHandler<GenderEnum> {
    @Override
    public void setParameter(PreparedStatement ps, int i, GenderEnum parameter, JdbcType jdbcType) throws SQLException {
        ps.setInt(i, parameter.getValue());
    }

    @Override
    public GenderEnum getResult(ResultSet rs, String columnName) throws SQLException {
        int genderValue = rs.getInt(columnName);
        return GenderEnum.getByValue(genderValue);
    }

    @Override
    public GenderEnum getResult(ResultSet rs, int columnIndex) throws SQLException {
        int genderValue = rs.getInt(columnIndex);
        return GenderEnum.getByValue(genderValue);
    }

    @Override
    public GenderEnum getResult(CallableStatement cs, int columnIndex) throws SQLException {
        int genderValue = cs.getInt(columnIndex);
        return GenderEnum.getByValue(genderValue);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

定义一个UserMapper,包含查询数据和写入数据接口

public interface UserMapper {

    User getOne(Long id);

    void insertOne(User user);
}
1
2
3
4
5
6

xml 中编写sql, 并应用映射器

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.king.im.UserMapper">
    <resultMap id="UserMap" type="com.king.im.User" autoMapping="true">
        <result property="gender" column="gender" typeHandler="com.king.im.GenderTypeHandler" />
    </resultMap>

    <select id="getOne" resultMap="UserMap">
        select * from t_user where id = #{0}
    </select>

    <select id="insertOne">
        insert into t_user(id, nick_name, gender)
        values (#{id}, #{nickName}, #{gender,typeHandler=com.king.im.GenderTypeHandler})
    </select>
</mapper>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

本地测试时,添加 mybatis加载配

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-config.dtd"
        >
<configuration>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://192.168.1.6:3306/test"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="UserMapper.xml"/>
    </mappers>
</configuration>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

测试用例

@SneakyThrows
public static void main(String[] args) {
    String resource = "mybatis-config.xml";
    InputStream is = Resources.getResourceAsStream(resource);
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

    try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
        User user = new User();
        user.setGender(GenderEnum.FEMALE);
        user.setNickName("for test");
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        mapper.insertOne(user);
        System.out.println("打印插入结果" + user);
        
        User one = mapper.getOne(1L);
        System.out.println("查询插入结果" + one);
    } finally {
        if (is !=null) {
            is.close();
        }
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# mybatisplus枚举映射

在枚举类中指定需要映射的字段

@Getter
public enum GenderEnum {

    MALE(1, "男性"),

    FEMALE(2, "女性");

    @EnumValue
    private final Integer value;

    private final String desc;

    GenderEnum(Integer value, String desc) {
        this.value = value;
        this.desc = desc;
    }
    
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

mybatisplus 枚举相关配置

#配置枚举 支持通配符 * 或者 ; 分割。指定枚举类所在的包
mybatis-plus:
  type-enums-package: com.king.im.entity.enum 
  configuration:
    default-enum-type-handler: org.apache.ibatis.type.EnumOrdinalTypeHandler
  #handler配置可以省略不写,默认配置就是上面这个Handler
1
2
3
4
5
6