[Java] [Java] Convert DB code to code value using enum

5 minute read

It is a sample that converts the status code registered in DB to a code value on the Java side. This eliminates the need to create a master that defines the meaning of status codes. The framework is Spring Boot.

Environment

  • OS: Windows10
  • IDE: Eclipse2020-03
  • Java: 8
  • MySQL: 5.7
  • Hibernate ORM: 5.4
  • Spring Boot: 2.3.1

Overview

Convert the student status code (integer value) registered in the student table to the corresponding code value using enum on the Java side.

ER diagram

image.png

Status code and code value

| Status code | Code value | |—|—| |1| |2|On leave of absence| |3|Graduation|

Package configuration diagram

enum-sample
     |
    src/main/java
     |----jp.co.high_school
     | |---- app
     | | |---- controller
     | | |---- response
     | |
     | |---- domain
     | | |---- service
     | | |---- repository
     | | |---- model
     | |
     | |---- constant
     |
    src/main/resources
     |----application.yml

Source code

1. DDL

student table


CREATE TABLE `students` (
  `student_id` int(10) unsigned zerofill NOT NULL AUTO_INCREMENT COMMENT'Student ID',
  `student_name` varchar(300) COLLATE utf8mb4_bin DEFAULT NULL COMMENT'student name',
  `sex` tinyint(4) DEFAULT NULL COMMENT'gender',
  `school_year` tinyint(4) DEFAULT NULL COMMENT'school year',
  `class` tinyint(4) DEFAULT NULL COMMENT'class',
  `student_status` tinyint(4) DEFAULT NULL COMMENT'student status',
  PRIMARY KEY (`student_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='student';

2. Constant class

Define and use enum in the constant class. You can create an enum as a class, but it was defined in the class assuming that the number will increase. By doing this, one class file can manage multiple enums.

Constant.java


package jp.co.high_school.constant;

import java.util.stream.Collectors;
import java.util.stream.Stream;

import lombok.Getter;

/**
 * Constant class
 * @author CHI-3
 * @Version 1.0
 */
public class Constant {

        /**
         * StudentStatus
         * Student status
         */
        @Getter
        public static enum StudentStatus {

            In(1, "while attending school"),
            Rest(2, "Absent from school"),
            Out(3, "Graduation");

            private StudentStatus(int key, String value) {
                this.key = key;
                this.value = value;
            }


            private int key;

            private String value;

            // return all code values
            public static Stream<StudentStatus> stream(){
                return Stream.of(StudentStatus.values());
            }

            // Return the code value that matches the acquired code
            public static String getStatusValue(Byte code) {
            return Stream.of(StudentStatus.values()).filter(v -> v.getKey() == code).map(v -> v.getValue()).collect(Collectors.joining());
            }

        }


        // Not used this time: Described as proof that multiple enums can be defined in one class
        /**
         * Grade
         * Grade
         */
        @Getter
        public static enum Grade{

            // Excellent, good, good is the minimum-sam, bad is the best
            Excellent(1, "Yu", 90),
            Good(2, "Good", 75),
            Passing(3, "OK", 60),
            Failing(4, "No", 59);


            private Grade(int key, String value, int order) {
                this.key = key;
                this.value = value;
                this.order = order;
            }

            private int key;

            private String value;

            private int order;

        }

}

3. Entity class

This time, using Hibernate Tools of Eclipse, it was automatically generated from the DB.

Student.java


package jp.co.high_school.domain.model;

import java.io.Serializable;
import javax.persistence.*;


/**
 * The persistent class for the students database table.
 *
 */
@Entity
@Table(name="students")
@NamedQuery(name="Student.findAll", query="SELECT s FROM Student s")
public class Student implements Serializable {
private static final long serialVersionUID = 1L;

@Id
@Column(name="student_id")
private Integer studentId;

@Column(name="class")
private Byte class_;

@Column(name="school_year")
private Byte schoolYear;

private Byte sex;

@Column(name="student_name")
private String studentName;

@Column(name="student_status")
private Byte studentStatus;

//bi-directional one-to-one association to Grade
@OneToOne(mappedBy="student")
private Grade grade;

public Student() {
}

public Integer getStudentId() {
return this.studentId;
}

public void setStudentId(Integer studentId) {
this.studentId = studentId;
}

public Byte getClass_() {
return this.class_;
}

public void setClass_(Byte class_) {
this.class_ = class_;
}

public Byte getSchoolYear() {
return this.schoolYear;
}

public void setSchoolYear(Byte schoolYear) {
this.schoolYear = schoolYear;
}

public Byte getSex() {
return this.sex;
}

public void setSex(Byte sex) {
this.sex = sex;
}

public String getStudentName() {
return this.studentName;
}

public void setStudentName(String studentName) {
this.studentName = studentName;
}

public Byte getStudentStatus() {
return this.studentStatus;
}

public void setStudentStatus(Byte studentStatus) {this.studentStatus = studentStatus;
}

public Grade getGrade() {
return this.grade;
}

public void setGrade(Grade grade) {
this.grade = grade;
}

}

4. Repository class

By specifying the student ID, the information of the corresponding student will be acquired.

StudentRepository.java


package jp.co.high_school.domain.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import jp.co.test_shop.domain.model.Student;

/**
 * Repository class for working with the students table
 * @author CHI-3
 * @Version 1.0
 */
@Repository
public interface StudentRepository extends JpaRepository<Student, Integer>{

/**
* findByStudentId method
* Get the student corresponding to the student ID
* @param studentId
* @return student
*/
public Student findByStudentId(Integer studentId);

}

5. Service class

Converts the student status code of the acquired student to the corresponding status code and returns it.

StudentInformationService.java


package jp.co.high_school.domain.service;

import java.util.Optional;

import org.springframework.stereotype.Service;

import jp.co.test_shop.constant.Constant.StudentStatus;
import jp.co.test_shop.domain.model.Student;
import jp.co.test_shop.domain.repository.StudentRepository;
import lombok.RequiredArgsConstructor;

/**
 * Student information acquisition service class
 * @author CHI-3
 * @version 1.0
 */
@Service
@RequiredArgsConstructor
public class StudentInformationService {

private final StudentRepository studentRepository;

/**
* getStatus method
* Get the student status (code value) of the target student
* @param studentId Student ID
* @return Student status (code value)
*/
public String getStatus(Integer studentId) throws Exception{

Student student = studentRepository.findByStudentId(studentId);
It's a sequel.
// Raise an exception if there is no student associated with the student ID
Optional.ofNullable(student).orElseThrow(Exception::new);
It's a sequel.
String status = null;
/* Status code → Corresponding code value: Comment out due to change in description by stream
for(StudentStatus ss:StudentStatus.values()){
if(ss.getKey() == student.getStudentStatus()) {
status = ss.getValue();
break;
}
}
*/
It's a sequel.
// Status code → corresponding code value
status = StudentStatus.getStatusValue(student.getStudentStatus());

return status;

}

}


6. Controller class

Formats and returns the code value obtained in Service class.

StudentInformationController.java


package jp.co.high_school.app.controller;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import jp.co.test_shop.app.response.StudentStatusResponse;
import jp.co.test_shop.domain.service.StudentInformationService;
import lombok.RequiredArgsConstructor;

/**
 * Student information acquisition controller class
 * @author CHI-3
 * @Version 1.0
 */
@RestController
@RequiredArgsConstructor
public class StudentInformationController {

private final StudentInformationService studenInformationService;

/**
* getStatus method
* Get student status
* @param studentId Student ID
* @return response entity (status code value + HTTP status)
*/
@GetMapping("/student-information/{studentId}")
public ResponseEntity<StudentStatusResponse> getStatus(@PathVariable("studentId") Integer studentId){
String status = studenInformationService.getStatus(studentId);
StudentStatusResponse studentStatusReponse = StudentStatusResponse.builder().status(status).build();
return new ResponseEntity<>(studentStatusReponse, HttpStatus.OK);
}

}

7. Response class

StudentStatusResponse.java


package jp.co.high_school.app.response;

import lombok.Builder;
import lombok.Getter;

/**
 * Student Status Response Class
 * Used to shape student status
 * @author CHI-3
 * @Version 1.0
 */
@Getter
@Builder
public class StudentStatusResponse {

private String status;

}

Operation check

This time we will check the operation in the local environment.

students table

|student_id|student_name|sex|school_year|class|student_status| |—|—|—|—|—|—| |1|While attending school|1|1|2|1|

If the student table has the above contents, hitting the API (using Advanced Rest Client) will return the following results. The code value (while attending school) corresponding to the status code (1) is taken properly.

Method | GET

  • –|— URL|http://localhost:8080/student-information/1 image.png

change history

  • 2020/07/13: Status code → Changed the description of the process to get the corresponding code value and the package configuration of constant class

At the end

Using enum will make management of master (DB) and constants (Java) much easier. I want to use it well.

Reference

  • [How to use Java enum that you do not know SE channel](https://tkmtys.hatenablog.com/entry/2015/10/11/182918)
  • [Basic usage of enum type (enum) and code example Qiita](https://qiita.com/igm50/items/8c9788d4ba5868642c69)
  • [How to use enum (enumerated type) in Java Narikiri Architect](https://architect.slowcat.net/java/enum/)
  • [Java 8-Filter sample map codeflow](https://www.codeflow.site/en/article/java8__java-8-filter-a-map-examples)