[스프링 프레임워크 첫걸음] ( 4 / 9 )

박북velog·2023년 4월 3일
0

제 4장. 데이터 베이스 작업


4.1 데이터 베이스 생성

4.1.1 데이터 베이스란 ?

데이터 베이스 ( Data Base ) : 데이터를 보관, 특정한 규칙을 적용하여 데이터를 정리해서 보관한다.

4.1.2 관계형 데이터 베이스

관계형 데이터 베이스 ( Relational DataBase, RDB ) 는 데이터를 표( table ) 형식으로 표현하고, 여러 표에서 항목의 값 사이에 관계( Relationship )를 맺고 있는 데이터베이스. 관계형 데이터베이스는 가장 일반적으로 사용되는 데이터 베이스이다.

  1. 사원 번호사원 이름부서 번호
    1001홍길동101
    1002이순신102
    1003김철수101
    1004최영희104
  2. 부서 번호부서 이름
    101총리부
    102경리부
    103인사부
    104개발부

부서 번호를 사용해서 테이블 간의 관계를 맺음

4.2 테이블 생성

4.2.1 테이블 이란 ?

테이블 : 실제로 규칙을 가진 데이터가 저장되는 상자
데이터를 이차원 표 형식으로 정리하여 저장한다.

4.2.2 레코드와 칼럼

  • 테이블의 가로 행 ( row )을 레코드 ( record ) 라고 한다.
    하나의 레코드 == 하나의 데이터 { 1001, 1002, ... )
  • 테이블의 세로 열 ( column )을 칼럼이라고 한다. 하나의 칼럼 == 데이터의 각 요소 ( 사원 번호, 부서 번호, ... )

테이블의 제약 조건

제약 조건개요
NOT NULLNULL 입력을 허용하지 않습니다. ( 필수 입력 )
UNIQUE중복값 입력을 허용하지 않습니다. ( 고유한 값 )
CHECK지정한 조건을 만족하지 않는 값의 입력을 허용하지 않습니다.
PRIMARY KEY테이블 안에서 레코드를 식별하는 기본 키를 설정합니다. 기본키는 NOT NULL 과 UNIQUE 가 함께 적용됩니다.
FOREIGN KEY관련된 테이블을 연결하는 설정입니다. 외부 키라고도 불립니다.
DEFAULT칼럼의 초기값을 설정합니다.

4.3 데이터 입력

4.3.1 SQL 이란 ?

SQL ( Structured Query Language )이란 데이터베이스를 조작하기 위한 언어이다. 각 다른 데이터베이스에서도 거의 같은 방법으로 조작이 가능하다.

CRUD

CRUD 란 영속적으로 데이터를 취급하는 4개의 기본적인 기능인

  • 생성( Create ) - INSERT , 데이터를 등록
  • 읽기 ( Read ) - SELECT , 데이터를 참조
  • 갱신 ( Update ) - UPDATE , 데이터를 갱신
  • 삭제 ( Delete ) - DELETE , 데이터를 삭제

의 줄임말이다.

CRUD구문
생성( Create )INSERT INTO 테이블명 (칼럼명) VALUES( 값 );
읽기 ( Read )SELECT 칼럼명 FROM 테이블명;
갱신 ( Update )UPDATE 테이블명 SET 칼럼명 = 값 WHERE 갱신할레코드특정하는_조건; WHERE로 조건을 지정하지 않는 경우 모든 레코드가 대상이 된다.
삭제 ( Delete )DELETE FROM 테이블명 WHERE 삭제할레코드를특정하는_조건; WHERE로 조건을 지정하지 않는 경우 모든 레코드가 대상이 된다.

4.4 엔티티와 리포지토리 알아보기

4.4.1 엔티티란 ?

엔티티 ( Entity ) 란 '데이터를 담아두는 객체'이다.
데이터베이스 테이블의 한 행( Record )에 대응하는 객체
엔티티의 필드는 테이블의 칼럼값에 대응한다.

Member 엔티티의 예)

/**
* Member 테이블: 엔티티
*/
public class Member {
	// id 칼럼 대응
    private Integer id;
    // name 칼럼 대응
    private String name;
    
    public Integer getId() {
    	return id;
    }
    public void setId(Integer id) {
    	this.id = id;
    }
    public String getName() {
    	return name;
    }
    public void setName(String name) {
    	this.name = name;
    }
}

엔티티의 세가지 팁

  • 클래스명은 대응하는 데이터베이스의 테이블명으로 하는 경우가 많다.
  • 데이터베이스 값을 등록 / 갱신하는 경우에는 엔티티에 값을 넣어서 넘겨준다.
  • 데이터베이스에서 값을 가져오는 경우에는 값을 엔티티에 넣어서 가져온다.

4.4.2 리포지토리 란 ?

리포지토리 ( Repository )란 데이터 베이스를 조작하는 클래스이다.
리포지토리를 생성하는 경우에는 반드시 인터페이스를 정의하고 구현해야 한다.

이유는 리포지토리 인터페이스의 필드에 리포지토리 구현 클래스를 DI하여 특정 구현에 의존하는 것을 피할 수 있기 때문.

4.5 스프링 데이터 JDBC 사용하기

4.5.1 O/R 매퍼란 ?

O/R 매퍼 ( Object-relational Mapper )는 애플리케이션에서 사용하는 Object, '객체' 와 Relational, '관계형 데이터베이스'의 데이터를 매핑하는 것이다.

