LoginSignup
1
2

More than 1 year has passed since last update.

Java CSVからのデータを表示させる(spring boot)

Posted at

プロローグ

Java(spring boot)を触り始めてコードを書き始めて2週間程度ですが、
色々と使い方を覚えてきたので、メモとして記録を残します。

不備不足だったり、理解が浅くて説明不足なところがあるかと思いますが、
勉強して更新していきたいとは思っています。

このプログラミングを書く前の理解度としては、アノテーションも分からずでした。
spring bootも分からなかったので、Ruby on Railsと同じようにMVCでデータを取得、加工、表示するのかなと思っていました。

計算処理を行う「service」というものの存在も知りませんでした。

この記事で何ができるようになるか

まだ自分自身もそれぞれのクラスの役割を理解してませんが、
データを受け取って表示させることができると思います。

まずは、わからないなりに手を動かして画面に表示させることで、なんとなくの流れをつかむことが大切なのかなと思います。

この記事でやることとしては、ファイル内に作成したCSVファイルを読み取って、画面上に表示させるというイメージです。

また、ただ読み取って表示させるだけではなく、合計点を算出していきたいと思います。

Javaの構造把握

まずは、ファイルの構造を紹介していきます。

file

src/main/java
 ├ resources
    files
       scores.csv
    templates
       score.html
       score
         total.html
 ├ repository
 ├   ScoreCsvRepository.java
   entity
 ├   ScoreEntity.java
   serivice
 ├   ScoreService.java
   dto
 ├   ScoreDto.java
   controller
     ScoreController.java

1.CSV

resources/files/scores.csv にあるデータをHTMLまでもっていき画面上に出したいとします。
CSVに下記のようなデータがあるとします。

scores.csv
name,english,math,
山田,50,38
田中,30,47
高橋,64,58
鈴木,NA,94
石井,74,28
坂本,73,85

これをイメージとしては下記画像のようにデータを渡していきます。
この記事では、「加工したデータ」というのはenglishとmathの合計点を算出したもの、とします。

スクリーンショット (6).png

フレームワークによってmodelの定義が異なるみたいです。
勉強になります・・。

【参考文献】
Webアプリケーション開発者から見た、MVCとMVP、そしてMVVMの違い

2.Repository

Repositoryでは、CSVのデータをとってきます。
CSVデータだけではなく、DBからデータをとってくることもできます。

とってきたデータをEntityという入れ物に入れますが、
その時にどこのどのデータを入れるか、をここで書いていきます。

scoreRepository.java
package repository;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.List;

import pg.skilltest.entity.ScoreEntity;

public class ScoreCsvRepository {
    public List<ScoreEntity> getAllScores() {
        var result = new ArrayList<ScoreEntity>();
        //resultは、ArrayListで作成したデータと定義しています。

        BufferedReader br = null;
        String score_csv = "src/main/resources/files/scores.csv";
    // 読み込みたいCSVファイルを指定します。
        try {
            File file = new File(score_csv);
            br = new BufferedReader(new FileReader(file));
            String line;
            String[] data;
            br.readLine();
      //CSVデータの1行目は見るとわかるのですが、「name,english,math」となっています。
      //この先のコードでenglishとmathの合計点を出したいので、タイトルの1行目を飛ばすために、
      //「br.readLine();」とここで書くと1行目は計算されず読み込まれます。
            while ((line = br.readLine()) != null) {
                data = line.split(",");
                var scoreEntity = new ScoreEntity();
                //ここの「setGroup」などは、例えば「setGroup」の場合
         //(data[0])を次のEntityに入れる棚のgroupという名前に入れるというのを示しています(わかりにくい…)
                scoreEntity.setName(data[0]);
                if(data[1].equals("NA") == false) {
                    scoreEntity.setEnglish(Integer.parseInt(data[1]));
                    scoreEntity.setMath(Integer.parseInt(data[2]));
                } else {
                    scoreEntity.setEnglish(0);
                    scoreEntity.setMath(0);
                }
                result.add(scoreEntity);
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
        } finally {
            try {
                br.close();
            } catch (Exception e) {
                System.out.println(e.getMessage());
            }
        }
        return result;
    }
}

CSVの読み込みは、下記の記事を参考に書きました。
ありがとうございます。

【参考文献】
JavaでのCSVファイル読み込み方法とは?

3.Entity

Repositoryで記載した「getName」などはここと連動しています。
つまり、.getName(data[0])と書いたら、data[0]が下記のnameに入っていくイメージです。
@Dataに関しては、便利だ!と思って使っていますが、よくわかっていないので、
@Dataなしでも書けるように便利なものも調べておきます・・。
getNameとやってEntityにデータが入っていくのも@Dataのおかげです)

ScoreEntity.java
package entity;

import lombok.Data;

@Data
public class ScoreEntity {
    private String name;
    private Integer english;
    private Integer math;
}

4.Servic

Serviceでは、Entityにいれたデータをもってきて、加工します。

ScoreService.java
package service;

import java.util.ArrayList;
import java.util.List;

import dto.ScoreDto;
import repository.ScoreCsvRepository;

public class ScoreService {
    public List<ScoreDto> getAllTotalScores() {
        var result = new ArrayList<ScoreDto>();
        var scoreCsvRepository = new ScoreCsvRepository();
        var allScore = scoreCsvRepository.getAllScores();

        for (int i = 0; i < allScore.size(); i++) {
            var score = allScore.get(i);
            var total = score.getEnglish() + score.getMath();
            var name = score.getName();
            var scoreDto = new ScoreDto();
      //Entityの時と同じように、Dtoにそれぞれの値をいれています。
            scoreDto.setTotal(total);
            scoreDto.setName(name);

            result.add(scoreDto);
        }
        return result;
    }

}

5.Dto

Integer など最初を大文字にすると、その値がnullの場合も入ります。
ここあたりも知らないことあるので、深堀したいです…。

ScoreDto.java
package dto;

import lombok.*;

@Data
public class ScoreDto {
    private String name;
    private Integer total;
}

6.Controller

ScoreController.java
package controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;


import service.ScoreService;


@Controller
public class ScoreController {

  // 得点一覧画面
    @RequestMapping("/score")
    public String index() {
        return "score";
    }

  // 合計画面
    @RequestMapping("/score/total")
    public String total(Model model) {
        var scoreService = new ScoreService();
        model.addAttribute("result", scoreService.getAllTotalScores());
                // `.getAllTotalScores()`がServiceで記載してあるのと一致しています。
         //その値を`result`に入れています。そしてHTMLに渡しています。

        return "score/total";
    }
}

7.HTML

かなりざっくりですが、下記のように記載すれば、controllerからデータを受け取ることができます。
この書き方はThymeleafと呼ばれるものです。
あまり書いたことないので、(これがはじめて)ここも勉強していかないとです…。

total.html

【結果】
    <p th:each="totalDto : ${result}">
  <!--Controllerの`result`をここで呼び出してeachで回しています。-->
      <span th:text="${totalDto.name}"></span>
  <!-- Dtoで定義した`name`を呼び出しています。-->
      <span th:text="${totalDto.total}"></span>
    </p>

終わりに

なんとなくJSと似ているところがあったりして、初めてプログラミングを学んだ時より理解はありましたが、
MVCだけではないクラスを使ってデータを加工するというのが初めてだったので、戸惑いがありました。

ただ、かなり整理されて作ることができるので、わかりやすいなと思いました。
まだまだなところや間違っていることがあるかと思いますので、勉強して更新していきたいです。

1
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
1
2