OmniAICreator/Qiita-1.07M huggingface dataset:
4か月でSAA-C03に合格した話

2024年4月1日から試験料金が値上げされますね。
値上げ話から昨年受験したことを思い出したので感想を書いていこうと思います。

https://aws.amazon.com/jp/certification/policies/before-testing/

# はじめに
2023年9月2日 SAA-C03に合格しました。
資格勉強する以前は、クラウド聞いたことはあるけど何それ美味しいの？？状態でした。

学生時代は趣味でプログラム書いたりハッカソン出たりしてましたが、学生個人でクラウド使うなんてほぼないですよね。。

そんな私でも短期間で資格が取れたので、初学者の参考になれば幸いです。
とはいうものの、ネットを見ればAWS全冠したつよつよの方々がたくさんいらっしゃいますのでお手柔らかにお願いします。。！


# 受験背景

特定の技術領域に関心を持たない私はフルスタックとして幅広い業務に携われる会社に入社しました。フルスタックなのでもちろんインフラも触るわけですが、困ったことにほとんど経験がありませんでした。23年5月に新卒研修でAWSに触れるも何が何やら。

せっかくなので体系的に学ぼうと資格取得を目指しました。

> 技術はすごい好きなんですけど、極めたい分野が未だに見つかっていません。。

## 資格に対する姿勢

私は資格教徒ではありません。資格よりも実力やろ派です。
私にとっての資格は、最終的なゴールに辿り着くための中間ゴールの一つだと考えます。

今回のゴールがクラウドないしAWSの全容を把握することであり、資格取得が目標設定として容易且つ最短であると考えたため受験を決めました。

# 勉強軌跡

上から順に参考にした資料と感想です。

- [AWSの基本・仕組み・重要用語が全部わかる教科書](https://www.amazon.co.jp/AWS%E3%81%AE%E5%9F%BA%E6%9C%AC%E3%83%BB%E4%BB%95%E7%B5%84%E3%81%BF%E3%83%BB%E9%87%8D%E8%A6%81%E7%94%A8%E8%AA%9E%E3%81%8C%E5%85%A8%E9%83%A8%E3%82%8F%E3%81%8B%E3%82%8B%E6%95%99%E7%A7%91%E6%9B%B8-%E8%A6%8B%E3%82%8B%E3%81%A0%E3%81%91%E5%9B%B3%E8%A7%A3-%E5%B7%9D%E7%95%91%E5%85%89%E5%B9%B3/dp/4815607850/)
    - 必要性は感じない
- [【SAA-C03版】AWS 認定ソリューションアーキテクト アソシエイト模擬試験問題集](https://www.udemy.com/course/aws-knan/)
    - 良かった。難易度はかなり高いが何周もすれば必ず力になる。
- [AWS認定ソリューションアーキテクト-アソシエイト問題集](https://www.amazon.co.jp/AWS%E8%AA%8D%E5%AE%9A%E3%82%BD%E3%83%AA%E3%83%A5%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%88-%E3%82%A2%E3%82%BD%E3%82%B7%E3%82%A8%E3%82%A4%E3%83%88%E5%95%8F%E9%A1%8C%E9%9B%86-%E5%B9%B3%E5%B1%B1-%E6%AF%85/dp/486594303X/)
    - SAA-C02の問題集。おすすめしない。当時C03の問題集を探しても無く、変わらないだろうと思い買った。全く参考にならない。
- [Ping-t](https://mondai.ping-t.com/)
    - めちゃめちゃ良かった。無料で問題が多く、解答の質も高い。最初にやるべきだった。


ひとつの情報源に頼るのはあまり好きではないのでいろいろ試しました。振り返ってみればやらなくて良かったと思うものが多いですね。
また、勉強の間に分からないことがあれば適宜ネットやYouTube見てました。AWS Black Belt Online Seminarはとても良かったですね。

> [AWS Black Belt Online Seminar 一覧リストを作成しました](https://dev.classmethod.jp/articles/blackbelt-list/)

# 個人的オススメ

AWSについて全く分からない方はYouTube等で概要を掴むのが先だと思います。
その上でおすすめを紹介します。

## 1. Ping-t

SAA-C03だけ無料で問題集を公開してます。無料とは思えない質の高さです。

本番相当の問題もありますが、ジャブのような問題もあります。
そのジャブのような問題もバカにならないので全てやることをお勧めします。

私は最初にやらなかったことを後悔してます。ていうか受験1週間前まで知りませんでした(泣)

## 2. 【SAA-C03版】AWS 認定ソリューションアーキテクト アソシエイト模擬試験問題集
udemyで販売されている模擬試験問題集

試験のレベルよりも難易度高めな問題を中心に構成されています(人に依る所はもちろんあるが)。また、問題自体も継続的に改善・修正されていたと思います(たしか)。購入後にこの問題集が時代においてかれることはしばらくないんじゃないかな？と思います。

いきなりこの問題集から入ると自分のできなさに絶望するので、最初に取り組むことはオススメしません。ですが必ず力になるのでやりましょう。

ちなみに私は最初の問題集としてこれを選んだため絶望してました。

## 3. 他

正直、上2つを回していれば合格できると思います。調べるとPing-tだけで合格したという人もいます。

問題集を回したうえで知識が乏しいと感じる所は都度調べれば良いと思います。
AWS Black Belt Online Seminarは特定のサービスにおいて体系的に学べるのでオススメです。


# 結果
受験後、あまり手ごたえを感じず帰宅。倒れるように眠りにつき、目を覚ますと結果通知が来てました。結果は2、3日後だと聞いてた記憶が。。？

結果としては776点

合格基準が720点なので、ギリギリ合格でした。


# まとめと今後

感想としてはやって良かったと思います。今どこまで覚えているかは怪しいですが、AWSを触ることに全く抵抗はありません。分からなくても大抵自己解決できます。そうなってくると日々の開発も楽しくなってきますね。

これからもAWSは触っていきますが、資格はしばらく取らないと思います。少なくとも3年は(有効期限)。資格よりも実際に触った方が楽しいですからね！

これからAWSを触る方の参考になれば幸いです！
SpringBootでEntityを使ってMySQLのレコード更新（アップサート）

# この記事はこれの続きです

https://qiita.com/waokitsune/items/4f73350f54b0474c99b1

# Repositoryクラス

変更無しです。

# Serviceクラス

Repositoryクラスの ```save()``` で1レコード分、 ```saveAll()``` で複数件。

```java:UnkoService.java
package com.example.demo;

import java.util.List;

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


@Service
@Transactional
public class UnkoService {

	
	@Autowired
    UnkoRepository unkoRepository;

	
    public List<Unko> findAll() {
        return unkoRepository.findAll();
    }
    
    
    public void upsertOne(Unko unko) {
    	unkoRepository.save(unko);
    }
    
    
    public void upsertAll(List<Unko> list) {
    	unkoRepository.saveAll(list);
    }
    
    
    public void deleteOne(Unko unko) {
    	unkoRepository.delete(unko);
    }
    
    
    public void deleteAll() {
    	unkoRepository.deleteAll();
    }
    
    
}
```

# Controllerクラス

```java:DemoController.java
package com.example.demo;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;


@Controller
public class DemoController {

	
	@Autowired
    UnkoService unko_service;
	
	
	@GetMapping("/")
	public String getIndex(Model model) {
		
		
		//既存レコードはアップデート。
		Unko unko_1_ = new Unko();
		unko_1_.setRecord_id(1);
		unko_1_.setTest_val("レコード1変更後の値");
		unko_service.upsertOne(unko_1_);
		
		
		//存在しなければインサート。
		Unko unko_2_ = new Unko();
		unko_2_.setRecord_id(2);
		unko_2_.setTest_val("レコード2の新規挿入値");
		unko_service.upsertOne(unko_2_);
		
		
		return "/index";
		
		
	}
	
	
}
```

# 実行結果

実行前。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/51bbdaca-c993-0257-92a8-2df62992fc71.png)

実行後。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/a9db20e4-bf89-fb49-cbe6-98159e7cb431.png)

インサート分のrecord_idが『9』なことに注目。

1. record_id = 2のレコードは無いのでインサート。
1. record_idはAUTOINCREMENTでインサート前は『次の値は9』の状態になっていた。
1. 『record_id = 2』ではなく『record_id = 9』でレコードが挿入された。

# この記事の続き

https://qiita.com/waokitsune/items/806b7f87e9a8348fb47a

# バージョン

Microsoft Windows [Version 10.0.19045.4170]
Spring Boot v3.1.10
@inlet/react-pixiから@pixi/reactに移行したときにやったこと

# はじめに

最近、業務にて`@inlet/react-pixi`から`@pixi/react`に移行する作業を行いました。この移行は、`@inlet/react-pixi`が廃止され、`@pixi/react`に変更されたこと、React v18が`@inlet/react-pixi`に未対応だったため行いました。

本記事では、`@pixi/react`への移行作業で行った主な変更点について解説します。

# 変更点1: PixiSpriteの型定義

`@inlet/react-pixi`では、PixiSpriteの型定義はシンプルに`useRef<PixiSprite>(null)`と記述していました。しかし、`@pixi/react`ではPixiRefを使用する必要があるため、以下のように変更しました。

```tsx
// 旧: @inlet/react-pixi
const maskRef = useRef<PixiSprite>(null);

// 新: @pixi/react
import { PixiRef } from '@pixi/react';
import { Sprite } from '@pixi/react';

type ISprite = PixiRef<typeof Sprite>;
const maskRef = useRef<ISprite>(null);
```

`PixiRef`はPixiJSオブジェクトをReact側から参照するための型です。

# 変更点2: PixiComponentのジェネリクス型


`@inlet/react-pixi`では、PixiComponentの第2引数にContainerを指定していました。しかし、`@pixi/react`では型エラーが発生してしまう問題が公式のIssueで報告されております。

```tsx
// 旧: @inlet/react-pixi
const PixiVideo = PixiComponent<PixiVideoProps, Container>('Video', {
  // 省略
}

// 新: @pixi/react
// https://github.com/pixijs/pixi-react/issues/457 でバグ報告のissueが立っている
const PixiVideo = PixiComponent<PixiVideoProps, any>('Video', {
  // 省略
}
```

この変更は、`@pixi/react`の内部実装が変更されたことに伴うものです。

# 変更点3: Stageコンポーネントのoptions

`@inlet/react-pixi`では、`Stage`コンポーネントの`transparent`オプションを使用していましたが、`@pixi/react`ではこのオプションが非推奨となり、代わりに`backgroundAlpha`オプションを使用する必要があります。

```tsx
// 旧: @inlet/react-pixi
<Stage
  options={{
    transparent: true,
  }}
/>

// 新: @pixi/react
<Stage
  options={{
    backgroundAlpha: 0,
  }}
/>
```

`backgroundAlpha`は背景の不透明度を0～1の値で指定します。`transparent: true`と同じ効果を得るには`backgroundAlpha: 0`と設定します。
ChatGPTでいい感じのアクティビティ図を書いてもらう（PlantUML）

## いい感じの図

「ここに棚があったら嬉しいよね」
「そうですね」
「あと、ここにフローチャート図とか欲しいよね」
「えー、そこはあえて余白の詫びさびを感じていただいて……。
だめですか……そうですか…」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663038/0d6e83b4-b3e8-a86e-1006-4269dbe68ed5.png)

アクティビティ図みたいな図をChatGPTに手っ取り早く作成してもらおうという試みです。

## アクティビティ図ってなんだっけ？
アクティビティ図は、UML（統一モデリング言語）の一種です。

https://www.omg.org/spec/UML

いわゆるフローチャート図とよく似ていますが、フローチャートとはちょっと違います。
見た目も少し違います（始点と終点の形だとか）。

ことばの上ではフローチャート図を所望されたとはいえ、厳密にフローチャート図が欲しいというわけでもない場合、さっと炒めたアクティビティ図でも用足りることがあります。

## PlantUMLってなんだっけ
PlantUMLは、UMLをテキストで作図してくれる便利なコンポーネントです。

https://plantuml.com/

ユースケース図やクラス図なんかがあって、アクティビティ図はβ番ですね。

## ChatGPTにサクッと書いてもらう

ChatGPTはPlantUMLを理解しているので、簡単な分岐処理程度ならささっと書いてくれます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663038/b2ca723d-b174-abc6-ea52-35f5cf98c746.png)

PlantUMLは、VS Codeで拡張機能が提供されています。

### Visual Studio Code 

https://code.visualstudio.com/

### 拡張機能（PlantUML）の追加

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/663038/70006358-56e9-fccb-65d5-56fafa44fd9e.png)

