質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Spring

Spring Framework は、Javaプラットフォーム向けのオープンソースアプリケーションフレームワークです。 Java Platform上に、 Web ベースのアプリケーションを設計するための拡張機能が数多く用意されています。

Q&A

解決済

2回答

5769閲覧

springbootでプルダウンに列挙型(DB登録)

KurisOswad

総合スコア15

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Spring

Spring Framework は、Javaプラットフォーム向けのオープンソースアプリケーションフレームワークです。 Java Platform上に、 Web ベースのアプリケーションを設計するための拡張機能が数多く用意されています。

0グッド

0クリップ

投稿2018/10/16 15:21

編集2018/10/17 15:27

前提・実現したいこと

スプリングブートで在庫一覧表に新規登録画面と更新画面を作成し
formを使ってプルダウンメニューを作成。
そのまま入力値をDBに登録するところまで出来ているのですが
プルダウンメニューに列挙型で定数を設定したいのですが
ネットで色々調べるも理解できる記事が見つからず困っています。
初心者で知識不足なので申し訳ないですが
どなたかご教授いただけないでしょうか。
DBの型がchar型になっていて、enunではStringで作成してます。
こちらは変換なども必要なのでしょうか。

追加の情報です。
A-pzさんのアドバイスに明確に答えられないかもしれません。
以下、私が使っているものです。

・エクリプスのSTSでスタータースプリングブート
・MYSQL
・Marven
・トムキャット
・mysql.jdbc.Driver
・ライブラリがよくわかっていないのですが
JREシステムライブラリというフォルダがプロジェクトにあります。

pom.xml

1<?xml version="1.0" encoding="UTF-8"?> 2<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4 <modelVersion>4.0.0</modelVersion> 5 6 <groupId>com.funayama.springboot</groupId> 7 <artifactId>pda_k_funayama</artifactId> 8 <version>0.0.1-SNAPSHOT</version> 9 <packaging>jar</packaging> 10 11 <name>pda_k_funayama</name> 12 <description>sample project for Spring Boot</description> 13 14 <parent> 15 <groupId>org.springframework.boot</groupId> 16 <artifactId>spring-boot-starter-parent</artifactId> 17 <version>2.0.5.RELEASE</version> 18 <relativePath/> <!-- lookup parent from repository --> 19 </parent> 20 21 <properties> 22 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 23 <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> 24 <java.version>1.8</java.version> 25 </properties> 26 27 <dependencies> 28 <dependency> 29 <groupId>org.springframework.boot</groupId> 30 <artifactId>spring-boot-starter-data-jpa</artifactId> 31 </dependency> 32 33 <dependency> 34 <groupId>org.springframework.boot</groupId> 35 <artifactId>spring-boot-starter-web</artifactId> 36 </dependency> 37 38 <dependency> 39 <groupId>mysql</groupId> 40 <artifactId>mysql-connector-java</artifactId> 41 <scope>runtime</scope> 42 </dependency> 43 <dependency> 44 <groupId>org.springframework.boot</groupId> 45 <artifactId>spring-boot-starter-test</artifactId> 46 <scope>test</scope> 47 </dependency> 48 <dependency> 49 <groupId>org.springframework.boot</groupId> 50 <artifactId>spring-boot-starter-thymeleaf</artifactId> 51 </dependency> 52 </dependencies> 53 54 <build> 55 <plugins> 56 <plugin> 57 <groupId>org.springframework.boot</groupId> 58 <artifactId>spring-boot-maven-plugin</artifactId> 59 </plugin> 60 </plugins> 61 </build> 62 63 64</project> 65

コンバーターと列挙型を作成してみましたがうまくいきませんでした。

