Spring BootでシンプルなDB接続操作(CrudRepository)

##Spring BootでDB接続する
これの方法は沢山あると思うのですが、シンプルで速攻使えるのが
1. DataSourceを使う
2. CrudRepositoryを使う
3. JpaRepositoryを使う

かなと思いました。今回は2のCrudRepositoryでシンプルにDB接続を実現してみたいと思います。(JpaRepositoryの記事はたくさん見つかったのですが、CrudRepositoryの方をシンプルに実現してみたい場合にあまり記事がなかったので今回書いてみました)

##設定

まずは、`pom.xml`に以下のdependencyを追加します。

```pom.xml
<dependency>
			<groupId>org.postgresql</groupId>
			<artifactId>postgresql</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
```

データベースについては、今回PostgreSQLを使用しました。

```application.properties
spring.datasource.driver-class-name=org.postgresql.Driver
spring.datasource.url=jdbc:postgresql://localhost:5432/spring
spring.datasouce.username=user
spring.datasouce.password=password
```

##構成

```
root/
　├ src/
　│　└ main/
　│　　　└ java/com/basiauth/basiauth
　│　　　　　└ config/
　│　　　　　　　└ SecurityConfig.java
　│　　　　　└ controller/
　│　　　　　　　└ EmployeeController.java　
　│　　　　　└ entity/
　│　　　　　　　└ Employee.java
　│　　　　　└ repository/
　│　　　　　　　└ EmployeeRepository.java
　│　　　　　└ service/
　│　　　　　　　└ EmployeeService.java
　│　　　　　　　└ EmployeeServiceImpl.java
　│　　　　　└ BasiauthApplication.java　//実行用mainメソッド
　│　└ test/
　└ lib/
```

##データベースの環境構築
予め以下のような形でテーブルを作成しておいて、サンプルデータを挿入しておきます。


```sql
CREATE TABLE EMPLOYEE (
EMPLOYEE_ID SERIAL,
EMPLOYEE_NAME VARCHAR(50),
PASSWORD VARCHAR(255),
SALARY INT,
DEPARTMENT VARCHAR(50),
PRIMARY KEY(EMPLOYEE_ID));
```

```SQL
INSERT INTO EMPLOYEE VALUES (
1,'HOGE HOGE','PASSWORD',30000,'HR');
```

##各コード
###Entity
まず今回取得するデータのEmployee情報用。

```Employee.java
import lombok.Data;
import lombok.Getter;
import lombok.Setter;

import javax.persistence.*;

@Data
@Entity
@Table(name = "employee")
public class Employee {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="employee_id")
    @Getter
    @Setter
    private Long employeeId;

    @Column(name="employee_name")
    @Getter
    @Setter
    private String employeeName;

    @Column(name="password")
    @Getter
    @Setter
    private String password;

    @Column(name="salary")
    @Getter
    @Setter
    private long salary;

    @Column(name="department")
    @Getter
    @Setter
    private String department;
}

```

###Repository

今回オリジナルの`findByxx`などのメソッドは作らないので、シンプルに以下のみ。

```EmployeeRepository.java
import com.basiauth.basiauth.entity.Employee;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface EmployeeRepository extends CrudRepository<Employee, Long> {
}
```

###Service

上のRepositoryを使ったサービスメソッドを作ります。

```EmployeeService.java
import com.basiauth.basiauth.entity.Employee;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import javax.swing.text.html.Option;
import java.util.List;
import java.util.Optional;

public interface EmployeeService {
    public List<Employee> getAllEmployees();
    public Optional<Employee> getEmployeeById(Long id);
    public void createEmployee(Employee employee);
    public void updateEmployeeById(Employee employee, Long id);
    public void deleteEmployeeById(Long id);
}
```

次に上のインターフェスを実現したメソッドを書きます。

```EmployeeServiceImpl.java
import com.basiauth.basiauth.entity.Employee;
import com.basiauth.basiauth.repository.EmployeeRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;

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

@Service
public class EmployeeServiceImpl implements EmployeeService{

    @Autowired
    EmployeeRepository employeeRepository;

    @Override
    public List<Employee> getAllEmployees() {
        Iterable<Employee> employeeIterable = employeeRepository.findAll();
        List<Employee> employeeList = new ArrayList<>();
        employeeIterable.forEach(employeeList::add);

        return employeeList;
    }

    @Override
    public Optional<Employee> getEmployeeById(Long id) {
       Optional<Employee> employee = employeeRepository.findById(id);
       return employee;
    }

    @Override
    public void createEmployee(Employee employee) {
        Employee employee1 = new Employee();
        employee1 = employeeRepository.save(employee);
    }

    @Override
    public void updateEmployeeById(Employee employee, Long id) {
        Optional<Employee> employee1 = employeeRepository.findById(id);
       Employee emp = employee1.get();
       emp =  employeeRepository.save(employee);
       System.out.println(emp);
    }

    @Override
    public void deleteEmployeeById(Long id) {
        employeeRepository.deleteById(id);
    }
}
```

あとは最後にControllerでHTTPメソッドからデータを取得するようにします。

```EmployeeController.java


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

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.basiauth.basiauth.entity.Employee;
import com.basiauth.basiauth.service.EmployeeServiceImpl;

@RestController
@RequestMapping("/api/v1/employees")
public class EmployeeController {

    @Autowired
    private EmployeeServiceImpl employeeService;

    @GetMapping
    public List<Employee> getEmployees() {
        List<Employee> employeeList = employeeService.getAllEmployees();
        return employeeList;
    }

    @GetMapping(path="{employeeId}")
    public Employee getEmployeeById(@PathVariable("employeeId") Long id) {
    	Optional<Employee> employeeOption = employeeService.getEmployeeById(id);
    	Employee emp = employeeOption.get();
    	return emp;
    }

    //register
    @PostMapping()
    public void postEmployee(@RequestBody Employee employee) {
    	employeeService.createEmployee(employee);
    }


    //update
    @PutMapping(path="{employeeId}")
    public void updateEmployee(@RequestBody Employee employee,@PathVariable("employeeId") Long id) {
        Optional<Employee> employee1 = employeeService.getEmployeeById(id);
        Employee emp = employee1.get();
        employeeService.updateEmployeeById(employee,id);
    }

    @DeleteMapping(path="{employeeId}")
    public void deleteEmployee(@PathVariable("employeeId") Long id) {
    	employeeService.deleteEmployeeById(id);
    }
}
```

これで、`localhost:8080/api/v1/employees/`などのエンドポイントにアクセスすれば、データが取得できます。