LoginSignup
3
9

More than 5 years have passed since last update.

Spring Boot 自分用メモ crossfish21

Posted at

src/main/resources/config messages_ja.properties

#バリデーションエラー時のメッセージ設定
javax.validation.constraints.NotEmpty.message={0}は入力必須です
javax.validation.constraints.NotNull.message={0}は入力必須です
javax.validation.constraints.Min.message={0}は{1}以上にしてください
javax.validation.constraints.Max.message={0}は{1}以下にしてください
#DecimalMax と DecimalMin は{2}が指定の数値になるので注意
javax.validation.constraints.DecimalMax.message={0}は{2}以下にしてください
javax.validation.constraints.DecimalMin.message={0}は{2}以下にしてください
javax.validation.constraints.Digits.message={0}の整数部と小数部の桁数が正しくありません
javax.validation.constraints.Email.message={0}はEメール形式にしてください
javax.validation.constraints.Future.message={0}は未来の日付で入力してください
javax.validation.constraints.Past.message={0}は過去の日付で入力してください
javax.validation.constraints.Pattern.message={0}は指定のパターンにマッチしません
#Size Length Range は{2}がminの値、{1}がmaxの値になるので注意
javax.validation.constraints.Size.message={0}の文字列長は{2}~{1}の範囲にしてください
org.hibernate.validator.constraints.Length.message={0}の文字列長は{2}~{1}の範囲にしてください
org.hibernate.validator.constraints.Range.message={0}は{2}~{1}の数値にしてください


#型変換に失敗した場合のエラーメッセージ設定
typeMismatch={0}を変換できません
typeMismatch.int={0}を数値に変換できません
typeMismatch.double={0}を数値に変換できません
typeMismatch.float={0}を数値に変換できません
typeMismatch.long={0}を数値に変換できません
typeMismatch.short={0}を数値に変換できません
typeMismatch.java.lang.Integer={0}を数値に変換できません
typeMismatch.java.lang.Double={0}を数値に変換できません
typeMismatch.java.lang.Float={0}を数値に変換できません
typeMismatch.java.lang.Long={0}を数値に変換できません
typeMismatch.java.lang.Short={0}を数値に変換できません
typeMismatch.java.math.BigDecimal={0}を数値に変換できません
typeMismatch.java.math.BigDecimal={0}を数値に変換できません
typeMismatch.java.math.BigInteger={0}を数値に変換できません
typeMismatch.java.time.LocalDate={0}を日付に変換できません
typeMismatch.java.time.LocalDateTime={0}をタイムスタンプに変換できません
typeMismatch.java.time.LocalTime={0}を時刻に変換できません

src/main/resources/config messages.properties

 message.text01=MESSAGE_TEXT01
 message.text02=MESSAGE_TEXT02
 message.text03=MESSAGE_TEXT03
 message.text04=\u65E5\u672C\u8A9E\u30E1\u30C3\u30BB\u30FC\u30B8

src/main/resources/static/css base.css

#wrapper{
    padding: 100px;
}

h3{
    margin-bottom: 25px;
}

src/main/resources/ application.properties

spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://localhost:5432/hsystem?currentSchema=schemah
spring.datasource.username=role21
spring.datasource.password=yellowAzarashi21
server.port=8091
spring.messages.basename=config/messages
spring.messages.cache-duration=-1
spring.messages.encoding=UTF-8
spring.thymeleaf.prefix=classpath:/page/
spring.thymeleaf.mode=HTML
spring.thymeleaf.cache=false
#spring.thymeleaf.cache=falseにすると、テンプレートの変更がアプリの再起動をしなくても反映される。ただし、本番では必ずtrueにすること
spring.thymeleaf.cache=false
spring.jpa.show-sql=true

src/main/resources/ hibernate.properties

hibernate.jdbc.lob.non_contextual_creation = true

com.crossfish.p1.config MessageConfig.java

package com.crossfish.p1.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.validation.Validator;
import org.springframework.validation.beanvalidation.LocalValidatorFactoryBean;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@SuppressWarnings("deprecation")
@Configuration
public class MessageConfig extends WebMvcConfigurerAdapter{
    @Autowired
    private MessageSource messageSource;

    @Bean
    public LocalValidatorFactoryBean validator()
    {
        LocalValidatorFactoryBean localValidatorFactoryBean = new LocalValidatorFactoryBean();
        localValidatorFactoryBean.setValidationMessageSource(messageSource);
        return localValidatorFactoryBean;
    }

    @Override
    public Validator getValidator()
    {
        return validator();
    }
}

com.crossfish.p1.controller PageController.java

package com.crossfish.p1.controller;

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

@Controller
@RequestMapping("page")
public class PageController {

    @RequestMapping("main_menu")
    public String mainMenu() {
        return "/page/main_menu";
        // メンメニューへ
    }