미리 설정된 객체와 관계형 데이터베이스 간의 대응 관계 정보를 가지고 인터페이스의 데이터에 대응하는 테이블에 내보내거나 데이터베이스에서 값을 읽어 들여 인터페이스에 대입하는 작업을 자동으로 실행한다.

4.5.2 스프링 데이터 JDBC 란 ?

스프링 데이터 JDBC 는 O/R 매퍼이다. 스프링 데이터가 제공하는 CRUDRepository를 상혹해서 자동으로 CRUD를 지원하는 메서드를 사용할 수 있다.

1. application properties 설정하기

항목설명
spring.datasource.driver-class-nameJDBC 드라이버의 클래스명을 지정한다.
spring.datasource.url데이터베이스의 '접속 URL' 을 설정한다.
spring.datasource.username데이터베이스에 접속하는 '유저명'을 설정한다.
spring.datasource.password데이터베이스에 젒ㄱ하는 '패스워드'를 설정한다.

2. 엔티티 생성하기

패키지를 우선적으로 생성하고, 클래스를 생성하여 보기 편하게 정리하는 습관을 가질 것.

package com.example.demo.entity;


import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
* Member 테이블 엔티티
*/

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Member {
	// Member 번호
    private Integer id;
    // Member 이름
    private String name;
}
  • Lombok 어노테이션을 사용
    세 어노테이션 모두 클래스에 부여하는 어노테이션

  • @Data
    전 필드에 대해 getter/setter 로 액세스할 수 있다. hashCode(), equals(), toString() 도 자동 생성된다.

  • @NoArgsConstructor
    기본 생성자가 자동 생성된다.

  • @AllArgsConstructor
    전 필드에 대해 초기화 값을 인수로 가지는 생성자가 자동 생성된다.

생성 후 테이블의 기본키( Primary Key )에 해당하는 id 값에 @Id 어노테이션을 부여해줄 수 있다.

@Id
private Integer id;

3. 리포지토리 생성하기

패키지를 만들고, 패키지 내부에 Class 가 아닌 Interface 로 생성한다. 그리고 뒤에 extends 를 추가한다.

package com.example.demo.repository;

import org.springframework.data.repository.CrudRepository;

import com.example.demo.entity.Member;

/**
* Member 테이블: 리포지토리
*/
public interface MemberCrudRepository extends CrudRepository<Member, Integer> {

}

이것으로 MemberCrudRepository 인터페이스 안에서 메서드를 작성하지 않아도 사용할 수 있다. 메서드에서 사용되는 반환값이나 인수의 엔티티나 ID는 <Member, Integer>로 지정한 타입이 된다.

CrudRepository의 CRUD 메서드

반환형메서드개요
longcount()취득한 엔티티의 수를 돌려준다.
voiddelete (Member entity)지정한 엔티티를 삭제한다.
voiddeleteAll()리포지토리에서 관리하는 모든 엔티티를 삭제한다.
voiddeleteAll (Iterable entities)지정한 복수의 엔티티를 삭제한다.
voiddeleteById (Integer id)지정한 ID에 해당하는 엔티티를 삭제한다.
booleanexistsById (Integer id)지정한 ID에 해당하는 엔티티의 존재 여부를 확인한다.
IterablefindAll()모든 엔티티를 반환한다.
iterablefindAllById (Integer id)지정한 복수의 ID에 해당하는 엔티티를 반환한다.
OptionalfindById (Integer id)지정한 ID에 해당하는 엔티티를 반환한다.
Membersave (Member entity)지정한 엔티티를 저장한다.
IterablesaveAll (Iterable entities)지정한 모든 엔티티를 저장한다.

중요한 점은 save 메서드는 @Id 어노테이션이 붙은 필드의 값이 null인 경우에는 INSERT가 실행되고, 그 외에는 UPDATE가 실행된다.

4. 클래스 생성하기

package com.example.SpringDataJDBCSample;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import com.example.demo.entity.Member;
import com.example.demo.repository.MemberCrudRepository;

/**
* 스프링 부트 가동 클래스
*/
@SpringBootApplication
public  class SpringDataJdbcSampleApplication {
	public static void main(String[] args) {
    	SpringApplication.run(SpringDataJdbcSampleApplication.class, args)
        .getBean(SpringDataJdbcSampleApplication.class).execute();
    }
    
    @Autowired
    MemberCrudRepository repository;
    
    /**
    * 등록과 전체 취득 처리
    */
    private void execute() {
    	//  등록
        executeInsert();
        // 전체 취득
        executeSelect();
    }
    
    /**
    * 등록
    */
    private void executeInsert() {
    	//	엔티티 생성 ( id는 자동 부여되기 때문에 null을 설정 )
        Member member = new Member(null, "이순신");
        // 리포지토리를 이용해 등록을 수행하고 결과를 취득
        member = repository.save(member);
        // 결과를 표시
        System.out.println("등록 데이터 : " + member );
    }
    
    /**
    * 전체 취득
    */
    private void executeSelect() {
    	System.out.println(" --- 전체 데이터를 취득합니다. --- " );
        // 리포지토리를 이용해 전체 데이터를 취득
        Iterable<Member> members = repository.findAll();
        for (Member member : members) {
        	System.out.println(member);
        }
    }
}
profile
느리지만 끝까지 해보자구

0개의 댓글