新しいファイルを作って、拡張子.pumlで保存します。

ChatGPTに書いてもらったコードを貼り付けて、コマンドパレットを開いてプレビューすると図が書けます。

### メリット○：気軽に図が書ける

ChatGPTはテキストの出力は上手なので、ちゃちゃっと書いてくれます。

### デメリット×：微調整がきかない

融通は利かないので、「こうしてほしい」という詳細な要望がありそうな場合は向きません。

身内向け簡単資料におすすめです。

なお、複雑すぎるとかなり取り回しが悪くなってきて、自分で描いた方が楽だな、となってくると思います。
自力で描くなら、doraw.ioをお勧めしておきます。

https://app.diagrams.net/


## 所感

GPT-4は画像認識を獲得しましたが、それもまだ「クッションに寝転んだ猫の写真」程度で作図はできません。

一方で、ChatGPTとテキスト表現は非常に相性が良いです。

ほか、ChatGPT＋PlantUMLでは、たとえば、マインドマップをつくっていらっしゃる方がいました。

https://note.com/currypurin/n/nccaca4ce85b0

マインドマップでしたらルールも複雑ではないので、かなりそのまま使えそうな印象を受けます。

AIの発展はすさまじいもので、いずれはこの画像での入力＆出力という点も克服していきそうですが（あるいは
Copilot for Microsoft 365などではすでに近いことができるのかもしれませんが）。

例えば、ノベルゲームだと、ティラノスタジオ/ティラノスクリプトなんてツールがあるわけですが、高機能なエディタよりも、いっそUIをとっぱらってコードをテキストで記述させるようなスクリプトのほうが単なるコードなので、ChatGPTには頼りやすくなる……のかもしれない。
Dockerfileの記述について理解

## 基本を整理
Dockerfileとは、dockerイメージを作成するためのテキストファイル。つまり「Dockerイメージの設計図」
Dockerfileの書き方としては、「FROM」,「RUN」,「CMD」などを記述し、作成します。

## 作成したものから読み解いていく

Webアプリのために（chatGPT）が作成したdockerファイルを見ていく。

```dockerfile:dockerfile
# ベースイメージを指定
FROM maven:3.8.3-openjdk-17-slim AS build

# 作業ディレクトリを指定
WORKDIR /app

# Maven Wrapperのセットアップ
COPY .mvn .mvn

# Mavenプロジェクトをビルド
COPY pom.xml .
RUN mvn -B dependency:go-offline

# アプリケーションのビルド
COPY src src
RUN mvn -B package -DskipTests

# 本番用の軽量なJREベースイメージを使用
FROM openjdk:17-jdk-slim

# アプリケーションのJARファイルをコピー
COPY --from=build /app/target/*.jar /app/app.jar

# アプリケーションの実行
CMD ["java", "-jar", "/app/app.jar"]
```

ひとつずつ見ていく
##
```dockerfile:FROM
# ベースイメージを指定
FROM maven:3.8.3-openjdk-17-slim AS build
```
Dockerfileの中で一番最初に記述されるべき命令
Dockerイメージのベースとなるイメージを指定

##
```dockerfile:WORKDIR
# 作業ディレクトリを指定
WORKDIR /app
```
コマンドを実行する作業ディレクトリを指定
後続の命令が実行される作業ディレクトリを指定。ここでは、/appディレクトリが作業ディレクトリとして使用

##
```dockerfile:COPY
# Maven Wrapperのセットアップ
COPY .mvn .mvn
```
ホスト（ローカル）のファイルやディレクトリをDockerイメージにコピー。
具体的な使い方としては、ソースコードや設定ファイルはローカルで作成して、COPYを使ってDockerイメージにコピーして使用する。
つまり、ここではホストの「.mvn」をdockerイメージ内の「/app/.mv」にコピーしている。

##
```dockerfile:RUN①
# Mavenプロジェクトをビルド
COPY pom.xml .
RUN mvn -B dependency:go-offline
```
Dockerイメージ内で、シェルコマンド実行をする
ここでは、pomファイルのコピーをして、依存関係の解決をする。アプリビルドの準備的な立ち位置。必須ではないが、ビルドプロセスを高速化させるため、実行することが一般的。

##
```dockerfile:RUN②
# アプリケーションのビルド
COPY src src
RUN mvn -B package -DskipTests
```
ソースコードをDockerイメージにコピーし、アプリをビルド
後続で使用するjarファイルがtarget配下に生成される

##
```dockerfile:FROM
# 本番用の軽量なJREベースイメージを使用
FROM openjdk:17-jdk-slim
```
またFROMがある（詳しくはおまけに記載）
新しいベースイメージを指定
ここでは、Javaアプリケーションを実行するために使用する軽量なJREイメージを指定

##
```dockerfile:COPY
# アプリケーションのJARファイルをコピー
COPY --from=build /app/target/*.jar /app/app.jar
```
ビルドステージ（buildステージ）から生成されたJavaアプリケーションのJARファイルをコピーする。
「--from=build」と記述しないと、直近でFROM指定したイメージから取得してきてしまう（ない）

