@Bean Annotation @Configuration @Autowired

"Bean": 스프링 프레임워크에서 관리하는 객체

@Configuration : 빈(bean) 정의 및 의존성 주입 등 다양한 설정을 포함할 수 있다.

1.빈 등록: @Bean 어노테이션과 함께 사용하여 스프링 컨테이너에 빈을 등록. 이를 통해 다른 클래스에서 필요할 때 주입하여 사용할 수 있다.

2.의존성 주입: @Autowired나 @Inject와 같은 어노테이션을 사용하여 다른 빈들 간의 의존성을 주입한다.

3.환경 설정: @PropertySource 어노테이션을 사용하여 외부 설정 파일을 읽어들일 수 있다.

4.프로필 설정: @Profile 어노테이션을 사용하여 개발, 테스트, 운영 등 다양한 환경에 맞는 빈 설정을 구성할 수 있다.

//svc interface
public interface MyService {
    String getMessage();
}
//svc Impl
import lombok.RequiredArgsConstructor;

@RequiredArgsConstructor
public class MyServiceImpl implements MyService {

    private final MyRepository myRepository;

    @Override
    public String getMessage() {
        return myRepository.getMessage();
    }
}
//DAO interface
public interface MyRepository {
    String getMessage();
}
//DAO Impl
public class MyRepositoryImpl implements MyRepository {

    @Override
    public String getMessage() {
        return "Hello from MyRepositoryImpl";
    }
}
@Configuration
public class AppConfig {

    @Bean
    public MyService myService(MyRepository myRepository) {
        return new MyServiceImpl(myRepository);
    }

    @Bean
    public MyRepository myRepository() {
        return new MyRepositoryImpl();
    }
}
//Controller
@RestController
public class MyController {

    private final MyService myService;

    @Autowired
    public MyController(MyService myService) {
        this.myService = myService;
    }

    @GetMapping("/message")
    public String message() {
        return myService.getMessage();
    }
}

JPA (Java Persistence API)

Java Persistence API (JPA)는 Java에서 관계형 데이터베이스를 다루기 위한 API로, 객체 지향 프로그래밍과 관계형 데이터베이스 간의 매핑을 제공한다. JPA는 개발자들이 SQL 쿼리를 작성하지 않고도 데이터베이스와 상호 작용할 수 있게 도와준다.

 

JPA 소개
JPA는 ORM (Object-Relational Mapping) 기술의 구현체 중 하나다. ORM은 객체와 데이터베이스 간의 매핑을 자동으로 처리하여 개발자들이 객체 지향적으로 데이터를 다룰 수 있도록 도와준다.

JPA는 Java SE와 Java EE에서 모두 사용 가능하며, Java EE에서는 JPA를 기반으로 JPA를 지원하는 EJB 컨테이너와 웹 애플리케이션 서버에서 JPA를 사용할 수 있다. JPA는 Hibernate, EclipseLink, OpenJPA 등의 구현체를 가지고 있다.

Oracle DB와 JPA 연동하기
JPA에서는 다양한 데이터베이스 관리 시스템과 호환되며, Oracle DB도 지원된다. JPA에서 Oracle DB를 사용하기 위해서는 해당 데이터베이스에 맞는 JDBC 드라이버가 필요하다. 이 드라이버를 클래스패스에 추가하고, JPA 프로바이더 설정에서 해당 드라이버를 사용하도록 설정하면 된다.

그러나 Oracle DB에서는 다른 데이터베이스 시스템과는 다른 특성이 있을 수 있으므로, JPA를 사용할 때 이에 맞는 설정이 필요할 수 있다. 예를 들어, Oracle DB에서는 시퀀스를 사용하여 자동 증가 ID 값을 생성하는 것이 일반적이다. 이러한 설정은 JPA에서 맞춤 설정할 수 있다.

JPA 설치 및 설정
JPA는 Java SE와 Java EE에 모두 포함되어 있으므로 별도로 설치할 필요가 없다. Java SE의 경우, JPA를 사용하기 위해서는 Java Persistence API 구현체를 추가해야 한다. 대표적인 JPA 구현체로 Hibernate, EclipseLink, OpenJPA 등이 있다.

이러한 JPA 구현체는 Maven, Gradle 등의 빌드 도구를 사용하여 프로젝트에 추가할 수 있다. 또는 해당 JPA 구현체의 라이브러리 파일을 다운로드하여 프로젝트에 추가할 수도 있다.