    @RequestMapping("outsourcing_worktime_register")
    public String outsourcingWorktime() {
        return "/page/outsourcing_worktime_register";
        // 外注者の稼働時間登録画面へ
    }
}

com.crossfish.p1.controller RegisterController.java

package com.crossfish.p1.controller;

import java.io.InputStream;

import javax.servlet.http.HttpSession;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;

import com.crossfish.p1.services.OutsourcingWorkingTimeServiceReadOnly;
import com.crossfish.p1.services.OutsourcingWorkingTimeServiceTransaction;

/*
 * @author Benten
 * DBへデータを登録する処理のコントローラー
 */
@Controller
@RequestMapping("register")
public class RegisterController {

  @Autowired
  HttpSession session;

  @Autowired
  private OutsourcingWorkingTimeServiceTransaction outsourcingWorkingTimeServiceTransaction;

  @Autowired
  private OutsourcingWorkingTimeServiceReadOnly outsourcingWorkingTimeServiceReadOnly;


  /*
   * @param multipartFile  アップされたファイル
   * @param model  Modelインスタンス
   * @return String 移動先のページのパス
   */
  @RequestMapping(value = "outsourcing_worktime_register_execute",method = RequestMethod.POST)
  public String outsourcingWorktimeRegisterExecute(
      @RequestParam("file01") MultipartFile multipartFile, Model model) {

    if (multipartFile.isEmpty()) {
      // ファイルがアップされていない場合
      model.addAttribute("errorMessage", "ファイルが指定されていません");
      return "/page/outsourcing_worktime_register";
    }

    Integer int1 = outsourcingWorkingTimeServiceReadOnly.getLastRivisionNumber("2018年度予算", "001");
    outsourcingWorkingTimeServiceTransaction.insert();


    try (InputStream input = multipartFile.getInputStream()) {

      try (XSSFWorkbook outsourcingWorktimeBook = (XSSFWorkbook) WorkbookFactory.create(input)) {

        XSSFSheet targetSheet = outsourcingWorktimeBook.getSheet("外注者の稼働時間");

        if (targetSheet == null) {  // シートが取得できなかった場合
          System.out.println("シートの取得に失敗");
        }

        String departmentString = ""; // 所属部署の18桁コード
        String versionString = ""; // バージョン名

        Row row03 = targetSheet.getRow(2); // 3行目を取得

        Cell cell01 = row03.getCell(5);

        if (cell01.getCellTypeEnum() != CellType.BLANK
            && cell01.getCellTypeEnum() == CellType.STRING) {
          // 一応文字列型であることと、空白でないことをチェック
          departmentString = cell01.getStringCellValue();
        }

        Row row05 = targetSheet.getRow(4);  // 3行目を取得
        cell01 = row05.getCell(2);
        versionString = cell01.getStringCellValue();

      } catch (Exception e) {
        e.printStackTrace();
      }

    } catch (Exception e) {
      e.printStackTrace();
    }

    return "/page/outsourcing_worktime_register";
  }
}

com.crossfish.p1.entities OutsourcingWorkingTime.java

package com.crossfish.p1.entities;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.Table;

import lombok.Data;

@Entity
@Data
@IdClass(value = OutsourcingWorkingTimeKey.class)     // コメント
@Table(name = "outsourcing_working_time",schema="schemah")
public class OutsourcingWorkingTime  implements Serializable {

    private static final long serialVersionUID = 1L;

  @Id
  @Column(name = "version_name")
  private String versionName;

  @Id
  @Column(name = "department_code")
  private String departmentCode;

  @Id
  @Column(name = "revision")
  private Integer revision;

  @Id
  @Column(name = "staff_no")
  private String staffNo;

  @Column(name = "staff_name")
  private String staffName;

  @Column(name = "company_name")
  private String companyName;

  @Column(name = "basetime_4")
  private Double basetime4;

  @Column(name = "overtime_4")
  private Double overtime4;

  @Column(name = "businessPlace_4")
  private String businessPlace4;

  @Column(name = "basetime_5")
  private Double basetime5;

  @Column(name = "overtime_5")
  private Double overtime5;

  @Column(name = "businessPlace_5")
  private String businessPlace5;

  @Column(name = "basetime_6")
  private Double basetime6;

  @Column(name = "overtime_6")
  private Double overtime6;

  @Column(name = "businessPlace_6")
  private String businessPlace6;

  @Column(name = "basetime_7")
  private Double basetime7;

  @Column(name = "overtime_7")
  private Double overtime7;

  @Column(name = "businessPlace_7")
  private String businessPlace7;

  @Column(name = "basetime_8")
  private Double basetime8;

  @Column(name = "overtime_8")
  private Double overtime8;

