🐡

formとentityとdtoの違いについて

2024/07/23に公開

Form

  • 画面の入力値を保持しておくオブジェクト
  • 従業員を入力する簡単なTodoアプリがあったとして、htmlのformから渡ってきた情報を格納します。

TodoForm

@Data //lombok
@AllArgsConstructor
public class TodoForm {

    @NotNull("タイトルを入力してください")
    @Size(min = 1, max = 20, message="20文字以内で記述してください")
    private String title;

    @NotNull("説明を入力してください")
    private String description;
}

入力値を受け取るだけのものなのでidやcreated_atなどは存在しません。
バリデーションを書くシチュエーションが多そうです。

TodoController

@RequestMapping("/form")
    public String form(TodoForm form){
        return "form";
    }

コントローラーの引数にFormクラスを指定することでThymeleafと値をやり取りすることができます。

Thymeleafの命名規則でオブジェクトの頭文字は小文字にする必要があります

つまりth:object="${todoForm}"のように変数名で受け取ることができます。

Entity

  • データベースのカラムに対応するオブジェクト
  • 全件取得やIDして1件取得したり、登録・更新するときに使用する値を格納するためにする
  • データベースと対応する必要があるので@IDで示したり(JPAの場合)、全カラムに対応する必要がある

例えば以下のようなテーブルがあったとする

employees

ID name department_id
1 後藤 1
2 喜多 3
3 山田 4
4 伊地知 5

departments

ID name
1 営業部
2 管理部
3 人事部
4 開発部
5 企画部

このテーブルに対応するEntityはこのようになる

EmployeeEntity

@Entity
@Data
@Table(name="employees")
public class EnployeeEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private Long department_id;
}

DepartmentEntity

@Entity
@Table(name = "departments")
@Data
public class DepartmentEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
}

dto

  • Entityだけでは格納できない情報を格納するためのオブジェクト
    例えば、先ほどのemployeesテーブルとdepartmentsテーブルをINNER JOINして以下のような結果を得たいとする
employee_id employee_name department_name
1 後藤 営業部
2 喜多 人事部
3 山田 開発部
4 伊地知 企画部

このときにEmployeeEntityだけではdepartment_nameというフィールドが存在しないので値を格納することができません。

そのときに使用するのがDTOです。

EmployeeDto

@Data
@Entity
public class EmployeeDto {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private String department_name;
}

このようにすることでEntityが持っていない情報を格納することができるため、関連する複数のEntityを結合し、サービス層に必要な形式でオブジェクトを渡すことが可能になります。

Discussion