Java EE의 경우, JPA를 지원하는 컨테이너를 사용하면 된다. 대표적인 Java EE 컨테이너로는 WildFly, TomEE, GlassFish 등이 있다. 이러한 컨테이너는 JPA 구현체를 자동으로 포함하고 있으므로 별도로 설치할 필요가 없다.

즉, JPA를 사용하기 위해서는 Java SE의 경우 구현체를 추가하거나 Java EE의 경우 컨테이너를 사용하면 된다. 하지만 이러한 구현체나 컨테이너에서 자동으로 JPA를 설치하고 구성해주는 것은 아니므로, 개발자가 직접 설정해주어야 한다.

 

JPA 설정 방법

JPA 설정 파일인 persistence.xml 파일을 생성합니다. 이 파일은 프로젝트의 src/main/resources/META-INF 폴더에 위치해야 한다. persistence.xml 파일에는 데이터베이스 연결 정보와 JPA 구현체에 대한 설정이 포함된다.

<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
             http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
             version="2.1">

    <persistence-unit name="MyPersistenceUnit">
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <properties>
            <property name="javax.persistence.jdbc.driver" value="oracle.jdbc.driver.OracleDriver" />
            <property name="javax.persistence.jdbc.url" value="jdbc:oracle:thin:@localhost:1521:XE" />
            <property name="javax.persistence.jdbc.user" value="your_username" />
            <property name="javax.persistence.jdbc.password" value="your_password" />

            <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle10gDialect" />
            <property name="hibernate.show_sql" value="true" />
            <property name="hibernate.format_sql" value="true" />
        </properties>
    </persistence-unit>
</persistence>

 

Java SE의 경우, 먼저 Maven이나 Gradle과 같은 빌드 도구를 사용하여 프로젝트에 JPA 구현체를 추가해야한다. 

나는 Bulid.gradle을 사용하고 있기에, Bulid.gradle을 기준으로 설명하겠다.

 

dependencies {
    implementation 'org.hibernate:hibernate-core:5.4.32.Final'
}

만약 해당 프로젝트에서 특정 데이터베이스와 연동하기 위해 필요한 JDBC 드라이버도 추가해야 한다면, 다음과 같이 의존성을 추가하면 된다. Oracle DB의 경우, 다음과 같이 의존성을 추가한다.

dependencies {
    implementation 'org.hibernate:hibernate-core:5.4.32.Final'
    implementation 'com.oracle.ojdbc:ojdbc8:19.3.0.0'
}

 

이렇게 설정한 후에는 앞서 설명한대로 persistence.xml 파일을 생성하고 필요한 설정을 추가하여 JPA를 사용할 준비를 마칩니다.

오늘은 객체 지향 프로그래밍의 세계에서 데이터베이스와 매핑되는 클래스, 즉 엔티티 클래스(Entity Class)에 대해 알아보겠다. 누군가는 엔티티 클래스를 객체와 데이터베이스 사이의 로맨틱한 브리지라고 불렀다고 한다. 그러면 이 로맨스가 어떻게 이루어지는지 함께 살펴보자.

 

JPA에서의 엔티티 클래스
JPA(Java Persistence API)에서는 엔티티 클래스를 사용하여 데이터베이스 테이블과 매핑을 수행한다. 이렇게 함으로써, JPA는 객체와 데이터베이스 간의 변환을 자동으로 수행할 수 있다.

이름은 좀 어렵게 들릴 수 있지만, 사실 엔티티 클래스는 마치 영화에서 주인공과 그의 사랑하는 사람 사이에 서는 코미디 캐릭터 같은 역할을 한다. 그들 사이를 이어주는 역할이라고 생각하면 된다!

다음과 같은 엔티티 클래스를 살펴보겠다.

@Entity
@Table(name = "product")
public class Product {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "name")
    private String name;

    @Column(name = "price")
    private int price;

    // ... 생성자, getter, setter 등의 메서드
}

위 코드에서는 @Entity 어노테이션을 사용하여 Product 클래스를 엔티티 클래스로 지정하고 있다. @Table 어노테이션을 사용하여 해당 엔티티가 매핑되는 데이터베이스의 테이블을 지정하고, @Id, @GeneratedValue, @Column 어노테이션을 사용하여 해당 엔티티의 필드와 데이터베이스 테이블의 컬럼을 매핑하고 있다.

이제 이 로맨스를 좀 더 편하게 즐길 수 있는 방법에 대해 알아보자.

 

스프링 부트와 JPA의 환상적인 만남


스프링 부트를 사용하면 JPA의 트랜잭션 처리를 더욱 쉽게 할 수 있다. 스프링 부트는 스프링 프레임워크의 기능을 확장하여 개발자들이 보다