  @Column(name = "businessPlace_8")
  private String businessPlace8;

  @Column(name = "basetime_9")
  private Double basetime9;

  @Column(name = "overtime_9")
  private Double overtime9;

  @Column(name = "businessPlace_9")
  private String businessPlace9;

  @Column(name = "basetime_10")
  private Double basetime10;

  @Column(name = "overtime_10")
  private Double overtime10;

  @Column(name = "businessPlace_10")
  private String businessPlace10;

  @Column(name = "basetime_11")
  private Double basetime11;

  @Column(name = "overtime_11")
  private Double overtime11;

  @Column(name = "businessPlace_11")
  private String businessPlace11;

  @Column(name = "basetime_12")
  private Double basetime12;

  @Column(name = "overtime_12")
  private Double overtime12;

  @Column(name = "businessPlace_12")
  private String businessPlace12;

  @Column(name = "basetime_1")
  private Double basetime1;

  @Column(name = "overtime_1")
  private Double overtime1;

  @Column(name = "businessPlace_1")
  private String businessPlace1;

  @Column(name = "basetime_2")
  private Double basetime2;

  @Column(name = "overtime_2")
  private Double overtime2;

  @Column(name = "businessPlace_2")
  private String businessPlace2;

  @Column(name = "basetime_3")
  private Double basetime3;

  @Column(name = "overtime_3")
  private Double overtime3;

  @Column(name = "businessPlace_3")
  private String businessPlace3;
}


com.crossfish.p1.entities OutsourcingWorkingTimeKey

package com.crossfish.p1.entities;

import java.io.Serializable;

import lombok.Data;

@Data
public class OutsourcingWorkingTimeKey implements Serializable {
// OutsourcingWorkingTimeエンティティの複合主キーを設定するクラス

  private String versionName;
  private String departmentCode;
  private Integer revision;
  private String staffNo;
}

com.crossfish.p1.repositories OutsourcingWorkingTimeRepository

package com.crossfish.p1.repositories;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import com.crossfish.p1.entities.OutsourcingWorkingTime;
import com.crossfish.p1.entities.OutsourcingWorkingTimeKey;

public interface OutsourcingWorkingTimeRepository
    extends JpaRepository<OutsourcingWorkingTime, OutsourcingWorkingTimeKey> {

// 最終のリビジョン番号を取得する
  @Query(value = "SELECT DISTINCT revision FROM outsourcing_working_time o WHERE version_name=:versionName AND "
          + "department_code=:departmentCode ORDER BY revision DESC LIMIT 1", nativeQuery = true)
// 先頭にvalue = を、末尾に, nativeQuery = trueをつける。valueはObject型になる。メソッドの戻り値として使える
// outsourcing_working_timeはテーブル名だが、Entityクラスの名前ではなくDBのテーブル名をそのまま記述することに注意
  public Integer getLastRivisionNumber(
          @Param("versionName")String  versionName,
          @Param("departmentCode")String  departmentCode);
}

com.crossfish.p1.services OutsourcingWorkingTimeServiceReadOnly.java

package com.crossfish.p1.services;

public interface OutsourcingWorkingTimeServiceReadOnly{

    public Integer getLastRivisionNumber(String  versionName,String  departmentCode);

}

com.crossfish.p1.services OutsourcingWorkingTimeServiceReadOnlyImple

package com.crossfish.p1.services;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.crossfish.p1.repositories.OutsourcingWorkingTimeRepository;

@Service
@Transactional(readOnly = true)
public class OutsourcingWorkingTimeServiceReadOnlyImple implements OutsourcingWorkingTimeServiceReadOnly {

    @Autowired
    private OutsourcingWorkingTimeRepository outsourcingWorkingTimeRepository;


    @Override
    public Integer getLastRivisionNumber(String  versionName,String  departmentCode) {

        Integer rivisionList = outsourcingWorkingTimeRepository.getLastRivisionNumber
                (versionName, departmentCode);

        return rivisionList;
    }
}

com.crossfish.p1.services OutsourcingWorkingTimeServiceTransaction

package com.crossfish.p1.services;

public interface OutsourcingWorkingTimeServiceTransaction{

    public void insert();
}

com.crossfish.p1.services OutsourcingWorkingTimeServiceTransactionImple

package com.crossfish.p1.services;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.crossfish.p1.entities.OutsourcingWorkingTime;
import com.crossfish.p1.repositories.OutsourcingWorkingTimeRepository;

@Service
@Transactional(readOnly = false)
public class OutsourcingWorkingTimeServiceTransactionImple implements OutsourcingWorkingTimeServiceTransaction {

    @Autowired
    private OutsourcingWorkingTimeRepository outsourcingWorkingTimeRepository;