##
```dockerfile:CMD
# アプリケーションの実行
CMD ["java", "-jar", "/app/app.jar"]
```
dockerコンテナが実行されるときに、実行されるデフォルトのコマンドを指定
ここでは　「java -jar /app/app.jar」を実行するように記載している

## 参考
https://qiita.com/gon0821/items/f9e3bcbb6cb01d4ef7fa


## おまけ_ステージについてChatGPTに聞いてみた
```text:ChatGPT
ステージ（stages）とは、Dockerfile内で複数の環境を定義し、それぞれの環境で異なる作業を行う方法です。マルチステージビルドは、1つのDockerfile内で複数の段階（ステージ）を持つことができ、各段階で異なる作業が行われます。

典型的なマルチステージビルドの流れは次のようになります：

最初のステージ（buildステージ）: このステージでは、ビルド用の環境が設定されます。通常、ビルドツールやコンパイラが含まれるイメージが使用されます。このステージでは、プロジェクトの依存関係を解決し、アプリケーションのビルドが行われます。

2番目以降のステージ（実行ステージなど）: これらのステージでは、ビルドされたアプリケーションが実行されるための環境が設定されます。通常、実行に必要な最小限のコンポーネントのみが含まれるイメージが使用されます。このステージでは、ビルドステージからビルドされた成果物がコピーされ、アプリケーションが実行されます。

マルチステージビルドの利点は、Dockerイメージのサイズを最小限に抑えることができることです。ビルドツールやコンパイラなどの開発用のツールは、実行時に必要ないため、最終的なイメージに含める必要がありません。このように、マルチステージビルドを使用することで、最終的なDockerイメージのサイズが小さくなり、セキュリティとパフォーマンスが向上します。
```
つまり、ビルドと実行の環境を分けて最終的なイメージは必要最低限にするといいよね
Pythonで「Pythonの正規表現で設定できるフラグの一覧」の動作を確認してみた

# 概要

Pythonで「Pythonの正規表現で設定できるフラグの一覧」の動作を確認してみました。
以下のページを参考にしました。

https://www.javadrive.jp/python/regex/index17.html

# 実装

以下のファイルを作成しました。
```sample.py
import re
pattern = re.compile(r'\w{4}')
print(bool(pattern.search('ABCD')))
print(bool(pattern.search('花鳥風月')))
pattern = re.compile(r'\w{4}', re.ASCII)
print(bool(pattern.search('ABCD')))
print(bool(pattern.search('花鳥風月')))

import re
pattern = re.compile(r'flower')
print(bool(pattern.search('flower')))
print(bool(pattern.search('Flower')))
print(bool(pattern.search('FLOWER')))
pattern = re.compile(r'flower', re.IGNORECASE)
print(bool(pattern.search('flower')))
print(bool(pattern.search('Flower')))
print(bool(pattern.search('FLOWER')))

import re
msg = """Today we're studying JavaScript.
Tomorrow will study the TypeScript."""
pattern = re.compile(r'\w{4}Script\.$')
result = pattern.findall(msg)
print(result)
pattern = re.compile(r'\w{4}Script\.$', re.MULTILINE)
result = pattern.findall(msg)
print(result)

import re
msg = """彼の住所は東京都中央区
日本橋です。"""
pattern = re.compile(r'<span>.*</span>')
print(bool(pattern.search(msg)))
pattern = re.compile(r'<span>.*</span>', re.DOTALL)
print(bool(pattern.search(msg)))
```

以下のコマンドを実行しました。
```
$ python3 sample.py 
True
True
True
False
True
False
False
True
True
True
['TypeScript.']
['JavaScript.', 'TypeScript.']
False
False
```

# まとめ

何かの役に立てばと。
常に週報を忘れてたけど、忘れなくなった件

# いつも週報忘れちゃう
早速ですが、私は週報とか日報と月報の類を忘れがちです。
Slackの標準のリマインダーを利用してもなんとなく放置しがちで、結局忘れてしまいます。

そんな私が、ある工夫をして、SlackWorkflow でリマインダーを作ったところ、ほぼ忘れなくなったのでその紹介です。

# どんなリマインダーか
ざっくりこんな感じ
時間になると何をするかリマインドしてくれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3716338/c483c74c-d304-0563-770a-8d0555256215.png)

そして…
忘れなくなった一番の工夫は、ボタンにあります。

[完了ボタン]を押下すると、ほめてくれるのです！！！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3716338/d45ce88c-5b25-2a1a-253a-532f5af140b2.png)

「偉いネ！」と言われたいがために、週報を忘れなくなりました！~~たまに書き漏れあって差し戻されているけど~~

# さっそく作る
1\.Slackを開き、左側のバーから「その他→自動化」を押下する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3716338/5e32111a-a862-58b5-5ef5-9abb8be63abe.png)
2\.テンプレートを押下する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3716338/e8a103fd-9109-8533-c634-7ced4def94c7.png)
3\.テンプレートギャラリーから「日時を設定してメッセージを送信する」を押下する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3716338/126197fd-1283-0002-bdaa-363490a8e999.png)
4\.右下の「テンプレートを使用する」を押下する。
5\.リマインドしたい日時等を設定する。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3716338/8ad1a825-f8dc-9a8a-e7be-c472553e78a3.png" width="50%">
6\.次にメッセージを設定する。
このとき、「ボタンを含める」にチェックをいれる。
ボタンの名称を設定する。（今回は「完了したよ」）
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3716338/58e863b8-421a-095e-2f2b-ee412506725b.png" width="50%">
7\. 「ステップを追加→メッセージ→スレッドでメッセージに返信する」を押下する。
週報書き終わったあとに、言ってほしい言葉を書く。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3716338/5afe6d53-d5a1-ade3-3d87-322fc0b33483.png" width="50%">
8\. 最後に「ワークフローの詳細」を選択し、お好きなアイコン、名前、説明を追加する。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3716338/a4ebe56d-a490-0589-3a90-a55825686c85.png" width="50%">




# 参考
* https://slack.com/intl/ja-jp/help/articles/16583775096083-Slack-%E3%83%AF%E3%83%BC%E3%82%AF%E3%83%95%E3%83%AD%E3%83%BC%E3%81%A8%E3%81%AF
レコードの存在チェック

```vb
Public Sub CheckRecordExistence()
    Dim db As DAO.Database
    Dim rs As DAO.Recordset
    Dim sql As String
    
    ' SQLクエリを準備します。ここではEmployeeIDが1のレコードを検索しています。
    sql = "SELECT * FROM Employees WHERE EmployeeID = 1"
    
    ' 現在のデータベースを開きます。
    Set db = CurrentDb()
    
    ' SQLクエリを実行し、結果をRecordsetオブジェクトに格納します。
    Set rs = db.OpenRecordset(sql, dbOpenDynaset)
    
    ' レコードが存在するかどうかをチェックします。
    If rs.EOF And rs.BOF Then
        MsgBox "対象のレコードは存在しません。", vbInformation, "レコードなし"
    Else
        MsgBox "対象のレコードが見つかりました。", vbInformation, "レコードあり"
    End If
    
    ' オブジェクトを閉じてリソースを解放します。
    rs.Close
    Set rs = Nothing
    Set db = Nothing
End Sub
EBSのアタッチに関して

## 初めに
AWSストレージサービスである「EBS」について記載していきます。
まずは、アタッチに関してです。

## EBSとは？
EBSとは、EC2インスタンスにアタッチして利用できるブロックストレージサービスです。

※用語解説
・ストレージ
→「記憶装置」の事。USBメモリはHDDが当てはまる。

・ブロックストレージ
→記憶媒体を「ブロック」という単位で管理するストレージ。

.EBSボリューム
→EBSの記憶領域

・アタッチ
→EC2に割り当てる事。

## アタッチパターン
①複数のインスタンスから1つのEBSボリューム
![スクリーンショット 2024-03-27 17.23.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3744656/3997657b-abcb-130b-4a0e-3dd49eb6eef1.png)
※片方がアタッチしていない場合は、もう1つのインスタンスでアタッチ可能
一部のボリュームタイプでマルチアタッチが可能な機能もある。

②1つのインスタンスから他AZのEBSボリューム
![スクリーンショット 2024-03-27 17.25.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3744656/a0bc04a1-757a-22cc-5e48-587f9b38a4c4.png)
・同一AZに存在する複数のEBSボリュームにはアタッチ可能
・1つのインスタンスから他AZのEBSボリュームにはアタッチできない

## 最後に
AWS検定では、ストレージ問題が多く出題されております。
他にもS3やEFSなどストレージサービスがありますので、学習の参考になれば幸いです。
【SQLServer】tempDBの圧縮

# 背景
大量データをSQLServerManagementStudioで開いたところ、
tempDBが自動拡張を続け、ドライブ容量がひっ迫した

自動拡張してしまった領域を解放するための手順の備忘録

# 手順

1. SSMSを開き、［データベース］-［システム データベース］-［tempDB］を右クリック<br><br>

2. コンテキストメニューの［タスク］-［圧縮］-［File］を選択

    ![手順①.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3756373/fea1f6bc-4cd7-3602-3fae-0398067144f8.png)
    
    :::note info
    圧縮の方法は以下の2通りから選択できる
    - <b>データベースの圧縮：</b>    データベースを圧縮する。作成時よりも小さいサイズに圧縮することはできない
    - <b>Fileの圧縮：</b>    データベースファイル圧縮する。初期サイズよりも小さいサイズに圧縮できる
    
    参考：[データベースの圧縮 | Microsoft Learn](https://learn.microsoft.com/ja-jp/previous-versions/sql/sql-server-2008-r2/ms189080(v=sql.105)?redirectedfrom=MSDN)

3. 各項目を設定して「OK」ボタンをクリック

    ![手順②.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3756373/e824c30b-983b-e68c-8669-ce7fddba1688.png)
    
    :::note info
    圧縮アクションでは、以下のうちから圧縮方法を選択する
    - <b>未使用領域を解放する</b>：すべての未使用領域を解放する
    - <b>未使用領域の解放前にページを再構成する</b>：ファイルサイズを指定して圧縮する
    - <b>データを同じファイル グループの他のファイルに移行してファイルを空にする</b>：すべてのデータを別ファイルに移行する|
ZED SDK の設定パラメータ

# 想定する読者
stereolabsのzed2, zed mini, zed x などのステレオカメラの利用者
いまどきのステレオカメラは何ができるのかを知りたい人

# 前提
ZED SDK 4.0
Ubuntu 20.04
ZED2i
Python 版のAPI

## 設定パラメータの保存と読み取り

以下のようにして、設定ファイルをymlファイルで保存 save, 読み込み loadすることができます 

```.py:
import pyzed.sl as sl