package com.funayama.springboot; import javax.persistence.AttributeConverter; //フォーム用クラス public class Converter implements AttributeConverter<JenreEnum, String> { //データーベースに登録する値(列挙型使用) @Override public String convertToDatabaseColumn(JenreEnum jenreCode) { if (jenreCode == null) { return null; } switch (jenreCode) { case Clock: return "1"; case Electron: return "2"; case Phone: return "3"; default: return null; } } //Entityに登録する値(列挙型使用) @Override public JenreEnum convertToEntityAttribute(String dbData) { if (dbData == null) { return null; } switch (dbData) { case "1": return JenreEnum.Clock; case "2": return JenreEnum.Electron; case "3": return JenreEnum.Phone; default: return null; } } }
ackage com.funayama.springboot; import javax.persistence.Convert; @Convert(converter = Converter.class) public enum JenreEnum { Unspecified("0", "指定なし"), Clock("1", "時計"), Electron("2", "電子"), Phone("3", "携帯"); //ジャンルID private String genreId; //ジャンル名 private String genreName; //コンストラクタ private JenreEnum(String genreId, String genreName) { this.genreId = genreId; this.genreId = genreName; } //商品IDゲッター public String getGenreId() { return genreId; } //ジャンル名ゲッター public String getGenreName() { return genreName; } }

Entityクラス

1@Convert(converter = Converter.class) 2 @Column(name = "product_genre",nullable = false,length = 2) 3 private String genre;

EntityをEnumに設定できないとエラーが発生してしまいました。
データーベースの型がcharなのにStringでしてしまっているからなのか
HTMLからの取り出し方に問題があるのか
なにがおかしいのか見当もつきません。
どなたかお力添えをしていただけないでしょうか。。
ちなみにHTMLも載せておきます

HTML

1<form method="post" action="/ProductList" th:action="@{/ProductList}" th:object="${formList}"> 2 <div class='form-id'> 3 <!--商品ID--> 4 <label>※必須※ 商品ID</label> <br> <input type="text" 5 name="id"> 6 </div> 7 <!--ジャンル--> 8 <div class='form-jenre'> 9 <label>ジャンル</label><br> <select style="width: 160px;" 10 name="genre"> 11 <option value='0'></option> 12 <option value='1'>時計</option> 13 <option value='2'>電子</option> 14 <option value='3'>携帯</option> 15 </select> 16 </div>

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

A-pZ

2018/10/17 07:44

データベースのアクセスに使っているライブラリを書くと明確な回答が得られるかもしれません。例えばSpring-JDBC、MyBatis、Doma2などがあります。
A-pZ

2018/10/18 05:15

なるほど、spring-boot-starter-data-jpa を指定しているので、JPAをお使いで、enumの変換で困っているのですね、ありがとうございます。
KurisOswad

2018/10/18 11:43

使ってるもので処理が違うということでしょうか…調べ方を変えてみます!ありがとうございます!
guest

回答2

0

ベストアンサー

JPAの @Convert 注釈は、enumにつけるのではなく、@Entityで変換したいフィールドに付与します。

例:Genre.java

java

1import javax.persistence.Column; 2import javax.persistence.Convert; 3import javax.persistence.Entity; 4import javax.persistence.Id; 5import javax.persistence.Table; 6 7import lombok.Getter; 8import lombok.Setter; 9import lombok.ToString; 10 11@Entity 12@Table(name="GENRE") 13@Getter @Setter @ToString 14public class Genre { 15 16 @Id 17 @Column(name="ID") 18 private Integer id; 19 20 @Column(name="NAME") 21 @Convert(converter = GenreAttributeConverter.class) 22 private GenreEnum name; 23}

ただし、わざわざAttributeConverterを作成せずとも、@Enumerated を付与することでenum型の名前とデータベースの値が合致する要素にもできますし、データベースの値が数値で、その数値の順番どおりにenumの要素が定義されている場合は、自動的に変換が可能です。

変換対象のEnumは以下の通りです。

GenreEnum.java

java

1public enum GenreEnum { 2 Other, Clock, Electron, Phone; 3}

これに対するGenreクラスは、以下のどちらかを適用します。(両方も可能ですが、それはあまり意味がないでしょう)

enumの要素名と、検索結果を照合させる場合のGenre.java

java

1import javax.persistence.Column; 2import javax.persistence.Entity; 3import javax.persistence.EnumType; 4import javax.persistence.Enumerated; 5import javax.persistence.Id; 6import javax.persistence.Table; 7 8import lombok.Getter; 9import lombok.Setter; 10import lombok.ToString; 11 12@Entity 13@Table(name="GENRE") 14@Getter @Setter @ToString 15public class Genre { 16 17 @Id 18 @Column(name="ID") 19 private Integer id; 20 21 @Column(name="NAME") 22 @Enumerated(EnumType.STRING) 23 private GenreEnum name; 24}

enumの要素の順番と、検索結果の数値を照合させる場合のGenre.java

java

1import javax.persistence.Column; 2import javax.persistence.Entity; 3import javax.persistence.Id; 4import javax.persistence.Table; 5 6import lombok.Getter; 7import lombok.Setter; 8import lombok.ToString; 9 10@Entity 11@Table(name="GENRE") 12@Getter @Setter @ToString 13public class Genre { 14 15 @Id 16 @Column(name="ID") 17 private GenreEnum id; 18 19 @Column(name="NAME") 20 private String name; 21} 22

この場合は、@Idによって、ordinary(順序指定=数値)が暗黙的に指定され、enumの場合は自動的に ordinal() が実行された結果が入ります。

例えばデータベースから取得した値が 2 だった場合は、ordinal値が2のもの(ordinailは0から開始される数値)なので、GenreEnum.Electron が返されます。


参考までに、Repositoryは以下のインタフェースで作成し、

java

1import org.springframework.data.repository.CrudRepository; 2 3import com.github.apz.springsample.entity.Genre; 4 5public interface GenreRepository extends CrudRepository<Genre, Integer> { 6 7}

@Controller@Serviceの責務がついたクラスなどからは以下で呼び出せるでしょう。

java

1@RestController 2@RequiredArgsConstructor 3public class GenreController { 4 5 private final GenreRepository repository; 6 7 @GetMapping("/genre") 8 public Iterable<Genre> getAllGenre() { 9 return repository.findAll(); 10 } 11}

テーブル定義

sql

1CREATE TABLE GENRE ( 2 ID INT NOT NULL, 3 NAME VARCHAR(256) NOT NULL 4); 5 6INSERT INTO GENRE (ID, NAME) VALUES (1, 'Clock'); 7INSERT INTO GENRE (ID, NAME) VALUES (2, 'Electron'); 8INSERT INTO GENRE (ID, NAME) VALUES (3, 'Phone');

余談:提示していただいたコードに、Jenre と Genre が入り混じっていますので、Genreに統一した方が良いかと思います。

投稿2018/10/19 01:11

A-pZ

総合スコア12011

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KurisOswad

2018/10/21 14:13

返事が遅くなり申し訳ありません 詳しく教えていただいてありがとうございます! コンバーターを作らずとも出来るのですね。。 色々ねっと情報を見ていたのですが今までで一番わかりやすかったです! 早速参考にさしていただきます。 大変助かりました。 また機会があればよろしくお願いします! ありがとうございました!
A-pZ

2018/10/22 04:51

d(・ω・ Converterを作成する理由は、回答のような「デフォルトの振る舞い」ではなく、それ以外の動きをしてほしい場合に指定します。たいていは既存システムの都合やDBの設計都合などによりデフォルトの振る舞いでは条件を満たせない場合があるのと、より複雑な構造を要する場合もあるため、Converterを使うことはよくあります。
KurisOswad

2018/10/22 13:48

なるほどですね。Converterについても気になっていたところでした。使う機会も多いということですね。どちらのパターンでも使えるように試してみたいと思います。知識が少なすぎて質問の仕方ですらよくわかっていなかったのですが、丁寧にお答え下さってありがとうございます。まだまだ理解しきれないところが多いのですが、教えてもらえたことしっかりプラスにしていきたいと思います!!
guest

0

ormによって違うので一概には言えません。

設定(ファイル/アノテーション)で対応可能なもの。(無設定で可能な場合はこちら)

コンバーターを作成して設定で対応可能なもの

が一般的になります。

投稿2018/10/16 23:25

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KurisOswad

2018/10/17 13:36

asahina1979さん アドバイスをありがとうございます。 今日これからですが、コンバーターで調べ再チャレンジしてみようかと思います。 昨日まで途方にくれていましたが、今日は少しでも進められるように頑張ってみます!! 助かります!
KurisOswad

2018/10/17 13:51

public interface AttributeConverter<X,Y> { public Y convertToDatabaseColumn (X attribute); public X convertToEntityAttribute (Y dbData); } 上記のものでうまくいくか作成してみようかと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問