    @Override
    public void insert() {
      OutsourcingWorkingTime outsourcingWorkingTime = new OutsourcingWorkingTime();
      outsourcingWorkingTime.setVersionName("2018年度予算");
      outsourcingWorkingTime.setDepartmentCode("002");
      outsourcingWorkingTime.setRevision(4);
      outsourcingWorkingTime.setStaffNo("7Y4001005");
      outsourcingWorkingTime.setStaffName("高橋朝子");
      outsourcingWorkingTime.setCompanyName("会社222");
      outsourcingWorkingTime.setBasetime4(156.23);
      outsourcingWorkingTime.setOvertime4(200.582);
      outsourcingWorkingTime.setBusinessPlace4("事業所100");
      outsourcingWorkingTime = outsourcingWorkingTimeRepository.saveAndFlush(outsourcingWorkingTime);
    }
}

STSのコード

package p1.controller;

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

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

import p1.repository.R02;
import p1.repository.entity.Table01;
import p1.repository.entity.Table01.Sex;
import p1.service.S01;
import p1.service.S02;

@Controller
@RequestMapping("c01")
public class C01 {

    @Autowired
    private S01 s01;  // S01はサービスクラス

    @Autowired
    private S02 s02;

    @Autowired
    private R02 r02;  // R02はリポジトリ


    @RequestMapping("01")  // リポジトリを使わないで、テーブルのデータ一覧を取得
    public String list01(Model model) {
        model.addAttribute("table01Data", s01.getTable01List());
        return "01/list01";
    }

    @RequestMapping("02")  // リポジトリを使って、テーブルのデータ一覧を取得
    public String list02(Model model) {
        model.addAttribute("table01Data", s02.getTable01List());
        return "01/list01";
    }

    @RequestMapping("03/{id}")  // id指定で、1つのデータを取得。存在しないidを指定するとエラーになる
    public String getOne(Model model,@PathVariable Integer id) {
        model.addAttribute("table01Data", s02.getOne(id));
        // getOne()は、サービスクラスに実装している
        // id指定で、データを参照するEntityをリターンする。該当するデータが存在しない場合はエラー発生
        return "01/list01";
    }

    @RequestMapping("04/{id}")  // id指定で、1つのデータを取得。存在しないidを指定するとエラーになる
    public String findById(Model model,@PathVariable Integer id) {

        Optional<Table01> table01 = s02.findById(id);
        // findById()は、サービスクラスに実装している
        // id指定で、Entityをリターンする。該当するデータが存在しない場合はnullが返るのでOptionalにする

        if(!table01.equals(Optional.empty())) {  // データが存在する場合。.equals(Optional.empty())にすることに注意
            model.addAttribute("table01Data", table01.get());  // .get()にすることに注意
            return "01/list01";
        }else {
            return "error/error01";
        }
    }

    @RequestMapping("05/{id1}/{id2}/{id3}")  // 3つのid指定で、データを取得
    // findAllById(List<Integer>) は、Postgresではエラーになってしまうらしい
    public String multiId(Model model, @PathVariable Integer id1, @PathVariable Integer id2, @PathVariable Integer id3) {

        List<Integer> idList = new ArrayList<>();
        idList.add(id1);
        idList.add(id2);
        idList.add(id3);
        model.addAttribute("table01Data", r02.findAllById(idList));
        // findAllById()は、リポジトリに存在している
        return "01/list01";
    }

    @RequestMapping("06/{id1}/{id2}")  // idがid1~id2の範囲のデータを取得
    public String betweenId(Model model, @PathVariable Integer id1, @PathVariable Integer id2) {
        model.addAttribute("table01Data", r02.findByIdBetween(id1,id2));
        return "01/list01";
    }

    @RequestMapping("07/{firstName}")  // firstNameで検索(完全一致)
    public String firstName(Model model, @PathVariable String firstName) {
        model.addAttribute("table01Data", r02.findByFirstName(firstName));
        return "01/list01";
    }

    @RequestMapping("08/{str}")  // firstNameにstrが含まれるデータを検索(firstName like %str% になる)
    public String findByFirstNameContains(Model model, @PathVariable String str) {
        model.addAttribute("table01Data", r02.findByFirstNameContains(str));
        return "01/list01";
    }

    @RequestMapping("17/{str}")  // firstNameにstrが含まれないデータを検索(firstName not like %str% になる)
    public String findByFirstNameNotContains(Model model, @PathVariable String str) {
        model.addAttribute("table01Data", r02.findByFirstNameNotContains(str));
        return "01/list01";
    }

    @RequestMapping("33/{str}")  // firstNameがstrで始まるデータを検索(firstName like str% になる)
    public String findByFirstNameStartsWith(Model model, @PathVariable String str) {
        model.addAttribute("table01Data", r02.findByFirstNameStartsWith(str));
        return "01/list01";
    }

