JDBC
- 자바 언어로 데이터베이스 프로그래밍을 하기위한 라이브러리
- DB에 직접 SQL을 실행하는 저수준 API
- jdbc를 매번 로딩해줘야하고 예외처리를 너무 많이 설정 해주어야함 -> JPA가 나옴
import java.sql.*;
public class JDBCDemo {
public static void main(String[] args) {
try {
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "user", "password");
PreparedStatement stmt = conn.prepareStatement("SELECT * FROM users WHERE email = ?");
stmt.setString(1, "test@example.com");
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
System.out.println("User Name: " + rs.getString("name"));
}
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
JPA
- JPA란 JAVA ORM(Object Relational Mapping) 기술에 대한 인터페이스
- ORM - 객체와 데이터베이스의 관계를 맵핑하는방법
- SQL을 직접 작성하지 않고, 엔티티 객체를 사용해 데이터 조작 가능
- JPA 자체는 인터페이스이므로, 직접 사용할 수 없음
EX)
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
User findByEmail(String email);
}
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
public User getUserByEmail(String email) {
return userRepository.findByEmail(email); // SQL 없이 데이터 조회
}
}
Hibernate
- JPA의 인터페이스를 구현한 라이브러리
- 내부적으로 JDBC를 사용하지만 자동으로 SQL을 생성하고 관리
Session session = HibernateUtil.getSessionFactory().openSession();
session.beginTransaction();
User user = session.get(User.class, 1); // 자동으로 SQL 실행됨
session.getTransaction().commit();
session.close();
흐름
JPA ( 인터페이스 ) -> Hibernate ( 구현체 ) -> JDBC ( SQL 실행 )-> DB
- JPA는 Hibernate 같은 구현체를 통해 동작하고, Hibernate는 내부적으로 JDBC를 사용해서 SQL을 실행
ORM (Object-Relational Mapping)
- ORM은 객체와 관계형 데이터 베이스 간의 매핑을 자동화 하는 기술
- SQL을 직접 작성하지 않고 객체(Entity)를 사용해 데이터베이스의 테이블을 조작할 수 있도록 하는 기술을 의미
- OOP(객체 지향 프로그래밍) 방식으로 데이터를 다룰 수 있으며 SQL을 직접 작성할 필요가 없어진다
JPA (ORM 방식) 예시
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, unique = true)
private String email;
private String name;
}
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
User findByEmail(String email);
}
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
public User getUserByEmail(String email) {
return userRepository.findByEmail(email); // SQL 없이 데이터 조회
}
}
ORM의 장점
- SQL 작성 필요없음
- 객체 지향적인 개발 가능
- DB 변경에 유연함
- 생산성 증가 -> 비즈니스 로직에 집중 할 수 있음
- 트랜잭션 관리 & 캐싱 -> Hibernate 같은 ORM 프레임워크는 자동으로 트랜잭션을 관리하고 성능 최적화를 제공
ORM의 종류
1. JPA (Java Persistence API)
- Java에서 ORM을 위한 표준 인터페이스.
- Hibernate, EclipseLink, OpenJPA 같은 구현체가 있음.
2. Hibernate
- JPA의 대표적인 구현체로, JPA보다 더 많은 기능을 제공.
- 캐싱, 성능 최적화 기능 내장.
3. MyBatis
- 완전한 ORM은 아니지만, XML 기반으로 SQL을 매핑하는 방식.
- 직접 SQL을 작성하지만, JDBC보다 간단하게 DB 매핑 가능.
그럼 비관계형 데이터 베이스랑은 사용할 수 없어?
-> ORM은 기본적으로 관계형 DB(RDBMS) 전용
- ORM은 SQL 기반의 관계형 데이터베이스(MySQL, PostgreSQL, Oracle, MariaDB 등)와 객체를 매핑하기 위해 설계됨.
- SQL을 자동 생성하고 테이블 구조를 객체(Entity)로 매핑하는 방식이기 때문에 MongoDB, Redis 같은 NoSQL과는 원래 맞지 않음.
- NoSQL은 테이블(스키마)이 없거나, 데이터 모델이 SQL과 다르기 때문에 기존 ORM 방식으로는 적용하기 어려움.
-> 일부 NoSQL 데이터베이스에서는 ORM과 유사한 기능을 제공하는 프레임워크가 있음
- 이를 ODM (Object-Document Mapping) 또는 ORM-like 프레임워크라고 부름.
- MongoDB - Mongoose (Node.js), Hibernate OGM ( Java ) / Redis - Spring Data Redis (Java) 같은 것이 대표적인 예 이다
Spring Data JPA
- Hibernate 외에 어떠한 라이브러리를 써도 반복되는 작업의 발생때문에 이를 편리하게 하고 transaction 관리도 spring 에서 관리해주는 형태
@Transactional
public User save(User user) {
return userRepository.save(user);
}
@Transactional
@Override
public <S extends T> S save(S entity) {
Assert.notNull(entity, "Entity must no be null.");
if(entityInformation.isNew(entity) {
em.persist(entity);
return entity;
} else {
return em.merge(entity);
}
}