[Spring] Framework, JPA 개요

Jay Mild Lee·2022년 12월 5일
0

Spring

목록 보기
2/3

I. Spring Framework의 특징

🤔 Framework
프레임워크는 프로그램의 기초를 구축할 수 있는 코드의 집합이다. 협업 시 개발자의 능력이나 작업 방식의 차이에서 올 수 있는 어려움을 방지하고, 쉽게 프로그램의 기본 뼈대를 구성할 수 있도록 한다.

  • ex) Spring, Django, Flask, React, .NET Framework

1. POJO(Plain Old Java Object) 기반의 구성

스프링은 내부적으로 별도 API를 사용하지 않고, Plain Java의 방식 그대로 객체를 구성한다. Java의 기본 개념인 객체지향에 집중하고, 특정 클래스나 라이브러리에 종속되지 않는 방식으로 짜여져있다.

2. Transaction 지원

상황에 따라 @Trancsactional 혹은 XML을 통해 Transaction을 간편하게 구현할 수 있다.

🤔 Transaction cf) Commit, Rollback*
**
데이터베이스의 상태를 변화시키기 위해 수행하는 작업의 단위. 크게 4가지 특성을 갖는다.

  1. 원자성 : Transaction은 DB에 모두 반영되거나, 전혀 반영되지 않아야한다.
  2. 일관성 : Transaction의 결과는 항상 일관되야 한다.
  3. 독립성 : 여러 Transaction이 실행 중일 때, 서로 연관에 관여할 수 없고, 참조할 수 없다.
  4. 지속성 : Transaction이 완료된 이후, 결과는 영구적으로 반영되어야 한다.

3. DI(Dependency Injection) / IoC(Inversion of Control)

💡 DI는 객체를 직접 생성하는 것이 아닌, 외부에서 생성한 후에 주입하는 방식이다.

class Person {
	Schedule schedule;

	public Person() {
		this.schedule = new Schedule();
	}

	// 가능한 여행 출발 날짜를 확인하기 위한 method
	public LocalDateTime vacation() {
		this.schedule.checkSchedule(); // 일정이 있는지 확인
		...
	}
}

위와 같은 코드에서 Person이 가능한 여행 출발 날짜를 확인하기 위해 vacation() 메소드를 호출하기 위해서는, Schedule Class를 필요로 한다. 이러한 경우를 PersonSchedule의존성(Dependency)를 갖는다고 이야기 한다. 이러한 경우, Person과 Schedule은 강한 결합을 지니게 되는데, 그에 따른 단점은 다음과 같다.

  1. 코드의 재사용성이 떨어진다.
  2. Schedule Class가 수정되면, Person Class도 함께 수정되어야 한다.

예를 들어 고객의 요청으로 인해, Schedule 을 상속한 CourseSchedule 혹은 WorkSchedule을 객체에 따라 사용해야한다면 어떨까? 이런 경우 코드는 다음과 같이 수정되어야 할 것이다.

 class Person {
	Schedule schedule;

	public Person() {
		this.schedule = new WorkSchedule();
	}

	// 가능한 여행 출발 날짜를 확인하기 위한 method
	public LocalDateTime vacation() {
		this.schedule.checkSchedule(); // 일정이 있는지 확인
		...
	}
}

만일 Person이 아닌 다른 객체에서도 Schedule 이 아닌 WorkSchedule 혹은 CourseSchedule을 사용해야 한다면, 해당 객체들을 일일이 찾아다니며 코드를 수정해야할 것이다. 결국, 객체 지향 언어를 사용하는 의미가 퇴색된다.

DI는 이러한 문제를 해결하기 위한 방법이다. DI는 객체(Person)가 의존하는 객체(Schedule)를 내부에서 생성하는 것이 아니라, 주입해줌으로써 이를 해결한다.

class Person {
	Schedule schedule;

	public Person(Schedule schdule) {
		this.schedule = schedule;
	}

	// 가능한 여행 출발 날짜를 확인하기 위한 method
	public LocalDateTime vacation() {
		this.schedule.checkSchedule(); // 일정이 있는지 확인
		...
	}
}

위 코드에서 WorkScheduleCourseScheduleSchedule을 상속받았기 때문에, 상황에 따라 Person을 생성할 때 의존할 객체를 선택하여 사용할 수 있다.

💡 IoC는 객체의 호출을 개발자가 결정하지 않고, 외부에서 결정하는 방식이다.

일반적인 객체의 생성 및 실행의 단계는 다음과 같다.

  1. Person 생성
  2. Schedule 생성
  3. schedule.checkSchedule() 호출