zed = sl.Camera()
init_params = sl.InitParameters()
init_params.save("zed-sdk-init-params.yml")
runtime_parameters = sl.RuntimeParameters()
runtime_parameters.save("zed-sdk-runtime-params.yml")
```

### 保存されたyml ファイルの例
注意：推奨条件ではありません。

```.yml:zed-sdk-init-params.yml
%YAML:1.0
InitParameters:
   camera_resolution: "6"
   camera_fps: "0"
   sdk_verbose_log_file: ""
   svo_real_time_mode: "0"
   coordinate_units: "2"
   coordinate_system: "2"
   depth_mode: "3"
   depth_minimum_distance: "-1.000000"
   depth_maximum_distance: "-1.000000"
   camera_image_flip: "2"
   enable_right_side_measure: "0"
   camera_disable_self_calib: "0"
   sdk_verbose: "0"
   sdk_gpu_id: "-1"
   depth_stabilization: "1"
   input_type_input: "6"
   input_type_conf: "0"
   optional_settings_path: ""
   sensors_required: "0"
   enable_image_enhancement: "1"
   optional_opencv_calibration_file: ""
   open_timeout_sec: "5.000000"
```

```:zed-sdk-runtime-params.yml
%YAML:1.0
RuntimeParameters:
   enable_depth: "1"
   enable_fill_mode: "0"
   confidence_threshold: "100"
   texture_confidence_threshold: "100"
   measure3D_reference_frame: "1"
   remove_saturated_areas: "1"
```

### 残念なこと
- Enumで設定される選択肢が、ことごとく数値に置き換わってしまっています。
- そのため、それぞれの数値がどういう意味の設定になっているのかを知るのが面倒です。

## Pythonスクリプトでの値を知るための手順
```.py:
runtime_parameters = sl.RuntimeParameters()
print(type(runtime_parameters.enable_fill_mode))
```
で
でデータ型を知る。
`help(そのデータ型)`　をするとEnumでのそのデータ型についての記述を得ることができる。
今更JavaでGUI

# JavaでWindow制御ってどうやってんの？
ふと疑問に思ったので調べてみました。
仮説としてはWindow制御はOS領域になるので、どこかでnativeメソッドなりを呼び出して管理を任せているはず。
今回はWindowsを対象にしてます。

## とりあえず何はともあれ表示
![1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48666/a71b008a-0aed-6997-91b5-f114e20dfb1c.png)
はい。
白背景のWindowを作成して表示することができました。
簡単なんですが、このキャプチャを取る時に予想外の挙動が。
Windows標準のSnipping Toolを使ったところ、表示されていたWindowがどこかへ行ってしまいます。
これもOS側での挙動でしょうか。

## APIコールを探して
Win32APIあたりを呼んでそうなnativeメソッドを探してソースコードを読み進めていきます。
![2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48666/fea8d3f0-58cd-0e13-fcbe-1ff6a5f61234.png)
![3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48666/6601185f-268d-0498-4db0-17e6a6542566.png)
![4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48666/2d0202b3-76c3-4480-c26e-8d61be9e7532.png)
![5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/48666/e1c5617f-24e4-81ef-597b-33d78a175c95.png)
これかな？

https://learn-microsoft-com.translate.goog/en-us/windows/win32/api/winuser/nf-winuser-sendmessage?redirectedfrom=MSDN&_x_tr_sl=en&_x_tr_tl=ja&_x_tr_hl=ja&_x_tr_pto=sc

確認してみたところ以下の順番で参照している模様。
awt.h -> stdhdrs.h -> windows.h -> winuser.h

## わかったこと

WindowクラスからComponentクラスを経て、ComponentPeerインターフェイスの各環境向け実装を呼び出し、そこから各環境用のJDK実装を呼び出していることがわかりました。
概ね予想通りの流れでしたが、思っていたより各環境へ合わせるため抽象化は多かったです。

## 今後の展望

根っこの方の内容は大まかに掴めたはずなので、今度は枝葉の部分として描画処理をやっていきます。
Sparkにおけるデータキャッシュ

2024/4/12に翔泳社より**Apache Spark徹底入門**を出版します！

<a href="https://www.amazon.co.jp/dp/4798182281/"><img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/87910d7c-8a63-c198-8e82-216ea7a8ee07.jpeg" width=300></a>

書籍の[サンプルノートブック](https://github.com/databricks/LearningSparkV2/blob/master/notebooks/LearningSparkv2.dbc)をウォークスルーしていきます。`Python/Chapter07/7-5 Caching Data`となります。

翻訳ノートブックのリポジトリはこちら。

https://github.com/taka-yayoi/SparkSample/tree/main

ノートブックはこちら

https://github.com/taka-yayoi/SparkSample/blob/main/Chapter07/7-5%20Caching%20Data.py

# _cache()_ の使用

いくつかのカラムを持つ大規模データセットを作成します。

```py
from pyspark.sql.functions import col

df = spark.range(1 * 10000000).toDF("id").withColumn("square", col("id") * col("id"))
df.cache().count()
```
```
10000000
```

どこにデータが格納されるのかを確認するためにSpark UIのstorageタブをチェックします。
![Screenshot 2024-03-27 at 17.02.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/3a88185e-568e-7f29-266f-8b9e47825159.png)

`Disk Memory Deserialized 1x Replicated`となっています。

```py
df.unpersist() # unpersistしない場合、下のdf2はdfと同じクエリープランであるためdf2はキャッシュされません
```
![Screenshot 2024-03-27 at 17.04.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/c6cf3345-0ce4-12dc-d8d5-1c686b1f97e5.png)

# _persist(StorageLevel.Level)_ の使用

```py
from pyspark import StorageLevel