위 코드에서는 ProductService 클래스의 updateProductName 메서드에 @Transactional 애노테이션을 추가하여, 해당 메서드에서 수행되는 모든 데이터 변경 작업이 하나의 트랜잭션으로 처리됨을 보장한다. 이렇게 함으로써, 트랜잭션 처리를 보다 간편하게 할 수 있다.

 

트랜잭션 처리 간편화
스프링 부트에서 JPA를 사용할 때는, 트랜잭션 처리를 위한 코드를 별도로 작성할 필요가 없다. 스프링 프레임워크에서 제공하는 @Transactional 애노테이션을 사용하여 간단하게 트랜잭션 처리를 할 수 있다.

예를 들어, ProductService 클래스에서 Product 엔티티를 저장하는 메서드를 작성한다고 가정해 보겠다.

@Service
public class ProductService {
    @Autowired
    private EntityManager entityManager;

    @Transactional
    public void saveProduct(String name, int price) {
        Product product = new Product();
        product.setName(name);
        product.setPrice(price);

        entityManager.persist(product);
    }
}

 

여기서 @Transactional 애노테이션을 사용하여 saveProduct 메서드에 트랜잭션 처리를 적용하고 있다. 이제 이 메서드를 호출하면, 스프링 프레임워크가 자동으로 트랜잭션을 시작하고, 메서드가 정상적으로 종료되면 트랜잭션을 커밋하게 된다. 만약 메서드 실행 중 예외가 발생하면, 트랜잭션은 자동으로 롤백된다.

레포지토리 사용의 편리성
또한 스프링 부트에서는 JpaRepository 인터페이스를 상속받는 레포지토리 클래스를 생성하여, 데이터베이스 작업을 보다 쉽게 처리할 수 있다. JpaRepository 인터페이스는 기본적인 CRUD 작업을 추상화하고 있어, 별도의 구현 없이도 사용할 수 있다.

public interface ProductRepository extends JpaRepository<Product, Long> {
}

이렇게 ProductRepository 인터페이스를 생성한 후, ProductService 클래스에서 이를 사용하면 된다.

@Service
public class ProductService {
    @Autowired
    private ProductRepository productRepository;

    public void saveProduct(String name, int price) {
        Product product = new Product();
        product.setName(name);
        product.setPrice(price);

        productRepository.save(product);
    }
}

이제 ProductService 클래스에서 JpaRepository를 통해 제공되는 기본 CRUD 메서드를 사용하여 데이터베이스 작업을 쉽게 처리할 수 있다.

정리하자면, 엔티티 클래스는 객체와 데이터베이스 사이의 로맨스를 이루는 중요한 요소입니다. 스프링 부트를 사용하면 JPA를 통해 엔티티 클래스와 데이터베이스 작업을 더욱 쉽게 처리할 수 있다. 트랜잭션 처리를 간편하게 적용할 수 있는 @Transactional 애노테이션과 JpaRepository 인터페이스를 사용하면, 코드의 가독성과 유지보수성이 높아진다.

 

 

트랜잭션은  더 이상 쪼갤 수 없는 업무 처리의 최소 단위이다.

 

 A라는 사람이 B라는 사람있는데 1,000원을 지급하고 B가 그 돈을 받은 경우, 이 거래 기록은 더 이상 작게 쪼갤 수가 없는 하나의 트랜잭션을 구성한다. 만약 A는 돈을 지불했으나 B는 돈을 받지 못했다면 그 거래는 성립되지 않는다. 이처럼 A가 돈을 지불하는 행위와 B가 돈을 받는 행위는 별개로 분리될 수 없으며 하나의 거래내역으로 처리되어야 하는 단일 거래이다. 이런 거래의 최소 단위를 트랜잭션이라고 한다. 트랜잭션 처리가 정상적으로 완료된 경우 커밋(commit)을 하고, 오류가 발생할 경우 원래 상태대로 롤백(rollback)을 한다.

트랜잭션은 데이터베이스에서 데이터의 일관성과 무결성을 보장하기 위해 사용된다.

 

트랜잭션은 일반적으로 다음과 같은 4가지 속성을 가진다.

 

원자성(Atomicity): 트랜잭션의 모든 작업이 완전히 수행되거나, 아니면 전혀 수행되지 않아야 한다. 즉, 트랜잭션 내의 작업 중 어느 하나라도 실패하면 전체 작업이 롤백되어야 한다.

 