    @RequestMapping("34/{str}")  // firstNameがstrで終わるデータを検索(firstName like %str になる)
    public String findByFirstNameEndsWith(Model model, @PathVariable String str) {
        model.addAttribute("table01Data", r02.findByFirstNameEndsWith(str));
        return "01/list01";
    }

    @RequestMapping("09/{id}/{firstName}")  // idとfirstNameのAND条件で検索
    public String findByIdAndFirstName(Model model, @PathVariable Integer id, @PathVariable String firstName) {
        model.addAttribute("table01Data", r02.findByIdAndFirstName(id,firstName));
        return "01/list01";
    }

    @RequestMapping("10/{id}/{firstName}")  // idとfirstNameのOR条件で検索
    public String findByIdOrFirstName(Model model, @PathVariable Integer id, @PathVariable String firstName) {
        model.addAttribute("table01Data", r02.findByIdOrFirstName(id,firstName));
        return "01/list01";
    }

    @RequestMapping("11/{id}")  // idが~未満の条件で検索
    public String findByIdLessThan(Model model, @PathVariable Integer id) {
        model.addAttribute("table01Data", r02.findByIdLessThan(id));
        return "01/list01";
    }

    @RequestMapping("12/{id}")  // idが~より大きいの条件で検索
    public String findByIdGreaterThan(Model model, @PathVariable Integer id) {
        model.addAttribute("table01Data", r02.findByIdGreaterThan(id));
        return "01/list01";
    }

    @RequestMapping("13")  // mailAddressがnullのデータを検索
    public String findByMailAddressIsNull(Model model) {
        model.addAttribute("table01Data", r02.findByMailAddressIsNull());
        return "01/list01";
    }

    @RequestMapping("14")  // mailAddressがnullではないデータを検索
    public String findByMailAddressNotNull(Model model) {
        model.addAttribute("table01Data", r02.findByMailAddressNotNull());
        return "01/list01";
    }

    @RequestMapping("15/{id1}/{id2}")  // idがid1~id2の範囲のデータを取得し、id昇順で並べ替え
    public String findByIdBetweenOrderByIdAsc(Model model, @PathVariable Integer id1, @PathVariable Integer id2) {
        model.addAttribute("table01Data", r02.findByIdBetweenOrderByIdAsc(id1,id2));
        return "01/list01";
    }

    @RequestMapping("16/{id1}/{id2}")  // idがid1~id2の範囲のデータを取得し、id降順で並べ替え
    public String findByIdBetweenOrderByIdDesc(Model model, @PathVariable Integer id1, @PathVariable Integer id2) {
        model.addAttribute("table01Data", r02.findByIdBetweenOrderByIdDesc(id1,id2));
        return "01/list01";
    }

    @RequestMapping("18/{id1}/{id2}/{id3}")  // idがid1,id2,id3のいずれかであるデータを検索(in (id1,id2,id3) になる)
    public String findByIdIn(Model model, @PathVariable Integer id1, @PathVariable Integer id2, @PathVariable Integer id3) {
        List<Integer> idList = new ArrayList<>();
        idList.add(id1);
        idList.add(id2);
        idList.add(id3);
        model.addAttribute("table01Data", r02.findByIdIn(idList));
        return "01/list01";
    }

    @RequestMapping("19/{id1}/{id2}/{id3}") // idがid1,id2,id3のいずれでもないデータを検索(not in (id1,id2,id3) になる)
    public String findByIdNotIn(Model model, @PathVariable Integer id1, @PathVariable Integer id2, @PathVariable Integer id3) {
        List<Integer> idList = new ArrayList<>();
        idList.add(id1);
        idList.add(id2);
        idList.add(id3);
        model.addAttribute("table01Data", r02.findByIdNotIn(idList));
        return "01/list01";
    }

    @RequestMapping("20/{str}")  // firstNameにstrが含まれるデータを検索。like %str%の形にする
    // firstName like str になるのだが、前後に%をつけないといけないので、like %str%にするならContainsのほうが簡単。前方一致・後方一致に使うべきだろう
    public String findByFirstNameLike1(Model model, @PathVariable String str) {
        str = "%" + str + "%";
        model.addAttribute("table01Data", r02.findByFirstNameLike(str));
        return "01/list01";
    }

    @RequestMapping("21/{str}")  // firstNameにstrが含まれるデータを検索。前方一致
    public String findByFirstNameLike2(Model model, @PathVariable String str) {
        str = str + "%";
        model.addAttribute("table01Data", r02.findByFirstNameLike(str));
        return "01/list01";
    }

    @RequestMapping("22/{str}")  // firstNameにstrが含まれるデータを検索。後方一致
    public String findByFirstNameLike3(Model model, @PathVariable String str) {
        str = "%" + str;
        model.addAttribute("table01Data", r02.findByFirstNameLike(str));
        return "01/list01";
    }

