LoginSignup
2
2

More than 3 years have passed since last update.

【Java】enumを使ってDBのコードをコード値に変換する

Last updated at Posted at 2020-06-28

DBに登録されたステータスコードをJava側でコード値に変換するサンプルです。
これにより、ステータスコードの意味を定義するマスタを作成する必要がなくなります。
フレームワークはSpring Boot。

環境

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

概要

生徒テーブルに登録された生徒ステータスコード(整数値)をJava側でenumを用いて対応するコード値に変換します。

ER図

image.png

ステータスコードとコード値

ステータスコード コード値
1 在学中
2 休学中
3 卒業

パッケージ構成図

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

ソースコード

1. DDL

生徒テーブル
CREATE TABLE `students` (
  `student_id` int(10) unsigned zerofill NOT NULL AUTO_INCREMENT COMMENT '生徒ID',
  `student_name` varchar(300) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '生徒名',
  `sex` tinyint(4) DEFAULT NULL COMMENT '性別',
  `school_year` tinyint(4) DEFAULT NULL COMMENT '学年',
  `class` tinyint(4) DEFAULT NULL COMMENT 'クラス',
  `student_status` tinyint(4) DEFAULT NULL COMMENT '生徒ステータス',
  PRIMARY KEY (`student_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin COMMENT='生徒';

2. 定数クラス

定数クラスにenumを定義して使用します。
クラスとしてenumを作成してもよいのですが、数が多くなることを想定してクラス内に定義しました。
こうすることで1クラスファイルで複数のenumを管理することができます。

Constant.java
package jp.co.high_school.constant;

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

import lombok.Getter;

/**
 * 定数クラス
 * @author CHI-3
 * @Version 1.0
 */
public class Constant {

        /**
         * StudentStatus
         * 生徒ステータス
         */
        @Getter
        public static enum StudentStatus {

            In(1, "在学中"),
            Rest(2, "休学中"),
            Out(3, "卒業");

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


            private int key;

            private String value;

            // コード値を全て返す
            public static Stream<StudentStatus> stream(){
                return Stream.of(StudentStatus.values());
            }

            // 取得したコードに一致するコード値を返す
            public static String getStatusValue(Byte code) {
                return Stream.of(StudentStatus.values()).filter(v -> v.getKey() == code).map(v -> v.getValue()).collect(Collectors.joining());
            }

        }


        // 今回は使用しない:1クラス内に複数enum定義できることの証明として記述
        /**
         * Grade
         * 成績
         */
        @Getter
        public static enum Grade{

            // 優、良、可は最低条件-sam、不可は最高条件
            Excellent(1, "優", 90),
            Good(2, "良", 75),
            Passing(3, "可", 60),
            Failing(4, "不可", 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クラス

今回は、EclipseのHibernate Toolsを用いて、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クラス

生徒IDの指定により、該当する生徒の情報を取得します。

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;

/**
 * 生徒(students)テーブル操作用リポジトリクラス
 * @author CHI-3
 * @Version 1.0
 */
@Repository
public interface StudentRepository extends JpaRepository<Student, Integer>{

    /**
     * findByStudentIdメソッド
     * 生徒IDに対応する生徒を取得する
     * @param studentId
     * @return 生徒
     */
    public Student findByStudentId(Integer studentId);

}

5. Serviceクラス

取得した生徒の、生徒ステータスのコードを対応するステータスコードに変換して返します。

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;

/**
 * 生徒情報取得用サービスクラス
 * @author CHI-3
 * @version 1.0
 */
@Service
@RequiredArgsConstructor
public class StudentInformationService {

    private final StudentRepository studentRepository;

    /**
     * getStatusメソッド
     * 対象の生徒の生徒ステータス(コード値)を取得する
     * @param studentId 生徒ID
     * @return 生徒ステータス(コード値)
     */
    public String getStatus(Integer studentId) throws Exception{

        Student student = studentRepository.findByStudentId(studentId);

        // 生徒IDに紐づく生徒が存在しない場合、例外を発生させる
        Optional.ofNullable(student).orElseThrow(Exception::new);

        String status = null;
        /* ステータスコード → 対応するコード値:streamによる記述に変更のためコメントアウト
        for(StudentStatus ss:StudentStatus.values()){
            if(ss.getKey() == student.getStudentStatus()) {
                status = ss.getValue();
                break;
            }
        }
        */

        // ステータスコード → 対応するコード値
        status = StudentStatus.getStatusValue(student.getStudentStatus());

        return status;

    }

}


6. Controllerクラス

Serviceクラスで取得したコード値を整形して返します。

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;

/**
 * 生徒情報取得用コントローラークラス
 * @author CHI-3
 * @Version 1.0
 */
@RestController
@RequiredArgsConstructor
public class StudentInformationController {

    private final StudentInformationService studenInformationService;

    /**
     * getStatusメソッド
     * 生徒ステータスを取得する
     * @param studentId 生徒ID
     * @return レスポンスエンティティ(ステータスのコード値+HTTPステータス)
     */
    @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クラス

StudentStatusResponse.java
package jp.co.high_school.app.response;

import lombok.Builder;
import lombok.Getter;

/**
 * 生徒ステータスレスポンスクラス
 * 生徒ステータスの成形に使用
 * @author CHI-3
 * @Version 1.0
 */
@Getter
@Builder
public class StudentStatusResponse {

    private String status;

}

動作確認

今回はローカル環境で動作確認を行います。

生徒(students)テーブル

student_id student_name sex school_year class student_status
1 在学中 1 1 2 1

生徒テーブルが上記の内容の場合、API(Advanced Rest Clientを使用)を叩くと以下のような結果が返ります。
きちんと、ステータスコード(1)に対応するコード値(在学中)がとれていますね。

メソッド GET
URL http://localhost:8080/student-information/1

image.png

変更履歴

  • 2020/07/13:ステータスコード → 対応するコード値を取得する処理の記述、定数クラスのパッケージ構成を変更

終わりに

enumを用いれば、マスタ(DB)や定数(Java)の管理がかなり楽になりそう。
うまく使っていきたいところです。

参考

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2