일관성(Consistency): 트랜잭션 수행 전과 수행 후의 데이터베이스 상태가 일관되어야 한다. 즉, 트랜잭션 수행 후에도 데이터베이스의 제약 조건이 유지되어야 한다.

 

격리성(Isolation): 여러 개의 트랜잭션이 동시에 수행되더라도, 각각의 트랜잭션은 독립적으로 수행되는 것처럼 보여야 한다. 즉, 다른 트랜잭션에서 수행하는 작업에 대해 영향을 받지 않아야 한다.

 

지속성(Durability): 트랜잭션이 성공적으로 완료된 후에는, 해당 작업의 결과가 영구적으로 데이터베이스에 반영되어야 한다. 즉, 시스템 장애 또는 기타 문제가 발생해도 데이터의 일관성과 무결성이 유지되어야 한다.

 

다음은 JPA를 사용하여 트랜잭션을 시작하고, 데이터 변경 작업을 수행한 후에 트랜잭션을 커밋하거나 롤백하는 예시 코드다.

EntityManager entityManager = entityManagerFactory.createEntityManager();
EntityTransaction transaction = entityManager.getTransaction();

try {
    transaction.begin(); // 트랜잭션 시작
    // 데이터 변경 작업 수행
    Product product = entityManager.find(Product.class, 1L);
    product.setName("새로운 상품명");

    transaction.commit(); // 트랜잭션 커밋
} catch (Exception ex) {
    transaction.rollback(); // 트랜잭션 롤백
} finally {
    entityManager.close();
}

위 코드에서는 EntityManager를 사용하여 엔티티를 조회하고, 엔티티의 속성을 변경하는 데이터 변경 작업을 수행한다. 이러한 데이터 변경 작업은 트랜잭션 내에서 수행되어야 한다. 따라서, 트랜잭션을 시작하고, 변경 작업을 수행한 후에는 반드시 트랜잭션을 커밋하거나 롤백해야 한다.

트랜잭션을 커밋하면, 영속성 컨텍스트에서 변경 사항이 데이터베이스에 반영된다. 반면에 트랜잭션을 롤백하면, 변경 사항은 모두 취소되어 원래의 상태로 복원된다. 이를 통해 데이터 일관성을 유지할 수 있다.

 

< 주로 활용 되는 곳 >

 

은행 및 금융 업무: 은행 및 금융 기관에서는 트랜잭션을 사용하여 계좌 이체, 입출금, 거래 기록 등의 금융 업무를 처리한다. 트랜잭션을 통해 동시성 문제를 해결하고 데이터의 일관성과 정확성을 유지할 수 있다.

온라인 쇼핑 및 결제: 온라인 쇼핑몰이나 결제 시스템에서 트랜잭션은 주문 처리, 결제 처리, 재고 관리 등의 업무에 활용된다. 고객이 주문을 생성하거나 결제를 수행할 때, 트랜잭션은 데이터의 일관성과 결제 과정의 안전성을 보장한다.

예약 시스템: 항공사, 호텔, 렌터카 등의 예약 시스템에서는 동시성을 관리하고 데이터의 일관성을 유지하기 위해 트랜잭션을 사용한다. 여러 사용자가 동시에 예약을 시도하더라도 충돌이나 중복 예약을 방지하여 데이터의 정확성과 일관성을 유지할 수 있다.

자원 관리 시스템: 자원 관리 시스템에서는 트랜잭션을 사용하여 자원의 예약, 할당, 해제 등의 작업을 처리한다. 예를 들어, 컴퓨터 자원의 할당이나 데이터베이스의 락(lock) 관리 등에서 트랜잭션이 활용한다.

비즈니스 프로세스 관리: 비즈니스 프로세스 관리 시스템(BPM)에서는 트랜잭션을 사용하여 여러 단계의 작업을 원자적인 단위로 처리하고, 중간 상태에서의 실패를 방지하여 데이터 일관성과 정확성을 유지한다.

이 외에도 트랜잭션은 데이터베이스 시스템의 안정성과 신뢰성을 보장하는데 핵심적인 역할을 한다. 다양한 업무 및 응용 분야에서 트랜잭션이 활용되어 데이터의 일관성과 정확성을 유지하고 동시성 문제를 해결할 수 있다.

'SQL 이론' 카테고리의 다른 글

DBMS(Database Management System)  (0) 2023.05.16
DataBase 일관성/무결성 제약 조건  (0) 2023.05.16
Mysql 설치 및 DBeaver 설치 방법 (Windows)  (0) 2023.05.14
row와 column이 뭐에요?  (0) 2022.07.28
Data Base가 뭐에요?  (0) 2022.07.28

+ Recent posts