    @RequestMapping("23")  // 総デー多数を取得する
    public String dataCount(Model model) {
        model.addAttribute("dataCount", r02.count());
        // R02 リポジトリに結びついているTable01の総データ数を取得
        return "other/dataCount";
    }

    @RequestMapping("24/{id}")  // 指定のidのデータが存在するかを調べる
    public String dataExists(Model model, @PathVariable Integer id) {

        Table01 table01 = new Table01();
        table01.setId(id);  // 検索条件のidを設定

        Example<Table01> example = Example.of(table01);
        // Exampleは検索条件を設定するクラス?なのかな
        model.addAttribute("result", r02.exists(example));
        // 設定したidのデータが存在するかを取得する。戻り値はboolean
        // ※リポジトリのインターフェイスにはexists()は無くても動作する

        return "other/result01";  // 結果を表示するページへ
    }

    @RequestMapping("25")  // Sexがmaleのデータの数を取得
    public String maleDataCount(Model model) {

        Table01 table01 = new Table01();
        table01.setSex(Sex.male);  // 検索条件のsexを設定

        Example<Table01> example = Example.of(table01);
        model.addAttribute("result", r02.count(example));
        // データ数を取得する
        return "other/result01";  // 結果を表示するページへ
    }

    @RequestMapping("26")  // Sexがmaleのデータを全取得
    public String maleData(Model model) {

        Table01 table01 = new Table01();
        table01.setSex(Sex.male);  // 検索条件のsexを設定

        Example<Table01> example = Example.of(table01);
        model.addAttribute("table01Data", r02.findAll(example));
        // 検索条件に合うデータを全取得
        return "01/list01";  // 結果を表示するページへ
    }

    @RequestMapping("27")  // Sexがmaleで、idが5のデータを全取得
    public String maleAnd5Data(Model model) {

        Table01 table01 = new Table01();
        table01.setSex(Sex.male);  // 検索条件のsexを設定
        table01.setId(5);  // 2番目の条件も設定できる

        Example<Table01> example = Example.of(table01);
        model.addAttribute("table01Data", r02.findAll(example));
        return "01/list01";  // 結果を表示するページへ
    }

    @RequestMapping("28")  // birthday昇順でソートする
    public String sort1(Model model) {
        model.addAttribute("table01Data", r02.findAll(new Sort("birthday")));
        // birthday昇順でソート
        return "01/list01";  // 結果を表示するページへ
    }

    @RequestMapping("29")  // id降順でソートする
    public String sort2(Model model) {
        model.addAttribute("table01Data", r02.findAll(new Sort(Sort.Direction.DESC,("id"))));
        // id降順でソート
        return "01/list01";  // 結果を表示するページへ
    }

    // ※ソートの条件指定はもっと複雑にできるので、詳しくは調べて



    @RequestMapping("30")  // データがDBに反映されるタイミング
    @Transactional(readOnly=false)
    public String updateTiming(Model model) {
        List<Table01> list = r02.findAll();
        list.get(0).setFirstName("ZZZ");   // Entiryの値を変更しただけでは、DBへは反映されない
        r02.findAll();   // テーブルにアクセスするので、この時点でupdateが実行され、DBへ反映される
        list.get(0).setLastName("XXX");
        r02.flush();  // 明示的にupdateを実行。DBへ反映される
        list.get(0).setFirstName("YYY");  // DBへ反映されていない変更は、トランザクションの終了時にDBへ反映される

        return "01/list01";  // 結果を表示するページへ

        //ということを本には書いてあるけど、実際にはトランザクションを実行するまではDBには反映されていないみたい。
        //ただ信頼できそうなサイトでも同じ事を書いてあるので、実際は反映されているのかも
    }


    @RequestMapping("31")  // データの更新と挿入
    @Transactional(readOnly=false)
    public String updateAndInsert(Model model) {
        Table01 table01 = new Table01();
        table01.setId(10);  // 存在するデータのidを指定
        table01.setFirstName("PPP");
        table01.setLastName("lll");
        r02.save(table01);  // Entityの変更を保存。DBへの反映はまだされない。既存のデータなので更新になる

        Table01 table01_2 = new Table01();
        table01_2.setId(20);  // 存在しないデータのidを指定
        table01_2.setFirstName("EEE");
        table01_2.setLastName("eee");
        table01_2 = r02.saveAndFlush(table01_2);  
        // Entityの変更を保存し、即座にDBに反映。既存のデータではないので挿入になる。saveでも同じ役割になる(DB反映はされないが)

        model.addAttribute("table01Data", table01_2);
        return "01/list01";  // 結果を表示するページへ
    }


