【JPA】table1とtable2を比較してtable2に存在しないデータを取得、更新する

今回DBにEmployee1とEmployee2というテーブルを用意し、
両方を比較してEmployee2に存在しないidのデータを取得・更新をする

##DB事前準備

Employee1

id | first_name | last_name | height | weight | skill_level
--- | --- | --- | --- | --- | ---
1 | TARO | TANAKA | 170 | 50 | 2
2 | JIRO | YAMADA | 150 | 60 | 3
3 | HANAKO | YAMASHITA | 156 | 44 | 3
4 | ICHIRO | SUZUKI | 180 | 80 | 5
5 | SABURO | TANAKA | 174 | 65 | 1
7 | AI | SUZUKI | 160 | 50 | 4
8 | GORO | AIDA | 177 | 60 | 3


Employee2

id | first_name | last_name | height | weight | skill_level
--- | --- | --- | --- | --- | ---
6 | 智久 | 山下 | 178 | 67 | 6
7 | サダヲ | 阿部 | 160 | 56 | 5
8 | かおる | 杉田 | 166 | 60 | 2
9 | 智也 | 長瀬 | 185 | 70 | 6
10 | 聡 | 妻夫木 | 180 | 70 | 6
11 | 謙 | 渡辺 | 180 | 75 | 6
12 | 洋介 | 窪塚 | 183 | 60 | 6
13 | あい | 加藤 | 166 | 50 | 4


##Entityクラス
● @Entity Entityクラスであることを宣言
● @Table マッピングされるDBのテーブル名を指定
● @id PKのカラムに付与
● @Column マッピングされるテーブルのカラム名を指定

```java:Employee1
@Entity
@Table(name = "employee1")
@Getter
public class Employee1 {

	@Id
	@Column(name = "id")
	private Integer id;
	
	@Column(name = "first_name")
	private String firstName;
	
	@Column(name = "last_name")
	private String lastName;
	
	@Column(name = "height")
	private Integer height;
	
	@Column (name = "weight")
	private Integer weight;
	
	@Column (name = "skill_level")
	private Integer skillLevel;
	
	//Employee2へ変換するメソッド
	public Employee2 toConvert() {
		return new Employee2(
				this.getId(),
				this.getFirstName(),
				this.getLastName(),
				this.getHeight(),
				this.getWeight(),
				this.getSkillLevel()
				) ;
	}
}
```

● @NoArgsConstructor　引数なしコンストラクタ(デフォルトコンストラクタ)を自動的に生成
● @AllArgsConstructor　引数ありコンストラクタ(全メンバ)を自動的に生成

```java:Employee2
@Entity
@Table(name = "employee1")
@Getter
@NoArgsConstructor
@AllArgsConstructor //Employee1のメソッドでEmployee2のインスタンスを生成するため、引数ありコンストラクタが必須
public class Employee1 {
	
	@Id
	@Column(name = "id")
	private Integer id;
	
	@Column(name = "first_name")
	private String firstName;
	
	@Column(name = "last_name")
	private String lastName;
	
	@Column(name = "height")
	private Integer height;
	
	@Column (name = "weight")
	private Integer weight;
	
	@Column (name = "skill_level")
	private Integer skillLevel;
}
```

##Repositoryクラス

● Repositoryクラスはインターフェース
● JpaRepositoryを継承し、第一引数にEntityクラス、第二引数にPKの型を渡す
● @Repository DBと通信するクラスに付与するアノテーション
● @Query 任意のメソッド名でクエリーを定義する事ができる


```Java:Employee1Repository
@Repository
public interface EmployeeRepository extends JpaRepository<Employee, Integer> {
	
	@Query(nativeQuery=true, value = " SELECT e.* FROM employee  e LEFT OUTER JOIN employee1"
	+ "  e1 ON e.id = e1.id WHERE e1.id IS NULL " )
	public List<Employee> notExist();
```

```JAva:Employee2Repository
@Repository
public interface Employee1Repository extends JpaRepository<Employee1, Integer> {

}
```

##実行クラス

● @Autowired　インスタンス変数に付与する

```Java:Main
@SpringBootApplication
public class EmployeeApplication implements CommandLineRunner{
	
	@Autowired
	EmployeeRepository employeeRepository;
	
	@Autowired
	Employee1Repository employee1Repository;
	
	
	public static void main(String[] args) {
		SpringApplication.run(EmployeeApplication.class, args);
	}

	@Override
	public void run(String... args) throws Exception {
		
		List<Employee> list = employeeRepository.notExist();
		System.out.println(list.size());
		List<Employee1> list1 = list.stream().map(Employee::toConvert).collect(toList());
		employee1Repository.saveAll(list1);
	}
}
```