하지만 Spring에서는 다음과 같은 순서로 객체를 생성한다.

  1. Person 생성
  2. Spring에 의해 Schedule 주입
  3. Spring이 만든 객체에서 schedule.checkSchedule() 호출

Spring은 ApplicationContext를 사용해 객체(Bean)을 생성하고, 그들 간의 의존 관계(Dependency)를 설정한다. @Configuration 이 붙은 Class들을 설정 정보로 등록해두고, @Bean 이 붙은 메소드의 이름으로 @Bean 리스트를 생성한다. 만일 클라이언트가 특정 @Bean 을 요청하면, ApplicationContext@Bean 리스트를 확인해 생성된 @Bean 을 반환하거나, 생성되지 않은 경우 객체를 @Bean 메소드를 통해 생성하고 반환한다.

II. ORM, JPA, Spring Data JPA

1. ORM(Object Relational Mapping)

객체와 관계형 데이터베이스의 데이터를 자동으로 Mapping해주는 것을 의미.

객체지향 프로그래밍의 목적은 시스템의 복잡성을 제어할 수 있는 다양한 장치를 구축하고 사용하기 위함이다. 이를 위해 추상화, 상속 등의 개념을 사용한다. 이에 반해 데이터베이스는 집합적인 사고로 구성되어있으며, 객체지향 프로그래밍과 지향하는 목적이 다르다. 이를 패러다임의 불일치라고 하며, 개발자의 역할은 이러한 문제를 해결하는 것에 있다.

문제는 이러한 패러다임의 불일치를 해결하기 위해, 개발자는 수많은 시간과 코드를 소비해야한다는 데 있다. 그나마 일정 부분 객체지향의 개념을 적용할 수 있는 RDBMS를 통해 구현해도, 낭비되는 자원은 적지 않다.

public abstract class Item {
    private Long id;
    private String name;
    private int price;
}
public class Album extends Item {
    private String artist;
}
public class Movie extends Item {
    private String director;
    private String actor;
}
public class Book extends Item {
    private String author;
    private String isbn;
}

새로운 ALBUM을 등록하기 위해서는, Album의 Field를 분해하고 두 번에 걸쳐 쿼리를 날려야한다.

INSERT INTO ITEM ...
INSERT INTO ALBUM ...

개발자는 쿼리를 날리기 위해 구문을 생성해야하고, DB에 쿼리를 날리기 위해 여러 메소드를 사용해야한다. 이러한 과정에서 여러 비용이 드는 것도 문제지만, DB에 접근하는 과정에서 반복적인 작업들 속 실수가 발생할 수 있는 것도 무시할 수는 없다. ORM은 이러한 문제를 해결하기 위해 개발되었으며, 프레임워크로는 SQLAlchemy, Sequalize, Hibernate, EclipseLink 등이 있다.

2. JPA(Java Persistent API)

JPA란 자바 ORM 기술에 대한 API 표준 명세를 의미한다. JPA는 ORM을 사용하기 위한 인터페이스를 모아둔 것이며, JPA를 사용하기 위해서는 JPA를 구현한 Hibernate 등의 ORM 프레임워크를 사용해야한다.

3. Spring Data JPA

Spring Data JPA는 Spring Framework에서 JPA를 편리하게 사용할 수 있도록 지원하는 프로젝트이다. CRUD 처리를 위한 공통 인터페이스를 제공하며, repository 개발 시 인터페이스만 작성하면 스프링 데이터 JPA가 구현 객체를 동적으로 생성해서 주입한다. 특히, 공통 메소드가 이닐 경우에도 Spring Data JPA가 메소드 이름을 분석해서 쿼리를 작성해 날려준다.

III. PP, OOP, AOP

1. 절차지향(Procedural Programming)

  • 순차적인 처리가 중요시되며, 프로그램 전체가 유기적으로 연결되도록 하는 프로그래밍 기법
  • 컴퓨터의 처리 방식과 유사하기 때문에, 실행 시간이 짧다는 장점이 있다.
  • 유지보수와 디버깅이 어렵다.
  • ex ) C

2. 객체지향(Object Oriented Programming)

  • 데이터와 절차를 하나의 덩어리로 묶어서 프로그램이 실행되도록 하는 프로그래밍 기법
  • 모듈을 재사용하기 때문에, 하드웨어의 처리량을 감소시킬 수 있다.
  • 모듈의 기능을 사용하기 위해서 전체 모듈을 불러와야하기 때문에, 절차지향 방식보다 프로그램의 크기가 더 커질 수도 있다.

3. 관점지향(Aspect Oriented Programming)

  • OOP를 각 기능별로 모듈화해서 분리하는 프로그래밍 기법
  • OOP의 대부분의 장점을 극대화시킨다.

0개의 댓글