    @RequestMapping("32")  // データの削除
    @Transactional(readOnly=false)
    public String delete(Model model) {

        Table01 table01 = new Table01();
        table01.setId(10);  // 存在するデータのidを指定
        r02.delete(table01);  // データを削除

        Table01 table01_2 = new Table01();
        table01_2.setId(30);  // 存在しないデータのidを指定
        table01_2.setFirstName("EEE");  
        // 存在しないidのEntityでも、Not Nullのフィールドは値を設定しないとエラーになる
        table01_2.setLastName("eee");
        r02.delete(table01_2);
        // 存在しないデータを削除しても、エラーにはならないが意味は無い

        Table01 table01_3 = new Table01();
        Table01 table01_4 = new Table01();
        Table01 table01_5 = new Table01();
        table01_3.setId(2);  // 存在するデータのidを指定
        table01_4.setId(3);  // 存在するデータのidを指定
        table01_5.setId(4);  // 存在するデータのidを指定
        List<Table01> list = new ArrayList<>();
        list.add(table01_3);
        list.add(table01_4);
        list.add(table01_5);
        r02.deleteInBatch(list);   // listのEntityを全て削除する

        r02.deleteAll();  // 全データを削除する

        r02.deleteAllInBatch();  // 全データを削除する

        // ※ "InBatch" が付くメソッドは、1つのクエリーですべての処理を実行するので、多数のEntityを処理する場合は効率がいい
        // "InBatch" が付かないメソッドは、Entityごとにクエリを発行するので処理が遅くなることに注意
        return "01/list01";
    }   
}



package p1.restControllers;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

import javax.servlet.http.HttpServletResponse;

import org.springframework.http.MediaType;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController  // 文字列等のデータ、JsonやXML等を返すWebAPI用のコントローラとして使う
public class RestController01 {

    @RequestMapping("rest01")
    public String aaa() {
        return "rest01にアクセスがありました";
        // http://localhost:8090/rest01  にアクセスすれば、"rest01にアクセスがありました"と表示される
    }

    @RequestMapping("rest02")
    public void bbb(HttpServletResponse res) throws IOException {
    // HttpServletResponseで、指定のhtmlファイルの内容をhtml形式で出力する。RestControllerはこのような使い方が多いか
        File file = new File("src/main/resources/files/aaa.html");
        res.setContentLength((int) file.length());
        res.setContentType(MediaType.TEXT_HTML_VALUE);
        // MediaType.TEXT_HTML_VALUE で、HTML形式を指定。他にもファイルタイプを指定する定数がたくさんある
        FileCopyUtils.copy(new FileInputStream(file), res.getOutputStream());
        // aaa.htmlの内容をコピーして、レスポンスとして出力する。結果としてaaa.htmlをViewとして表示させたのと同じことになる
    }
}




package p1.controller;

import java.util.List;
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;

import p1.repository.ProductMasterRepository;
import p1.repository.SalesDataRepository;
import p1.repository.StaffMasterRepository;
import p1.repository.WorkingDataRepository;
import p1.repository.entity.Product_master;
import p1.repository.entity.Sales_data;
import p1.repository.entity.Staff_master;
import p1.repository.entity.Working_data;

@Controller
@RequestMapping("hsystem")
public class ControllerH {

    @Autowired
    private StaffMasterRepository staffMasterRepository;

    @Autowired
    private SalesDataRepository salesDataRepository;

    @Autowired
    private WorkingDataRepository workingDataRepository;

    @Autowired
    private ProductMasterRepository productMasterRepository;

    @RequestMapping("01/{id}")
    public String getById(Model model, @PathVariable Integer id) {
        Optional<Staff_master> data = staffMasterRepository.findById(id);
        if(!data.equals(Optional.empty())) {
            model.addAttribute("staffMasterData", data.get());
            return "hsystem/staffMasterList";
        }else {
            return "error/error01";
        }
    }

    @RequestMapping("02/{id}")
    public String getById2(Model model, @PathVariable Integer id) {
        Optional<Sales_data> data = salesDataRepository.findById(id);
        if(!data.equals(Optional.empty())) {
            model.addAttribute("salesDataData", data.get());
            return "hsystem/salesDataList";
        }else {
            return "error/error01";
        }
    }

    @RequestMapping("03/{id}")
    public String getById3(Model model, @PathVariable Integer id) {
        Optional<Working_data> data = workingDataRepository.findById(id);
        if(!data.equals(Optional.empty())) {
            model.addAttribute("workingDataData", data.get());
            return "hsystem/workingDataList";
        }else {
            return "error/error01";
        }
    }

    @RequestMapping("04/{id}")
    public String getById4(Model model, @PathVariable Integer id) {
        Optional<Product_master> data = productMasterRepository.findById(id);
        if(!data.equals(Optional.empty())) {
            model.addAttribute("productMasterData", data.get());
            return "hsystem/productMasterList";
        }else {
            return "error/error01";
        }
    }

