Management of partitioned values and their names Enum (Java) vs DB

When developing a system There are many cases where you want to correspond the division value with its meaning, such as "1: male, 2: female", "A: excellent B: good C: acceptable D: no". Also, there are many cases where you want to convert a division value to a character string.

So, this time, I would like to compare the method using Java Enum and the method of saving in the master table of DB.

It is assumed that Java will be used as the language and MySQL will be used as the DB.

1. Enum class

Starting with Java5, there is the concept of enums. Effective Java also recommends using it as a constant.

First, define the following encoder interface.

Encoder interface


/**
 *Encoder interface for Enum
 *
 * @param <T>Enum definition
 */
public interface Encodable<T extends Serializable> {
    /**
     *encoder
     *
     * @return Enum definition
     */
    T getCode();

    /**
     *Returns the name of the code.
     *
     * @return name
     */
    String getName();
}

To generate a string from the partition value, define the decoder class as follows.

Decoder class


/**
 *Decoder class for Enum
 *
 * @param <K>Code value
 * @param <V>value
 */
public class Decoder<K extends Serializable, V extends Encodable<K>> {

    /**Map definition*/
    private Map<K, V> map;

    /**
     *Decoder
     *
     * @param values Enum group
     */
    private Decoder(V[] values) {
        map = new HashMap<K, V>(values.length);

        for (V value : values) {
            V old = map.put(value.getCode(), value);

            //Does not support duplicate code values
            if (old != null) {
                throw new IllegalArgumentException("duplicated code: " + value);
            }
        }
    }

    /**
     *Decoder
     *
     * @param code code value
     * @return Enum class
     */
    public V decode(K code) {
        return map.get(code);
    }

    /**
     *Definition to omit the specification of type argument
     *
     * @param <L>Code value
     * @param <W>value
     * @param values Enum group
     * @return decoder
     */
    public static <L extends Serializable, W extends Encodable<L>> Decoder<L, W> create(W[] values) {
        return new Decoder<L, W>(values);
    }
}

The actual class looks like this: In the case of gender, it will be as follows.

Gender enum class


/**
 *Gender enum class.
 * 
 */
public enum Gender implements
                     Encodable<Integer> {

    /**Man*/
    MALE(1, "Man"),
    /**woman*/
    FEMALE(2, "woman");

    /**Decoder*/
    private static final Decoder<Integer, Gender> DECODER = Decoder.create(values());

    /**Code value*/
    private final Integer code;

    /**name*/
    private final String name;

    /**
     *constructor.
     * 
     * @param code code value
     * @param name name
     */
    private Gender(Integer code, String name) {
        this.code = code;
        this.name = name;
    }

    @Override
    public Integer getCode() {
        return code;
    }

    /**
     *Get the Enum class from the code value.
     * 
     * @param code code value
     * @return Receipt format Enum class
     */
    public static Gender decode(Integer code) {
        return DECODER.decode(code);
    }

    /**
     *Method to get the name.
     * 
     * @return name
     */
    public String getName() {
        return name;
    }
}

You can get the name with the decode class and getName method as shown below.

Example of use


// 1:male
Gender male = Gender.decode(1);
String name = male.getName();

merit

High maintainability

If you write it in the program and give it a meaningful class name, it will be highly readable and maintainable. The code is easy to maintain.

Easy to write logic

Since the division name can be obtained without connecting to the DB one by one, it is easy to process.

Demerit

It is not easy to add a division value or change the name

When a division value is added or a name is changed due to a specification change, etc., a program modification will occur and release work will also occur.

When to use

I think it's a good idea to use Enum to manage things that cannot be changed, such as gender and prefectures in Japan. If it is changed, it will often be necessary to modify the logic.

2. DB master table

It is like managing id and its name using the following master table. Of course, it is possible to enter additional information in addition to the name.

Login user master


CREATE TABLE login_user_mst (
    id VARCHAR(11) NOT NULL,
    password CHAR(40) NOT NULL comment 'Login password',
    name VARCHAR(255) NOT NULL comment 'Full name',
    name_kana VARCHAR(255) default NULL comment 'Name Kana',

    PRIMARY KEY(id)
) CHARACTER SET 'utf8'
  COMMENT 'Login user';

Data example

id password name name_kana
10000001 xxxxxxxxxxxxxx Suzuki Nanako Suzuki Nanako
10000002 xxxxxxxxxxxxxx Matsumoto Kazuo Matsumoto Cazuo
10000003 xxxxxxxxxxxxxx Taku Watanabe Watanabe Taku

merit

Easy to change the name

To change the name of the partition value, just update the DB record, so The cost is considerably lower because it can be changed without program modification.

You can get the division name by table join

Since you can join the master table and get the name only with SQL, All you need is the logic of displaying the SQL result on the screen or outputting it to CSV.

Demerit

There is no meaning in branch processing by division value

For example, when a process branch occurs depending on the division value, Because there is no choice but to have that classification value on the application side Even if you have a value in the DB, it will be in a double maintenance state.

Difficult to manage as the number of tables increases

If the project has a rule that "let's manage all constants in the master table", When there are many types of constants, if you create a table for each constant, a huge number of master tables will be created. If it is a master table, I think it is still easy to manage if there is a rule such as prefixing it with "mst_". ..

When to use

Login user management, sales office information, I think that it is good to use it for things that are relatively changed in many cases.

At the end

I think that how to manage the division value and the name is an eternal issue (personally). In my current project, I am using both Enum type and DB master. I think you should understand and use each characteristic.

Recommended Posts

Management of partitioned values and their names Enum (Java) vs DB
[Java] [Kotlin] Generically call valueOf and values of Enum
Reverse Enum constants from strings and values in Java
Advantages and disadvantages of Java
About fastqc of Biocontainers and Java
Java 15 implementation and VS Code preferences
Java arguments, return values and overloads
[Java] Judgment of identity and equivalence