Spring Data JDBC라는 O/R Mapper를 통해 DB조작에 관한 부분을 생성함.
만들부분은 이 부분.
Spring Boot 프로젝트에서 application.properties는 환경설정을 수행하기 위한 파일.
여기서 전편에서 생성한 accountdb를 연결하기 위한 설정을 진행해줘야 함.
src/main/resources
의 application.properties
파일을 열어 수정해줌.
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://mysql 주소./accountdb spring.datasource.username=ID spring.datasource.password=PASSWORD
driver-class-name
은 동일하게 설정해주고
url
은 localhost로 설정해줘도 상관없고, AWS와 같은 클라우딩 컴퓨팅 서비스의 엔드포인트를 설정해줘도 괜찮다.
username
과 password
는 설정한 것으로 입력해준다.
O/R Mapper로는 Spring Data JDBC를 사용하고, RepositoryImpl은 Spring Data JDBC가 자동으로 작성해줌.
따라서 이 프로젝트에서 직접적으로 작성해야하는것은 Domain Object
와 Repository
가 됨.
서비스처리를 실행하기 위해 필요한 자원.
DB로 치자면 Entity와 같은 말이라고 할 수 있음.
즉 DB의 테이블 한줄에 해당하는 클래스.
src/main/java/
에서 entity
패키지를 추가한다음 Account
클래스를 추가함.
Account.java
package com.example.account.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.Id;
/**
* account 테이블용 Entity
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Account {
// 식별 ID
@Id
private Integer key;
// 회원 id
private String id;
// 회원 이름
private String name;
// 회원 이메일 주소
private String mail;
// 회원 비밀번호
private String password;
}
@Data
어노테이션은 클래스에 부여함으로 모든 필드에 대해 getter/setter로 엑세스 할 수 있게 해줌.
@NoArgsConstructor
어노테이션은 클래스에 부여함으로 기본적인 생성자를 자동으로 생성해줌
@AllArgsConstructor
어노테이션은 클래스에 부여함으로 모든 필드에 대한 초기화 값을 인수로 얻을 수 있게 하는 생성자(Constructor)를 생성함.
@Id
어노테이션은 테이블의 Primary Key에 해당하는 필드 id에 대해서 부여됨.
Repository는 인터페이스이며 DB에대한 데이터 조작 정의만 구성됨.
src/main/java
에서 repository
패키지를 추가하고, 패키지 안에 AccountRepository
인터페이스를 추가함.
Repository 인터페이스에 Spring Data가 제공하는 CrudRepository
를 상속하여 RepositoryImpl
이 생성이 됨.
CrudRepository
의 형 인수는 Entity형인Account
및 @Id
어노테이션이 부여된 Integer
를 순서대로 지정함.
AccountRepository.java
package com.example.account.repository;
import com.example.account.entity.Account;
import org.springframework.data.repository.CrudRepository;
/**
* Account 테이블의 RepositoryImpl
*/
public interface AccountRepository extends CrudRepository<Account, Integer> {
}
Spring Data가 제공하는 CurdRepository
를 상속함으로써 자동으로 CRUD를 지원하는 메소드를 사용 가능함.
메소드의 종류는 아래와 같음.
CRUDRepository 메소드 종류
<Account, Integer>
는 저장대상의 객체형과 저장대상의 객체의 기본키형의 지정.
Spring Boot 어플리케이션 시작 클래스인 AccountApplication
필드에 AccountRepository
를 @Autowired
어노테이션을 주입하고 AccountApplication
의 실행상태를 확인함.
src/main/java/AccountApplication.java
에 다음과 같은 내용을 추가해줌
AccountApplication.java
package com.example.account;
import com.example.account.entity.Account;
import com.example.account.repository.AccountRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class AccountApplication {
public static void main(String[] args) {
SpringApplication.run(AccountApplication.class, args).getBean(AccountApplication.class).execute();
}
@Autowired
AccountRepository repository;
/**
* 실행 메소드
*/
private void execute() {
// 등록처리
setup();
}
/**
* 2개의 계정 추가
*/
private void setup() {
// 엔티티 생성
Account account1 = new Account(null, "aaaa", "가나다","aaaa@gmail.com","11111");
// 등록
account1 = repository.save(account1);
// 등록 확인
System.out.println("등록된 데이터: " + account1);
// 엔티티 생성
Account account2 = new Account(null, "bbbb", "James","james@naver.com","22222");
// 등록
account2 = repository.save(account2);
// 등록 확인
System.out.println("등록된 데이터: " + account2);
}
}
@Autowired
에서는 AccountRepository
를 주입함.
main 메소드는 execute 메소드를 호출하며, execute메소드가 호출하는 것은 setup메소드.
setup 메소드 중에서 CrudRepository
를 상속하에 사용가능하게 된 save메소드를 호출함.
save메소드는 엔티티를 저장하는 메소드. 따라서 엔티티가 null이면 안되지만 @Id
어노테이션이 부여된 항목이라면 자동으로 반영하여 INSERT 쿼리문을 SQL에 던져줌.
지정한 엔티티를 데이터베이스에 저장함.
실행 결과
SQL DB에도 정상적으로 쿼리문이 작동되었음을 알 수 있다.
AccountApplicaion
클래스에 아래 메소드를 추가함
private void showList() {
System.out.println("---전체 검색 시작---");
// Repository를 사용하여 모든 내역을 얻는 결과
Iterable<Account> accounts = repository.findAll();
for (Account account : accounts) {
System.out.println(account);
}
}
showList 메소드에서는 CrudRepository
를 상속하에 사용가능하게 된 findAll 메소드를 호출하여, 모든 엔티티의 값을 Iterable 형으로 바꿔서 저장한다.
그것들을 for문으로 모두 출력하는 형식의 메소드라고 할 수 있다.
실행하기위해 AccountApplicaion
의 execute 메소드의 값도 바꿔준다.
/**
* 실행 메소드
*/
private void execute() {
// 등록처리
//setup();
showList();
}
그럼 다음과 같은 값이 출력된다.
AccountApplicaion
클래스에 아래 메소드를 추가함
/**
* 1건 데이터 얻기
*/
private void showOne() {
System.out.println("---1건의 데이터 얻기---");
// Repository를 사용하여 1건의 데이터를 얻고 결과를 얻음
// return값은 Optional
Optional<Account> accountOptional =repository.findById(2);
// 값 존재 확인
if(accountOptional.isPresent()) {
System.out.println(accountOptional.get());
} else {
System.out.println("해당 퀴즈가 없습니다.");
}
System.out.println("---1건 데이터 얻기 완료---");
}
showOne 메소드에서는 CrudRepository
를 상속하에 사용가능하게 된 findById 메소드를 호출하여 메소드에 제시된 값에 대응하는 엔티티를 얻을 수 있음.
여기서는 Primary Key에 대응하는 id의 2를 넘김.
findById 메소드의 리턴값은 Optional(java.util.Optional)
null일지도 모르는 값이 있을 수도 있기 때문에 Optional을 통해 값을 래핑하여 사용함.
Optional의 메소드 isPresent()
를 통해 값이 들어있는지를 확인하여 get 메소드로 래핑한 값을 취득함.
값이 존재하지 않으면 런타임 예외 - NoSuchElementException
을 던짐.
마찬가지로 AccountApplicaion
의 execute메소드 수정
/**
* 실행 메소드
*/
private void execute() {
// 등록처리
//setup();
//showList();
showOne();
}
다음과 같은 값이 출력된다.
AccountApplicaion
클래스에 아래 메소드를 추가
/**
* 업데이트 처리
*/
private void updateAccount() {
System.out.println("--- 업데이트 처리 시작 ---");
// 변경 엔티티 설정
Account account1 = new Account(1, "abab","가가가", "abab@gmail.com", "1212");
// 업데이트 실행
account1 = repository.save(account1);
// 업데이트 확인
System.out.println("업데이트 된 데이터: " + account1);
System.out.println("--- 업데이트 처리 완료 ---");
}
}
updateAccount 메소드는 CrudRepository
를 상속하에 사용가능하게 된 save 메소드를 호출하여 지정한 엔티티를 데이터베이스에 저장함.
save에 대한 설명은 앞서 했으므로 생략.
AccountApplicaion
의 execute 메소드도 수정
/**
* 실행 메소드
*/
private void execute() {
// 등록처리
//setup();
//showList();
//showOne();
updateAccount();
}
실행결과
제대로 실행되었음을 알 수 있음.
AccountApplicaion
클래스에 아래 메소드를 추가
/**
* 삭제
*/
private void deleteAcoount() {
System.out.println("--- 삭제 처리 실행 ---");
repository.deleteById(2);
System.out.println("--- 삭제 처리 완료 ---");
}
}
상속받은 CrudRepository
의 deleteById 메소드 사용
Id 2인 엔티티 삭제하게 됨.
AccountApplicaion
클래스 execute메소드 수정
/**
* 실행 메소드
*/
private void execute() {
// 등록처리
//setup();
//showList();
//showOne();
//updateAccount();
deleteAcoount();
}
실행 결과
정상적으로 실행이 됨.