    @RequestMapping("05/{id}")
    public String greaterId(Model model, @PathVariable Integer id) {
        List<Sales_data> list = salesDataRepository.greaterId(id);
        model.addAttribute("salesDataData", list);
        return "hsystem/salesDataList";
    }

    @RequestMapping("06/{id1}/{id2}")
    public String betweenId(Model model, @PathVariable Integer id1, @PathVariable Integer id2) {
        List<Sales_data> list = salesDataRepository.betweenId(id1,id2);
        model.addAttribute("salesDataData", list);
        return "hsystem/salesDataList";
    }

    @RequestMapping("07/{id1}/{id2}")
    @Transactional(readOnly=false)
    public String deleteBetweenId(Model model, @PathVariable Integer id1, @PathVariable Integer id2) {
        int resultInt = salesDataRepository.deleteBetweenId(id1,id2);
        System.out.println(resultInt);
        List<Sales_data> list = salesDataRepository.findAll();
            model.addAttribute("salesDataData", list);
            return "hsystem/salesDataList";
    }
}



package p1.repository;

import java.util.List;
import java.util.Optional;

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

import p1.repository.entity.Table01;

@Repository
public interface R02 extends JpaRepository<Table01, Integer> {

    public Optional<Table01> findById(Integer id);

    public List<Table01> findAllById(List<Integer> idList);  // 複数のidを指定してデータを取得
    // findAllById(List<Integer>) は、Postgresではエラーになってしまうらしい

    public List<Table01> findByIdBetween(Integer id1, Integer id2);   // idがid1~id2の範囲のデータを取得

    public List<Table01> findByFirstName(String firstName);   // firstNameで検索(完全一致)

    public List<Table01> findByFirstNameContains(String str);   // firstNameにstrが含まれるデータを検索(firstName like %str% になる)

    public List<Table01> findByFirstNameNotContains(String str);   // firstNameにstrが含まれないデータを検索(firstName not like %str% になる)

    public List<Table01> findByFirstNameStartsWith(String str);   // firstNameがstrで始まるデータを検索(firstName like str% になる)

    public List<Table01> findByFirstNameEndsWith(String str);   // firstNameがstrで終わるデータを検索(firstName like %str になる)

    public List<Table01> findByIdAndFirstName(Integer id,String firstName);   // idとfirstNameのAND条件で検索

    public List<Table01> findByIdOrFirstName(Integer id,String firstName);   // idとfirstNameのOR条件で検索

    public List<Table01> findByIdLessThan(Integer id);   // idが~未満の条件で検索

    public List<Table01> findByIdGreaterThan(Integer id);   // idが~より大きいの条件で検索

    public List<Table01> findByMailAddressIsNull();   // mailAddressがnullのデータを検索

    public List<Table01> findByMailAddressNotNull();   // mailAddressがnullではないデータを検索

    public List<Table01> findByIdBetweenOrderByIdAsc(Integer id1, Integer id2);   // idがid1~id2の範囲のデータを取得し、id昇順で並べ替え

    public List<Table01> findByIdBetweenOrderByIdDesc(Integer id1, Integer id2);   // idがid1~id2の範囲のデータを取得し、id降順で並べ替え

    public List<Table01> findByIdIn(List<Integer> idList);   // idがidListのいずれかであるデータを検索(in (id1,id2,id3) になる)

    public List<Table01> findByIdNotIn(List<Integer> idList);   // idがidListのいずれでもないデータを検索(not in (id1,id2,id3) になる)

    public List<Table01> findByFirstNameLike(String str);   
    // firstNameにstrが含まれるデータを検索(firstName like str になるのだが、前後に%をつけないといけないので、Contains,StartsWith,EndsWithのほうが簡単
}



package p1.repository;

import java.util.List;
import java.util.Optional;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import p1.repository.entity.Sales_data;

public interface SalesDataRepository extends JpaRepository<Sales_data, Integer> {

    public Optional<Sales_data> findById(Integer id);

    @Query("SELECT s FROM Sales_data s WHERE s.id > :id")
    public List<Sales_data> greaterId(@Param("id")Integer id);

    @Query("SELECT s FROM Sales_data s WHERE s.id BETWEEN :id1 AND :id2")
    public List<Sales_data> betweenId(@Param("id1")Integer id1, @Param("id2")Integer id2);

    @Query("DELETE FROM Sales_data s WHERE s.id BETWEEN :id1 AND :id2")
    @Modifying  // 更新・削除の場合は@Modifyingが必要
    public int deleteBetweenId(@Param("id1")Integer id1, @Param("id2")Integer id2);

}

3
9
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
3
9