Spring boot MyBatis枚举解决方案

问题

在开发中我们经常会遇见以下情况
固定范围的常量 
比如性别
只会存在 男/女/其他
如果我们在数据建一个表做存储有太过麻烦 还影响查询性能

示例枚举

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonValue;

import java.util.HashMap;
import java.util.Map;

/**
 * @author lhj
 * @date 2019/6/25 11:02
 */
public enum Sex {

    /**
     * 女
     */
    WOMAN(0, "女"),
    /**
     * 男
     */
    MAN(1, "男"),
    /**
     * 未设置
     */
    INTERSEX(10, "未设置");

    private Integer code;
    private String label;

    @JsonValue
    public Map<String, Object> jsonValue() {
        Map<String, Object> jsonValue = new HashMap<>();
        jsonValue.put("code", this.getCode());
        jsonValue.put("label", this.getLabel());
        return jsonValue;
    }

    @JsonCreator
    public static Sex codeFind(Integer code) {
        for (Sex item : Sex.values()) {
            if (item.getCode().equals(code)) {
                return item;
            }
        }
        return null;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getLabel() {
        return label;
    }

    public void setLabel(String label) {
        this.label = label;
    }

    Sex(Integer code, String label) {
        this.code = code;
        this.label = label;
    }

}

示例DO对象


import lombok.Data;
import org.lhj.domain.enumerate.Sex;

import javax.persistence.*;

/**
 * @author lhj
 * @date 2019/6/25 11:00
 */
@Data
@Table(name = "user")
public class UserDO {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    Long id;
    String name;
    Integer age;
    @Column(name = "sex")
    Sex sex;
}

解决方案

持久化

我们可以通过在代码中定义枚举
将DO实体中的属性设置成枚举
在配合Mybatis的类型转换

实现类型转换器

import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedTypes;
import org.apache.ibatis.type.TypeHandler;
import org.lhj.domain.enumerate.Sex;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * @author lhj
 * @date 2019/6/25 11:25
 */
@MappedTypes(value = {Sex.class})
public class SexTypeHandler implements TypeHandler<Sex> {

    public SexTypeHandler() {
    }

    @Override
    public void setParameter(PreparedStatement ps, int i, Sex sex, JdbcType jdbcType) throws SQLException {
        if (jdbcType == null) {
            ps.setString(i, sex.getCode().toString());
        } else {
            ps.setObject(i, sex.name(), jdbcType.TYPE_CODE);
        }
    }

    @Override
    public Sex getResult(ResultSet resultSet, String s) throws SQLException {
        return Sex.codeFind(resultSet.getInt(s));
    }

    @Override
    public Sex getResult(ResultSet resultSet, int i) throws SQLException {
        return Sex.codeFind(resultSet.getInt(i));
    }

    @Override
    public Sex getResult(CallableStatement callableStatement, int i) throws SQLException {
        return Sex.codeFind(callableStatement.getInt(i));
    }
}

在spring boot 配置文件中配置好类型转换器包的位置

mybatis:
  type-handlers-package: org.lhj.mybatis.type.handlers

数据库处理使用tk.mybats

		UserMapper userMapper = applicationContext.getBean(UserMapper.class);
        UserDO userDO = new UserDO();
        //id自增 我们设置成null 他会自动设置id
        userDO.setId(null);
        userDO.setName("苏武");
        userDO.setAge(23);
        userDO.setSex(Sex.MAN);
        userMapper.insert(userDO);

api接口

由于使用的spring mvc 
默认序列化工具 是 jackson
我们可以直接使用注解进行序列化处理

反序列化

使用 @JsonCreator 
这个注解标识的方法块表示在接收http数据 构建对象的时候怎么构建
这里前端只需要传具体的CODE进来就行了
	@JsonCreator
    public static Sex codeFind(Integer code) {
        for (Sex item : Sex.values()) {
            if (item.getCode().equals(code)) {
                return item;
            }
        }
        return null;
    }

序列化

当需要序列化这个类型时候 会去找这个类型携带@JsonValue 注解的方法
    @JsonValue
    public Map<String, Object> jsonValue() {
        Map<String, Object> jsonValue = new HashMap<>();
        jsonValue.put("code", this.getCode());
        jsonValue.put("label", this.getLabel());
        return jsonValue;
    }

示例效果

  	  [ {
  	  "id" : 2,
  	  "name" : "苏武",
  	  "age" : 23,
  	  "sex" : {
  	    "code" : 1,
  	    "label" : "男"
  	  }
  	} ]

你可能感兴趣的:(java)