하루 4개씩 기초지식!
더보기
1. Index는 뭐고 장/단점은 뭐가 있을까?
- Index란 테이블을 처음부터 끝까지 검색하는 방법인 FTS(Full table Scan)과는 달리 인덱스를 검색하여 해당 자료의 테이블을 엑세스 하는 방법!
- 예를 들어, DB를 책으로 비유하자면 데이터는 책의 내용일 것이고, 데이터가 저장된 레코드의 주소는 index 목록에 있는 페이지 번호일 것이다!
- 예를 들어, DB를 책으로 비유하자면 데이터는 책의 내용일 것이고, 데이터가 저장된 레코드의 주소는 index 목록에 있는 페이지 번호일 것이다!
- 인텍스는 항상 정렬된 상태를 유지하기에 원하는 값을 검색하는데 빠르지만, 새로운 값을 추가하거나 삭제, 수정하는 경우에는 쿼리문 실행 속도가 느려집니다.
- 즉! 인덱스는 데[이터의 저장 성능을 희생하고 그 대신 데이터의 검색 속도를 높이는 기능이라 할 수 있다!
2. 정규화?
- 하나의 릴레이션에 하나의 의미만 존재하도록 릴레이션을 분해하는 과정이며, 데이터의 일관성, 최소한의 데이터 중복, 최대한의 데이터 유연성을 위한 방법입니다
- 릴레이션?
- 릴레이션이란 관계형 데이터 베이스에서 정보를 구분하여 저장하는 기본 단위
- 릴레이션이란 관계형 데이터 베이스에서 정보를 구분하여 저장하는 기본 단위
- 릴레이션?
- 제1 정규형 : 테이블의 컬럼이 원자 값(Atomic Value; 하나의 값)을 갖도록 분해합니다.
- 제2 정규형: 제1 정규형을 만족하고, 기본키가 아닌 속성이 기본키에 완전 함수 종속이도록 분해합니다.
※ 여기서 완전 함수 종속이란 기본키의 부분집합이 다른 값을 결정하지 않는 것을 의미 - 제3 정규형 : 제2 정규형을 만족하고, 이행적 함수 종속을 없애도록 분해합니다.
※ 여기서 이행적 종속이란 A → B, B → C가 성립할 때 A → C가 성립되는 것을 의미 - BCNF 정규형 : 제3 정규형을 만족하고, 함수 종속성 X → Y가 성립할 때 모든 결정자 X가 후보키가 되도록 분해합니다.
- 장점
- 1. 데이터베이스 변경 시 이상현상이 발생하는 문제점을 해결할 수 있다.
- 2. 데이터베이스 구조 확장 시 정규화된 데이터베이스는 그 구조를 변경하지 않아도 되거나 일부만 변경해도 된다.
- 1. 데이터베이스 변경 시 이상현상이 발생하는 문제점을 해결할 수 있다.
- 단점
- 릴레이션의 분해로 인해 릴레이션 간의 연산(JOIN 연산)이 많아진다. 이로인해 질의에 대한 응답 시간이 느려질 수 있다.
+ 정규화를 수행한다는 것은 이상현상을 제거하는 것이다. 데이터의 중복 속성을 제거하고 결정자에 의해 동일한 의미의 일반 속성이 하나의 테이블로 집약되므로 한 테이블의 데이터 용량이 최소화되는 효과가 있다. 따라서 정규화된 테이블은 데이터를 처리할 때 속도가 빨라질 수도 있고 느려질 수도 있는 특성이 있다.
- 릴레이션의 분해로 인해 릴레이션 간의 연산(JOIN 연산)이 많아진다. 이로인해 질의에 대한 응답 시간이 느려질 수 있다.
3. 이상 현상의 종류가 뭐가 있을까?
- 이상 현상은 테이블을 설계할 때 잘못 설계하여 데이터를 삽입,삭제,수정할 때 생기는 논리적 오류를 말합니다.
- 삽입 이상 : 자료를 삽입할 때 특정 속성에 해당하는 값이 없어 NULL을 입력해야 하는 현상
- 갱신 이상 : 중복된 데이터 중 일부만 수정되어 데이터 모순이 일어나는 현상
- 삭제 이상 : 어떤 정보를 삭제하면, 의도하지 않은 다른 정보까지 삭제되어버리는 현상
- 이러한 이상 현상을 예방하고 효과적인 연산을 하기 위해 데이터 정규화를 합니다.
4. SQL Injection이 무엇인지 설명해주세요.
- SQL Injection이란 공격자가 악의적인 의도를 갖는 SQL 구문을 삽입하여 데이터베이스를 비정상적으로 조작하는 코드 인젝션 공격 기법입니다.
2. JPA에 대해서 한번 알아볼까?
1. ORM?
- Object- Relational Mapping 이름 그대로 객체와 DB의 관계를 매핑 해주는 도구!
- 객체 즉, 자바의 클래스와 DB의 데이터를 직접 매핑 하려면 앞서 살펴본 것 처럼 매우 번거롭고 많은 작업들이 필요했지만 ORM을 사용하면 이를 자동으로 처리해준다..!!!!!!
- 객체 즉, 자바의 클래스와 DB의 데이터를 직접 매핑 하려면 앞서 살펴본 것 처럼 매우 번거롭고 많은 작업들이 필요했지만 ORM을 사용하면 이를 자동으로 처리해준다..!!!!!!
- 장점
- 객체와 테이블 간의 매핑을 자동으로 처리해 개발 속도가 빨라진다!
- ORM 프레임 워크를 사용하면 동일한 엔티티 클래스를 여러 프로젝트에서 재사용?!!
- 단점
- 복잡성 : 복잡한 매핑과 연관 관계를 다룰 때 복잡해질 수 있다...
- 대용량 데이터 처리 시, ORM이 자동으로 생성한 쿼리의 성능이 떨어질 수 있다!
- 복잡성 : 복잡한 매핑과 연관 관계를 다룰 때 복잡해질 수 있다...
- 종류
- Hibernate : 가장 널리 사용되는 JPA 구현체로, 다양한 기능을 제공한다!
- EclipseLink : JPA의 참조 구현체!
- Apache OpenJPA : 아파치 프로젝트에서 제공하는 JPA 구현체!
예시 코드
@Entity // 이 클래스가 JPA 엔티티임을 나타냄. 데이터베이스 테이블에 매핑됨.
public class User {
@Id // 이 필드가 엔티티의 고유 식별자(Primary Key)임을 나타냄.
@GeneratedValue(strategy = GenerationType.IDENTITY) // Primary Key 값을 자동으로 생성해줌.
private Long id; // 데이터베이스 테이블의 "id" 컬럼에 매핑됨.
private String username; // 데이터베이스 테이블의 "username" 컬럼에 매핑됨.
private String email; // 데이터베이스 테이블의 "email" 컬럼에 매핑됨.
// 기본 생성자. JPA는 엔티티 클래스를 인스턴스화할 때 기본 생성자를 사용함.
public User() {}
// 모든 필드를 초기화하는 생성자.
public User(String username, String email) {
this.username = username;
this.email = email;
}
// Getter와 Setter 메서드. JPA가 필드 값을 읽고 쓸 때 사용함.
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
2. ORM이랑 JPA랑 무슨 관련이 있어요..?
- JPA(Java Persistence API)는 Java 진영의 ORM 기술 표준으로 채택된 인터페이스 모음!
- 장점은 뭘까요?
- SQL을 직접 작성하지 않고도 데이터베이스 작업을 할 수 있다! 따라서 코드 간결! 생산성 증가!
- 객체지향적인 코드 작성으로 인한 유지 보수 쉬움!
- JPQL과 같은 추상화된 쿼리 언어를 사용해 특정 DBMS에 종속되지 않아!
- SQL을 직접 작성하지 않고도 데이터베이스 작업을 할 수 있다! 따라서 코드 간결! 생산성 증가!
- 그럼 단점은..?
- 복잡한 데이터 처리 작업에서는 SQL보다 성능이 떨어질 수 있다..
- JPA의 개념과 동작 원리를 이해하는데 초기 비용이 필요!
- 복잡한 데이터 처리 작업에서는 SQL보다 성능이 떨어질 수 있다..
3. JPA에서 관리하는 객체? 바로 Entity
- 특징이랄까
- 엔티티 클래스는 데이터베이스 테이블에 매핑되어, 클래스의 각 필드는 테이블의 컬럼과 매핑!
- 각 엔티티는 고유 식별자가 있어야 하고, 이 식별자는 기본 키로 사용!
- 엔티티 클래스는 데이터베이스 테이블에 매핑되어, 클래스의 각 필드는 테이블의 컬럼과 매핑!
- 장점
- 엔티티 클래스는 데이터베이스 테이블 구조를 명확히 표현할 수 있다!
- JPA가 엔티티의 상태를 자동으로 관리해, 데이터베이스와의 동기화가 쉬워진다!
- 엔티티 클래스는 데이터베이스 테이블 구조를 명확히 표현할 수 있다!
- 그럼 단점은??
- 복잡한 매핑이나 특수한 요구사항이 있는 경우 추가적인 설정이 필요!
- 앤타타 설계까 잘못되면 데이터베이스와의 상호작용이 어려워질 수 있다!
- 복잡한 매핑이나 특수한 요구사항이 있는 경우 추가적인 설정이 필요!
- 종류로는 무엇이 있을까?
- 단일 엔티티 : 하나의 테이블과 매핑되는 기본적인 엔티티!
- 상속 엔티티 : 테이블 간의 상속 관계를 매핑하는 엔티티 (@Inheritance 어노테이션 사용!)
- 임베디드 엔티티 : 엔티티 내에 포함되는 엔티티로, 별도의 테이블에 매핑되지 않고 포함된 엔티티의 필드가 동일한 테이블에 매핑된다! ( @Embedded 어노테이션 사용!)
- 어노테이션
- @Entity : JPA가 관리할 수 있는 Entity 클래스로 지정할 수 있습니다.
- @Entity(name = "Memo") : Entity 클래스 이름을 지정할 수 있습니다. (default: 클래스명)
- JPA가 Entity 클래스를 인스턴스화 할 때 기본 생성자를 사용하기 때문에 반드시 현재 Entity 클래스에서 기본 생성자가 생성되고 있는지 확인해야 합니다.
- @Entity(name = "Memo") : Entity 클래스 이름을 지정할 수 있습니다. (default: 클래스명)
- @Table : 매핑할 테이블을 지정해줍니다.
- @Table(name = "memo") : 매핑할 테이블의 이름을 지정할 수 있습니다. (default: Entity 명)
- @Table(name = "memo") : 매핑할 테이블의 이름을 지정할 수 있습니다. (default: Entity 명)
- @Column :
- @Column(name = "username") : 필드와 매핑할 ****테이블의 컬럼을 지정할 수 있습니다. (default: 객체의 필드명)
- @Column(nullable = false) : 데이터의 null 값 허용 여부를 지정할 수 있습니다. (default: true)
- @Column(unique = true) : 데이터의 중복 값 허용 여부를 지정할 수 있습니다. (default: false)
- @Column(length = 500) : 데이터 값(문자)의 길이에 제약조건을 걸 수 있습니다. (default: 255)
- @Column(name = "username") : 필드와 매핑할 ****테이블의 컬럼을 지정할 수 있습니다. (default: 객체의 필드명)
- @Id : 테이블의 기본 키를 지정해줍니다.
- 이 기본 키는 영속성 컨텍스트에서 Entity를 구분하고 관리할 때 사용되는 식별자 역할을 수행합니다.
- 따라서 기본 키 즉, 식별자 값을 넣어주지 않고 저장하면 오류가 발생합니다.
- 따라서 기본 키 즉, 식별자 값을 넣어주지 않고 저장하면 오류가 발생합니다.
- @Id 옵션만 설정하면 기본 키 값을 개발자가 직접 확인하고 넣어줘야 하는 불편함이 발생합니다.
- 이 기본 키는 영속성 컨텍스트에서 Entity를 구분하고 관리할 때 사용되는 식별자 역할을 수행합니다.
- @GeneratedValue 옵션을 추가하면 기본 키 생성을 DB에 위임할 수 있습니다.
- @GeneratedValue(strategy = GenerationType.IDENTITY**)**
- id bigint not null auto_increment : auto_increment 조건이 추가된 것을 확인할 수 있습니다.
- 해당 옵션을 추가해주면 개발자가 직접 id 값을 넣어주지 않아도 자동으로 순서에 맞게 기본 키가 추가됩니다.
- @GeneratedValue(strategy = GenerationType.IDENTITY**)**
- @Entity : JPA가 관리할 수 있는 Entity 클래스로 지정할 수 있습니다.
<예시 코드>
@Entity //JPA가 관리할 수 있는 Entity 클래스 지정
public class Product {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private double price;
// Getter, Setter, Constructor
}
4. 영속성 컨텍스트! (PErsistence Context)
- Entity 객체를 효율적으로 쉽게 관리하기 위해 만들어진 공간!
- 영속성 컨텍스트에서 동일한 엔티티는 동일성을 보장해, 즉, 같은 엔티티는 동일한 메모리 참조를 가진다!
- EntiryManager? 갑자기 이게 뭐죠..?
- 영속성 컨텍스트에 접근하여 Entity 객체들을 조작하기 위해서는 EntityManager가 필요하다!
- EntityManager를 사용해서 Entity를 조회하고 저장하고 수정하고 삭제할 수 있다!
- EntityManager는 EntityManagerFactory를 통해 생성하여 사용할 수 있다!
- 영속성 컨텍스트에 접근하여 Entity 객체들을 조작하기 위해서는 EntityManager가 필요하다!
- EntityManagerFactory는 또 뭐야,,,
- EntityManagerFactory는 일반적으로 DB 하나에 하나만 생성되어 애플리케이션이 동작하는 동안 사용된다!
- EntityManagerFactory를 만들기 위해서는 DB에 대한 정보를 전달해야 한다!
<예시 코드>
EntityManager em = ...; // EntityManager는 JPA의 핵심 클래스. 엔티티를 관리하고 데이터베이스 작업을 수행함.
em.getTransaction().begin(); // 트랜잭션을 시작함. JPA는 트랜잭션 내에서 작업을 처리함.
Customer customer = new Customer("Winter", "winter@sm.com"); // 새로운 Customer 엔티티 객체를 생성함.
em.persist(customer); // 생성한 엔티티를 영속성 컨텍스트에 저장함. 이제 이 엔티티는 영속 상태가 됨.
Customer foundCustomer = em.find(Customer.class, customer.getId());
// 영속성 컨텍스트에서 Customer 엔티티를 ID로 조회함. 영속성 컨텍스트에 이미 존재하면 1차 캐시에서 반환됨.
foundCustomer.setName("Karina");
// 조회된 엔티티의 값을 변경함. 영속성 컨텍스트는 이 변경을 감지하고, 트랜잭션 커밋 시점에 데이터베이스에 반영함.
em.getTransaction().commit(); // 트랜잭션을 커밋함. 이 시점에 변경된 사항이 데이터베이스에 반영됨.
5. JPA 트랜젝션 ,, 뭐가 이렇게 많지,,?
- 우선 트랜젝션이 뭐지?
- 트랜잭션은 DB 데이터들의 무결성과 정합성을 유지하기 위한 하나의 논리적 개념! (어렵다;)
- 쉽게 표현하자면 DB의 데이터들을 안전하게 관리하기 위해서 생겨난 개념이다!
- 가장 큰 특징은 여러개의 SQL이 하나의 트랜잭션에 포함될 수 있다는 점이다!
- 모든 SQL이 성공적으로 수행이 되면 DB에 영구적으로 변경을 반영하지만 SQL 중 단 하나라도 실패한다면 모든 변경을 되돌린다..?
- 명령어
- JPA에서 이러한 트랜잭션의 개념을 적용하기 위해서는 EntityManager에서 EntityTransaction을 가져와 트랜잭션을 적용할 수 있습니다.
- EntityTransaction et = em.getTransaction();
- 해당 코드를 호출하여 EntityTransaction을 가져와 트랜잭션을 관리할 수 있습니다.
- et.begin();
- 트랜잭션을 시작하는 명령어입니다.
- et.commit();
- 트랜잭션의 작업들을 영구적으로 DB에 반영하는 명령어입니다.
- 트랜잭션의 작업들을 영구적으로 DB에 반영하는 명령어입니다.
- et.rollback();
- 오류가 발생했을 때 트랜잭션의 작업을 모두 취소하고, 이전 상태로 되돌리는 명령어입니다!.
- JPA에서 이러한 트랜잭션의 개념을 적용하기 위해서는 EntityManager에서 EntityTransaction을 가져와 트랜잭션을 적용할 수 있습니다.
- 트랜잭션은 DB 데이터들의 무결성과 정합성을 유지하기 위한 하나의 논리적 개념! (어렵다;)
<예시 코드>
@Service // 이 클래스가 Spring 서비스 클래스임을 나타냄. 비즈니스 로직을 처리하는 곳임.
public class OrderService {
@Autowired // Spring이 EntityManager를 자동으로 주입하도록 함.
private EntityManager em; // EntityManager는 JPA의 핵심 인터페이스로, 엔티티 관리를 담당함.
@Transactional // 이 메서드가 트랜잭션 안에서 실행됨을 나타냄. 메서드 내 모든 작업은 하나의 트랜잭션으로 묶임.
public void placeOrder(Long productId, int quantity) {
Product product = em.find(Product.class, productId);
// 특정 ID로 Product 엔티티를 조회함. 영속성 컨텍스트에서 조회되며, 없으면 데이터베이스에서 조회됨.
// 비즈니스 로직 처리 (예: 재고 확인, 가격 계산 등)
// 이 부분에서 주문 처리에 필요한 추가 로직을 작성할 수 있음.
em.persist(new Order(product, quantity));
// 새로운 Order 엔티티를 생성하고 영속성 컨텍스트에 저장함. 주문이 생성됨.
// 트랜잭션이 종료될 때 (메서드 종료 시점) 변경사항이 자동으로 커밋되어 데이터베이스에 반영됨.
}
}
'스프링' 카테고리의 다른 글
Spring 인증 및 관리 시스템 (0) | 2024.09.06 |
---|---|
[TroubleShooting] 의존성 주입,,,실패하다,, (1) | 2024.08.29 |
스프링 의존성 주입? 강한 결합? 느슨한 결합? (0) | 2024.08.21 |
Servlet은 뭐고 Dispatcher - Servlet은 뭐죠..? (0) | 2024.08.20 |
[Spring] Entity...! (0) | 2024.08.19 |