df2 = spark.range(1 * 10000000).toDF("id").withColumn("square", col("id") * col("id"))
df2.persist(StorageLevel.DISK_ONLY).count()
```
```py
df2.count()
```
```
10000000
```

データがどこに格納されているのかを確認するためにSpark UIのStorageタブをチェックします。

![Screenshot 2024-03-27 at 17.07.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/3da5a4d7-d16e-e7dc-7b14-d69a6b0b2830.png)

`Disk Deserialized 1x Replicated`となっています。

# SQLでのキャッシュ

```py
df.createOrReplaceTempView("dfTable")
spark.sql("CACHE TABLE dfTable")
```

どこにデータが格納されるのかを確認するためにSpark UIのstorageタブをチェックします。
![Screenshot 2024-03-27 at 17.11.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/d6b58cba-0b38-34be-3e7c-a9be4a3c7f57.png)

`In-memory table dfTable`がキャッシュされています。

```py
spark.sql("SELECT count(*) FROM dfTable").show()
```
```
+--------+
|count(1)|
+--------+
|10000000|
+--------+
```

### はじめてのDatabricks

[はじめてのDatabricks](https://qiita.com/taka_yayoi/items/8dc72d083edb879a5e5d)

### Databricks無料トライアル

[Databricks無料トライアル](https://databricks.com/jp/try-databricks)
Parallels Desktop上のQGISの文字デカくね？　を解決したい

# はじめに
私事ですが、最近Macを使い始めました。
今までWindows人間だったので、使い勝手の違いに翻弄される今日この頃です。

とはいえ、MacにParallelsを導入すればWindows環境も利用できるので、ポジティブに考えるとMac環境もWindows環境も好き勝手試せる素敵な状況だなと思っていたりします。

「Parallelsあれば、Macでなんでもできるなーすごいなー」
なんて思いつつ、Parallels上のWindowsにQGISをインストールしたところ

![スクリーンショット 2024-03-06 173233.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1147458/39bf6f24-9c54-3f8d-1ac5-c2a86cbfcce2.png)

<font>$\huge{「...なんか文字デカくね？？？」}$</font>

という問題に出くわしました。

**お子様からご年配の方まで、誰でも読みやすい素敵な仕様**なのですが
お仕事で使うには色々と支障が出そうなので、
ここでは解決方法について記載していきます。

# 予想される検索ワード
以下、この記事を求めているであろう方が入力しそうな
（というか実際に私が必死で検索した）検索ワードです。

QGIS, Parallels, フォント, 大きい

# 実行環境
- macOS Sonoma 14.2
- Parallels Desktop
- QGIS 3.28

# 手順
## QGIS側のフォント設定を変更する
1. parallels上でQGISを起動する
2. 設定→オプションを選択して、オプションウィンドウを開く
3. 「一般情報」の「アプリケーション」という項目の中にフォント設定があるのでフォントサイズを「9」に変更する（手持ちのWindows環境だとデフォルト9だった）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1147458/c9ff8fdf-f222-6fb6-fe72-77cdb8c08b27.png)

4.　QGISを立ち上げ直す
5.　それでも、文字サイズが大きい場合はParallelsの設定を見直す（後述）

## Parallelsの設定を見直す
QGIS側のフォントを変更したにも関わらず、文字サイズが大きい場合は、
Parallels側の設定を見直します。

1. parallelsの右上にある歯車マークをクリックする
2. 「ハードウェア」タブの「グラフィック」を選択する
3. 真ん中の「サイズ調整される」を選択する（変更するとwindowsはサインアウトされるので注意）
![スクリーンショット 2024-03-01 14.09.18（2）.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1147458/e413e502-372d-8d2f-0125-fb2b87f94cc2.png)

4. QGISを立ち上げ直す
　
無事にフォントサイズが小さくなっている（はず）
![スクリーンショット 2024-03-06 183109.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1147458/2f9de950-78e2-ab4b-4876-d08eff0cd2cd.png)

## おわりに
今回Parallelsを触ってみて、便利なものがあるなぁ、と思いつつ
生粋のWindowsユーザーから見ると「ん？なんか違うぞ？」みたいなクセはちょこちょこありそうだと感じました。

また使っていく中で、純粋なWindows環境との違いがあれば
対応方法を探りつつやっていこうと思います。
DatadogでSLOのCountByがでないとき

# はじめに

DataDogのterafformを書くのに躓いたのでまとめます

# 問題

以下のようなSLOを書きました

```tf:metric.tf
resource "datadog_logs_metric" "sample" {
  name = "cloudfront.requests.duration.get_sample"
  compute {
    aggregation_type = "count"
  }

```
しかしなぜかCountByが使えませんでした

# 解決方法

```tf:metric.tf
resource "datadog_logs_metric" "sample" {
  name = "cloudfront.requests.duration.get_sample"
  compute {
    aggregation_type = "distribution"
  }

```

このようにすることでCountByが利用できました

# おわりに

2回目だったのでメモ程度に残しておきます
SharePoint Onlineで承認申請ワークフローを作る



入力にはリスト、承認申請ワークフローは PowerAutomate を使って構築したいと思います。

ワークフローは申請者が承認経路を選択して流れるようにしたいと思います。
ワークフロー自体は共通にしたい、また１つのリストで未承認などを管理できたらいいと思います。


ということで、それぞれの申請内容を記入するリスト（複数）とワークフローを管理するリストの２つに分けたいと思います。こうすることで新しい申請内容を作る隊時には、申請内容を記入するリストを既存のリストから複製すれば済むようしたいと思います。



|リスト名|内容|
|:----------------|:--------------------|
|承認申請ListView|ワークフローを設定している共通のリスト|
|経路マスター|申請経路を選択することで、承認者を設定するリスト。これを使ってアクセス権を管理します。|
|019重変更届|住所変更用の申請内容を保存するリスト|
|020出生届|出生届用の申請内容を保存するリスト|


|リスト名|フローの機能|
|:----------------|:--------------------|
|承認申請ListView|アイテムが作成されたらワークフロー起動します|
|経路マスター|なし|
|019重変更届|アイテムが作成されたら、承認経路等を付与して承認申請ListViewを作成します。|
|020出生届|アイテムが作成されたら、承認経路等を付与して承認申請ListViewを作成します。|

以上の構成にすることで、承認申請のコンテンツが増えてもそのコンテンツを格納するリストと承認申請ListViewを作成するフローを複製してつくればいいだけになります。

また、フローは複製が簡単にできるようにリスト名などはすべて変数にしておきます。

# それぞれの承認申請リストの構造（共通部分）


|項目       |属性        |
|:----------|:-----------|
|タイトル	|1 行テキスト|	
|RouteSelection（承認経路）	|参照	|
|申請者(代理申請の場合のみ入力)	|ユーザーまたはグループ	|
|申請日	|日付と時刻	|
|承認者     |ユーザーまたはグループ	|
|status	|選択肢|


# それぞれの承認申請が作成された時のフロー

### アイテムが作成されたらフローを起動させます


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/0092a0c8-198c-7a64-e3ef-f3637670a948.png)

### 承認経路マスターのリストを参照します。
承認申請のリストで承認経路を選択させているので、そのIdを使って１件のアイテムを取得します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/c80baa24-2e12-53f7-660a-17b2bd32b478.png)

### 変数の初期化

+ リストは初め英語で作成して、ラベルだけを日本語に修正しているので、リストに関する変数は２つ用意します。
+ EditPermisson 変数には、承認後に修正権限を付与したいグループをセットします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/1fea4e27-3926-55e8-4b1a-156cd7dd6487.png)

### 申請者は入力がなければ作成者をセットするように分岐を設定しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/faeef051-09ea-c209-65a3-26221e8e46d9.png)

### この承認申請のリスト自身の修正

この部分を変数とすることで、固有の値に修正しなくてもいいようにしています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/4f7431a0-d847-5eb2-80ce-c835d7b0309f.png)

### 承認申請のワークフローがある共通のリストにアイテムを追加します。

この部分を変数とすることで、固有の値に修正しなくてもいいようにしています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/6322c5af-a281-0947-ab5d-647b535ea2c2.png)


 ### このリストの編集、参照権を変えたいので一旦すべての共有権限を停止します。

 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/5112b176-c917-8a06-6b57-d89620f611cc.png)


### 申請者に編集権限を付与します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/3e5b60fe-2661-e40e-c802-f31127df08a1.png)


### 承認者に編集権限を付与します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/075af5bf-52ca-59a2-0684-f864b50f2db3.png)

### 申請後に管理部門のグループにも編集権限を付与したいので、グループを取得します。

グループ名から検索します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/3b382a51-8d22-fcef-59ec-e74cb65fb73d.png)

### Idを抽出します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/45497629-718f-c4b9-2ddf-881d39de811b.png)

### グループに編集権限を付与します。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/9e1c280a-95c2-cc47-2e67-26f029add1a7.png)
【小ネタ】SharePointリストからDataverseへのデータ移行を簡単におこなう

## プレビュー機能 - SharePoint リストで作成とは

あっという間にSharePoint リストからDataverseに移行が完了するPower Appsの新機能です。
Dataverseを使ってみたいけど、SPOに既存のデータがあり、乗り換えが大変...と足踏みしていた皆様に朗報です。

本記事は、Dataverseテーブルの作成方法の『SharePoint リストで作成(Create with SharePoint list)』の使用手順および仕様について記載しております。

### 機能概要
・ SPOリストの既存データからDataverseテーブルを少ない操作で作成・コピー
・ SPOリストのデータ種類（型）をサポート　※一部のデータ種類・型は非サポート
・ スキーマ名などの項目も自動生成

### 活用のメリット
・ 開発コスト：既存のデータの再利用により、ゼロからの開発に比べてコストを削減
・ 一元管理：Dataverseへのデータ移行により、データを一箇所に集約可能

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2975138/54455fd8-b724-f34e-b078-0408e8dd04b0.png)

## 操作手順
1. Power Appsポータルより[テーブル]-[Create with SharePoint list]をクリックします

1. SharePointサイトを選択します。サイトURLを入力するか、もしくは、[最近利用したサイト]からSharePointのサイトを選択します

1. 対象のリストを選択します

1. [次へ]をクリックします

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2975138/f632842e-73b0-f359-5293-fab107f3487c.png)

1. SPOリストのデータの種類やレコードを引き継いだ状態でDataverseテーブルのプレビューを確認します※一部のデータ種類・型は非サポート


1. 必要に応じて、テーブルのプロパティや列のプロパティを変更します

1. テーブル・列のプロパティの編集が完了したら、[作成]をクリックし、Dataverseテーブルを作成します

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2975138/48b92384-f134-0527-cbb7-826fa7930e56.png)


## データの種類（型）のサポート状況
『SharePoint リストで作成(Create with SharePoint list)』を利用して、Dataverseテーブルを作成した場合、サポートされるデータの種類（型）は下記のとおりです。

仕様上、サポートされていない型があるため、Dataverseテーブルを作成後にPower Automate等を利用してデータのインポートを検討する必要がある

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2975138/90459a36-7066-d15c-4245-5b6a9f00d021.png)


## まとめ
あっという間にSharePoint リストからDataverseに移行が完了するPower Appsの新機能です。
Dataverseを使ってみたいけど、SPOに既存のデータがあり、乗り換えが大変...と足踏みしていた皆様、ぜひお使いくださいー！
webアプリを公開　HelloWorld!

## やったこと
最小限の作業で完成させた。
手順ゼロについては以下参照
https://qiita.com/isekaigk/items/ab2809a4305d46adbe68

1. コントローラー作成
2. Dockerfile作成
3. Github登録
4. RenderとGithub連携

## 1.コントローラー作成
コントローラー（受け渡し部品）の作成をした
リンク（リクエスト）と動作をマッピングする。今回の動作は「Hello Wlorld」を出力する

```java:HelloApplicationController.java
package com.example.hello;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloApplicationController {
    @RequestMapping("/")  // ルートへこのメソッドをマップする
    public String test() {
        return "Hello World";
    }
}
```
## 2. Dockerfile作成
ここで、何も考えずに作成したら、後のデプロイ時にエラーが発生した。今回はchatgptにお願いして作成してもらった。
Dockerfileに記載する内容は、「ビルド、実行」である。その「ビルド、実行」に必要なmavenの指定、コマンドについて記載する必要がある。
これ以上の詳しい内容は別途調べようと思う。

```dockerfile:作成

# ベースイメージを指定
FROM maven:3.8.3-openjdk-17-slim AS build

# 作業ディレクトリを指定
WORKDIR /app

# Maven Wrapperのセットアップ
COPY .mvn .mvn

# Mavenプロジェクトをビルド
COPY pom.xml .
RUN mvn -B dependency:go-offline

# アプリケーションのビルド
COPY src src
RUN mvn -B package -DskipTests

# 本番用の軽量なJREベースイメージを使用
FROM openjdk:17-jdk-slim

# アプリケーションのJARファイルをコピー
COPY --from=build /app/target/*.jar /app/app.jar

# アプリケーションの実行
CMD ["java", "-jar", "/app/app.jar"]
```

## 3. Github登録
詳しくは省略するが
VS CodeとGitHubアカウントを連携してpushした。
firstPushは少し特殊なので注意が必要。

## 4. RenderとGithub連携
RenderとGithubを連携することでデプロイが可能になる。
Renderをあまり調べずにやってみたが、指定ブランチにプッシュ（マージ）すると勝手にビルドしてくれる。

ここでエラーに見舞われた。
```java:エラー

no main manifest attribute, in .mvn/wrapper/maven-wrapper.jar

```
このとき、私は二つのミスをしていた。解決方法と合わせて書く。
1. pomファイル記述不足
エントリポイントを保持するクラス（＝メインクラス）を指定する必要があった
参考：https://stackoverflow.com/questions/9689793/cant-execute-jar-file-no-main-manifest-attribute

2. Dockerfileの記述ミス 
エラーにもあるように実行のjarファイルが「.mvn/wrapper/maven-wrapper.jar」となっているが、これはビルドした成果物ではないので、これを実行しても意味がない（詳しくは番外編にて）


修正後無事にデプロイ成功！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2781864/8db3a1aa-1520-d2a9-2850-ce8fcda64ff1.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2781864/6b35d0b3-4406-6c77-4ba3-abafe4591489.png)



## 番外編＿エラー
### デプロイ時にエラー

```java:エラー

no main manifest attribute, in .mvn/wrapper/maven-wrapper.jar

```
Dockerfileでアプリケーション実行の時に指定したjarファイルが間違っていたことが原因。
エラー時に指定していたのは、「Maven Wrapper の JAR ファイル」つまり、mavenを使うための情報が入ったもの（mavenアプリ自体のjar）。
もちろん、デプロイ時に必要なのはJavaアプリケーションの成果物。
/* こんなことで・・・。となるけど気がつけないもんなんです。。理解を深めていくと問題を解決できる。このマインドを大切に挫けないようにしたい。
/*
動的メンバーシップの判定基準を付与されているライセンスで判定できるか試してみた

Microsoft 365関連で調査、検証した内容をブログにしています。


かなり久しぶりの投稿となります。
今回はEntra IDの動的メンバーシップについて検証した内容となります。


# ■はじめに
動的メンバーシップについて簡単に説明すると、グループへのメンバー登録/削除を自動で行ってくれる機能となります。

動きとしては、グループ作成時にメンバーへ追加するユーザーの属性をクエリとして条件定義し、その条件にマッチするユーザーのみを登録してくれるようなものとなります。

例としては、「営業部」というグループを作成し動的にメンバーの出し入れをしたい場合、[部署]の属性が[営業部]というユーザーのみを登録するというクエリを定義するようなイメージです。

# ■検証した理由
Microsoft 365ではライセンスの種類が多様化しているため、テナント内で複数のライセンスを契約しているパターンは少なくないと思っています。
そのような状況を想定し、特定ライセンスが付与されているユーザーのみに絞った形で動的メンバーシップが組めるのかを確認してみました。

上手く活用できれば、特定のサービスプランが含まれているライセンスでないと使えない機能（例えば条件付きアクセスなど）の利用グループとして使えるのではないかと考えています。

# ■条件定義可能な範囲について
条件として定義可能な範囲は以下に記載されているものとなります。

[Microsoft Entra ID のグループの動的メンバーシップ ルール](https://learn.microsoft.com/ja-jp/entra/identity/users/groups-dynamic-membership)


# ■「assignedPlans」条件
リンクの内容を見ていただくと分かるのですが、残念ながら定義できる条件にライセンスはありませんでした…

しかしながら、ライセンスに含まれているサービスプランを条件として定義する「assignedPlans」というものがありました。
使い方によっては今回やりたかったことと近しい制御ができるのではないかと思い検証してみました。


# ■検証内容
テナント内に「Microsoft 365 Apps for business」、「Microsoft 365 Business Premium」という2つのライセンスを適用し、Business Premiumが付与されているユーザーのみが属する動的グループが作成できるかを検証します。
以下は設定手順です。
 　
①グループの作成画面を開きます。
※動的グループの作成はEntra ID管理センターからのみ可能となります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618363/e870df3f-1e6e-e538-04fe-51b5823529a6.png)
　

 
②メンバーシップの種類に[動的ユーザー]を指定し、[動的クエリの追加]をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618363/8d1fb2cc-d9bc-55da-2f7d-c4e220b696ad.png)
　
  
③動的メンバーシップの設定画面が開くので、[編集]をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618363/22b25a6e-1bae-5e6d-6077-ffd321deab47.png)


 　
④以下のクエリを入力し、[OK]をクリックします。
今回はApps for businessには無く、Business Premiumには有るサービスを指定したいのでEntraID P1を条件として定義します。

```
user.assignedPlans -any (assignedPlan.servicePlanId -eq "対象サービス名のフレンドリ名" -and assignedPlan.capabilityStatus -eq "Enabled")
※EntraID P1の場合「41781fb2-bc02-4b7c-bd55-b576c07bb09d」 
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618363/de9e6f6b-eb0f-8951-ef3c-8d825eeee8ce.png)


各サービスのフレンドリ名については以下のリンクから確認できます。
[ライセンスのための製品名とサービス プラン 識別子](https://learn.microsoft.com/ja-jp/entra/identity/users/licensing-service-plan-reference)

 　
⑤グループを保存します。Entra ID側の設定としてはこれで完了です。

　
  
⑥ユーザーを作成して動的メンバーシップが動くかを確認します。
赤枠にユーザーのみBusiness Premiumのライセンスを付与しているので、このユーザー達がメンバーに登録されれば上手く動作したことになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618363/86fd580c-5cba-e56a-689e-8168bdca1ee2.png)


 　
⑦対象ユーザーのみがメンバーに登録されていることが確認できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618363/19cab63e-aadf-9a33-0e46-1e8447b4f910.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3618363/db654175-da15-fba4-1063-ae97265d02e1.png)


# ■最後に
「assignedPlans」条件を代用することでやりたいことがどうにか実現できました。
こちらを活用することで例に挙げた条件付きアクセスの割り当てグループやIntuneのポリシーの割り当てにも利用できると思うので、結構使う場面は多そうです。

ただ、あくまでライセンスではなくサービスプランの差異を確認したうえで対象とするサービスを指定している形ですので、事前にライセンスの差異確認はしっかりと行った方がいいと思います。

本記事の内容が何かの参考になれば嬉しいです。

今後もMicrosoft 365関連で調査、検証した内容はブログに残していこうと思います。
【学習メモ：Flutter入門編】StatelessWidgetの使い方

これから「Flutter」を勉強していこうと思っている人向けには「メモ」程度で参照してみてください。

■ 「main.dart」以外のファイル作成方法
名前については基本的に以下のネーミングルールが良いらしい。

* すべてが小文字の英字
* 区切り目は「_（アンダーバー）」とする

また、1行目に必ず必要な定義はお決まりなので記載を忘れないこと。

`import 'package:flutter/material.dart';`

■ StatelessWidget（ステートレスウィジェット）
オリジナルのWidgetを作りたい時に利用する。
ベースとなるクラスの定義は以下のコードを記載する事で、自動的にコードを準備してくれるみたい。

① `stless` と入力
② 「Flutter Stateless Widget」の選択肢を選択

以下のコードが自動的に挿入される。

```
class MyWidget extends StatelessWidget {
  const MyWidget({super.key});

  @override
  Widget build(BuildContext context) {
    return const Placeholder();
  }
}
```

「StatelessWidget」を作成することにより、作成したWidgetを他の方にあげたり、共有する事も可能。

■ 「main.dart」等の他のファイルから読み込む場合
下記のように「import」文を追加する必要がある。

`import 'package:★★★★★/★★★★★.dart';`

:::note info
ファイル内で直接作成したクラス名を記載する事で、VSCode側で自動的に宣言を補完してくれるみたい。
:::

■ オリジナル「Widget」への値渡し
定義の方法を以下のように修正する。

```diff
class MyCoounter extends StatelessWidget {
+ // 受け渡し変数
+ final int number;
- const MyCoounter({super.key});
+ const MyCoounter({super.key, required this.number});
```

「$」を付与してあげてないと、たんなる **「numberという文字列」** として認識されます。

```diff
final text = Text(
-  '1',
+  '$number',
);
```

もちろん、呼び出し側の方も修正が必要なので以下のように修正します。
「number: 1」の部分は、固定数ではなく「変数」を受け渡す形でも問題ありません。

```diff
- final con = MyCoounter();
+ final con = MyCoounter(number: 1);
```

上記のように修正する事で呼び出し側の方から、オリジナル「Widget」に対して可変の値を受け渡す「入口」を用意してあげる事ができるので、汎用性が高くなります。

# 最後に
Flutter（Dart言語）に関する最低限の情報を「学習メモ」としてまとめてみました。
内容に誤りがありそうであれば、遠慮なくご指摘いただけますと幸いです。

【学習の参考にした動画】
素敵な解説動画の作成ありがとうございます。
本記事の内容より。動画を見た方が解りやすいと思います。

https://www.youtube.com/watch?v=IgH1EOlB11Q&list=PLY1cxwSQf6nz6zo2Y_UJlDjGOpASAO4hd&index=6
【学習メモ：Flutter入門編】 Containerの使い方

これから「Flutter」を勉強していこうと思っている人向けには「メモ」程度で参照してみてください。

■ Container（コンテナ）
コンテナができる事としては、代表的な主として以下の内容が存在する。

* color
* width & height
* child
* alignment
* padding & margin

■ color
コンテナの色を決める事が可能。

<details><summary>サンプルコード</summary>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3755252/a2d95635-fc02-b209-b5fc-6f81ebbae690.png)

```rb
final con = Container(   
  color: Colors.red,
);
```
</details>

■ width & height
コンテナのサイズを調整する事が可能。
* width：横幅
* height：縦幅

<details><summary>サンプルコード</summary>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3755252/b7bd728b-d509-f355-e629-f7faed833d7e.png)

```rb
final con = Container(   
  color: Colors.red,
  width: 150,
  height: 200
);
```
</details>

■ child
コンテナ（親）に対して、コンテナ（子）を追加したり、他の「Widget」を追加する事が可能。

<details><summary>サンプルコード</summary>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3755252/a37bdcd2-0258-8c6a-b3f8-e283f9388837.png)

```rb
final con = Container(   
  color: Colors.red,
  width: 150,
  height: 200
);

final con2 = Container(
  color: Colors.lime,
  width: 300,
  height: 400,
  child: con,
);
```
</details>

【表示例】
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3755252/f24dd8bc-b1aa-6026-5776-2926d956a9aa.png)

:::note alert
コンテナの入れ子については、参考にした動画の説明では特に「alignment」の指定が無くても、上記画像のような表示になっていたのですが、私の動作環境では **「alignment: Alignment.center」** の指定を加えないと、しっかりと入れ子表示になりませんでした。
この現象についてもし理由が解れば教えていただけると嬉しいです。
:::

【「alignment」の指定なし】
ソース上の「con2（親）」のサイズに、「con（子）」の色が引っ張られてしまい、何故か想定通りの「入れ子表示」にならなかった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3755252/c3720f54-e4f3-dad3-7d56-dc8378f75d96.png)

■ alignment
コンテナの中の子供の位置を調整する事が可能。

* Alignment.center：中央
* Alignment.centerLeft：中央左
* Alignment.centerRight：中央右
* Alignment.topCenter：上中央
* Alignment.topLeft：上左隅
* Alignment.topRight：上右隅
* Alignment.bottomCenter：下中央
* Alignment.bottomLeft：下左隅
* Alignment.bottomRight：下右隅

■ padding & margin
両方とも余白を設定する事が可能。
細かい説明は動画解説を参照した方が解りやすいと思います。

* padding：要素の内側の余白
* margin：要素の外側の余白

【EdgeInsets.all()】
全方向のサイズを設定可能

【EdgeInsets.fromLTRB()】
「left, top, right, bottom」の順番にサイズを設定可能

# 最後に
Flutter（Dart言語）に関する最低限の情報を「学習メモ」としてまとめてみました。
内容に誤りがありそうであれば、遠慮なくご指摘いただけますと幸いです。

【学習の参考にした動画】
素敵な解説動画の作成ありがとうございます。
本記事の内容より。動画を見た方が解りやすいと思います。

https://www.youtube.com/watch?v=8Ze2F-kQpUQ&list=PLY1cxwSQf6nz6zo2Y_UJlDjGOpASAO4hd&index=5
Pythonで簡易的な脆弱性ツールを書いてみた話

# はじめに
Chatgptやネットで調べた情報をもとに作成しました！！！
使用環境はVScodeです！！
## 実際のコード
```py
import subprocess
import re

def check_connected_devices():
    # LAN上のデバイスを取得するコマンド
    cmd = "arp -a"
    try:
        # コマンドを実行して結果を取得
        output = subprocess.check_output(cmd, shell=True)
        # 出力をデコードして文字列に変換
        output_str = output.decode('utf-8')
        # 改行で分割してデバイス情報を取得
        devices = output_str.split('\n')
        # 最初と最後の行は不要なので除外
        devices = devices[1:-1]
        # 各デバイス情報を表示
        for device in devices:
            print(device)
        # 脆弱性診断を実行
        perform_vulnerability_scan(devices)
    except subprocess.CalledProcessError as e:
        print("Error executing command:", e)

def perform_vulnerability_scan(devices):
    for device in devices:
        # デバイスからIPアドレスを抽出
        ip_address = re.findall(r'\d+\.\d+\.\d+\.\d+', device)
        if ip_address:
            # 各デバイスのIPアドレスに対して脆弱性スキャンを実行
            scan_result = run_scan_tool(ip_address[0])
            print("IP Address:", ip_address[0])
            print("Scan Result:", scan_result)
            print()

def run_scan_tool(ip_address):
    # 実際の脆弱性スキャンツールのコマンドを実行する部分
    # ここではダミーの結果を返す
    return "Vulnerability scan result for " + ip_address

if __name__ == "__main__":
    check_connected_devices()

```
このコードでは、**perform_vulnerability_scan**関数が追加されています。この関数は、LAN上のデバイスからIPアドレスを抽出し、それぞれに対して脆弱性スキャンを実行します。
**run_scan_tool**関数は、実際の脆弱性スキャンツールを実行する部分で、ここではダミーの結果を返すようにしています。
# まとめ
まだまだ簡易的ではありますが、これからこのコードを元にいろんなカスタムをしていきたいですね！
見ずらい部分などあるかと思いますが、何卒ご容赦ください！
【学習メモ：Flutter入門編】画像の表示

これから「Flutter」を勉強していこうと思っている人向けには「メモ」程度で参照してみてください。

■ 画像の置き場所
お勧めとして「assets（アセッツ）」フォルダの配下に「images（イメージズ）フォルダを配置して画像を格納

【補足】
asset（アセット）：「資産・価値あるも・役に立つもの」等の意味が存在

■ 「pubspec.yaml」ファイルの編集
「dart」言語では「pubspec.yaml」ファイルに大事な定義を記載しておく

:::note info
アプリ開発では頻繁に利用される設定ファイル
:::

ファイルに「flutter:」という箇所が存在しているので、下記のように「assets/images」配下に設置した画像ファイルの名前を定義しておきます。

```
flutter:
  uses-material-design: true
  assets:
     - assets/images/★★★★★.png
```

■ 「Image」のWidgetについて
下記の4種類が存在している。
* Image.asset()
* Image.network()
* Image.memory()
* Image.file()

詳しい補足は下記の記事がお勧めです。（ありがとうございます！）

https://qiita.com/ling350181/items/916ab3174c3e0dfadb00

■ 「Image.asset()」の使い方
「assets」に配置されている「pubspec.yaml」ファイルに定義した画像を表示する場合に利用。
```
Image.asset(
    'images/★★★★★.png'
)
```

■ 「Image.network()」の使い方
インターネットを通じて遠くの画像を表示する場合に利用。
```
Image.network(
    'https://★★★★★'
)
```

■ 「Image.memory()」の使い方
直接画像ファイルの受け渡しする際に利用。

■ 「Image.file()」の使い方
ローカルファイル形式で画像を表示する際に利用。
※ 現時点で詳しく説明ができないです・・ごめんなさい。

# 最後に
Flutter（Dart言語）に関する最低限の情報を「学習メモ」としてまとめてみました。
内容に誤りがありそうであれば、遠慮なくご指摘いただけますと幸いです。

【学習の参考にした動画】
素敵な解説動画の作成ありがとうございます。
本記事の内容より。動画を見た方が解りやすいと思います。

https://www.youtube.com/watch?v=ZYpnosbnd6w&list=PLY1cxwSQf6nz6zo2Y_UJlDjGOpASAO4hd&index=4
【学習メモ：Flutter入門編】レイアウトの基礎 （Column/Row）

これから「Flutter」を勉強していこうと思っている人向けには「メモ」程度で参照してみてください。

■ const or final
「Flutter」ではできる限り「const」を使った方がよい。

【理由】
* アプリを軽くする（無駄な処理を自動で減らしてくれる）

:::note warn
新しい「Widget」には「Const」に対応しておらず、仕方がなく「final」を利用する場面が存在する。
:::

■ Column（カラム）
Widgetどうしを縦に配置する。

■ Row（ロウ）
Widgetどうしを横に配置する。

■ 配置調整は各「Widget」単位で子供（children）の設定を変更
「mainAxisAlignment」は縦方向の調整で合計「6種類」
* start（スタート）：上寄せ
* center（センター）：中央寄せ
* end（エンド）；下寄せ
* spaceEvenly（スペースイーブンリー）：均等配置
* spaceBetween（スペースビトウィーン）：均等配置（両端のスペースが存在しない）
* spaceAround（スペースアラウンド）：均等配置（両端のスペースが少しだけ存在）

「crossAxisAlignment」は横方向の調整で合計「4種類」
* start（スタート）：右寄せ
* center（センター）：中央寄せ
* end（エンド）；左寄せ
* stretch（ストレッチ）：伸縮（右から左まで引き延ばす）

■ 「Column」と「Row」のサイズ調整
「mainAxisSize」を「min」に設定することで、余分なスペースを削りコンパクトに設定する事が可能

■ 「Widget」の組み合わせ
「Column」に「Row」を代入したり、「Row」に「Column」を代入することでレイアウトを構築していく

# 最後に
Flutter（Dart言語）に関する最低限の情報を「学習メモ」としてまとめてみました。
内容に誤りがありそうであれば、遠慮なくご指摘いただけますと幸いです。

【学習の参考にした動画】
素敵な解説動画の作成ありがとうございます。
本記事の内容より。動画を見た方が解りやすいと思います。

https://www.youtube.com/watch?v=XLC7QmNW8A4&list=PLY1cxwSQf6nz6zo2Y_UJlDjGOpASAO4hd&index=3
【学習メモ：Flutter入門編】 Widgetの基礎 

これから「Flutter」を勉強していこうと思っている人向けには「メモ」程度で参照してみてください。

■ これからFlutterのコードを書いていく為に必要な定義
`import 'package:flutter/material.dart';`

■ プログラミングのスタート関数は「main」
記載するファイルは「main.dart」となる。
```
void main() {
    // ここにコードを書いていく
}
```

■ 「Flutter」の構成について
基本的にほとんどが「Widget（ウィジェット）」で構成されている。
以下はすべて「Widget（ウィジェット）」である。 ※すべて記載していません。
* Text()
* Center()
* Scaffold()
* MaterialApp()

■ Scaffold（スキャフォールド）
日本語で「はしご」という意味。
一つの画面を作成したい時に利用する。（アプリ画面構成が「はしご」っぽい見た目になっている為）

■ MaterialApp（マテリアルアップ）
「Flutter」ではアプリそのものが「Widget」となるので、
* 「アプリを作成 ＝ Widgetを作成」と同義である

■ 「runApp()」関数
アプリを実行する。
作成した「MaterialApp」のWidgetを代入することで、アプリが実行される。

# テストで作成したコード例
```
import 'package:flutter/material.dart';

void main() {
  const a = MaterialApp(
    home: Scaffold(
      body: Center(
        child: Text('Widgetの基礎'),
      ),
    )
  );
  runApp(a);
}
```

# 最後に
Flutter（Dart言語）に関する最低限の情報を「学習メモ」としてまとめてみました。
内容に誤りがありそうであれば、遠慮なくご指摘いただけますと幸いです。

【学習の参考にした動画】
素敵な解説動画の作成ありがとうございます。
本記事の内容より。動画を見た方が解りやすいと思います。

https://www.youtube.com/watch?v=aEu17XiWSZ0&list=PLY1cxwSQf6nz6zo2Y_UJlDjGOpASAO4hd&index=2
SpringBootでEntityを使ってMySQLのレコード削除（1件、全件）

# この記事はこれの続きです

https://qiita.com/waokitsune/items/de1ae587d335cb7a6464

# Repositoryクラス

変更無しです。

# Serviceクラス

Repositoryクラスの ```delete()``` で1レコード分、 ```deleteAll()``` で全件。

```java:UnkoService
package com.example.demo;

import java.util.List;

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


@Service
@Transactional
public class UnkoService {

	
	@Autowired
    UnkoRepository unkoRepository;

	
    public List<Unko> findAll() {
        return unkoRepository.findAll();
    }
    
    
    public void insertOne(Unko unko) {
    	unkoRepository.save(unko);
    }
    
    
    public void insertAll(List<Unko> list) {
    	unkoRepository.saveAll(list);
    }
    
    
    public void deleteOne(Unko unko) {
    	unkoRepository.delete(unko);
    }
    
    
    public void deleteAll() {
    	unkoRepository.deleteAll();
    }
    
}
```

# Controllerクラス（1件削除）

```java:DemoController
package com.example.demo;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;


@Controller
public class DemoController {

	
	@Autowired
    UnkoService unko_service;
	
	
	@GetMapping("/")
	public String getIndex(Model model) {
		

		Unko unko_ = new Unko();
		//主キー以外のフィールドは値セット必要無し。
		unko_.setRecord_id(6);
		unko_service.deleteOne(unko_);
		
		
		return "/index";
		
		
	}
	
	
}
```

# 実行結果（1件分）

実行前。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/b25248c3-8eb0-4930-1552-6a38168bdfbd.png)

実行後。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/706116/b2c7c3cb-07a3-9bff-631a-f2acfce60282.png)

# テーブルに存在しない主キーがEntityにセットされていた場合

例外にはならないです。
下記のようなSQLを流したのと同じ。


```sql:
DELETE FROM neko.unko WHERE record_id = 6
```

# Controllerクラス（全削除）

```java:DemoController
package com.example.demo;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;


@Controller
public class DemoController {

	
	@Autowired
    UnkoService unko_service;
	
	
	@GetMapping("/")
	public String getIndex(Model model) {
		
		
		unko_service.deleteAll();
		
		
		return "/index";
		
		
	}
	
	
}
```

全レコード削除するだけなので実行結果は割愛。

# この記事の続き

https://qiita.com/waokitsune/items/098fbfa874175faad474

# バージョン

Microsoft Windows [Version 10.0.19045.4170]
Spring Boot v3.1.10