implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
runtimeOnly 'com.mysql:mysql-connector-j'
JPA에서 제공하는 인터페이스 제공함
✅ 장점
1. 코드가 매우 간결함 (인터페이스만 선언하면 됨)
2.반복적인 CRUD 코드 제거 - 간결함
3.페이징, 정렬, 쿼리 메서드 등 풍부한 기능 제공 - 빠른동작에는 편리함
⚠️ 단점
1.너무 복잡하거나 동적인 쿼리는 오히려 불편
2.트랜잭션 관리나 영속성 컨트롤이 필요할 땐 제약이 있음 Spring Data JPA가 제공하는 인터페이스 기반 CRUD 도구
3.기본적인 저장, 조회, 삭제 메서드들이 자동으로 구현되어 있음
4.쿼리 메서드만 선언하면 복잡한 SQL 없이도 동작
JPA의 핵심 API, 직접 사용하는 방식
✅ 장점
1.JPQL, Native Query 등을 자유롭게 작성 가능
2.세밀한 트랜잭션 제어 가능
3.복잡한 비즈니스 로직 처리 시 유리
⚠️ 단점
1. 직접 작성해야 하므로 코드량 많음
2.반복 작업이 많아지면 생산성 낮아짐
@Repository
public interface DepartmentRe extends JpaRepository<Department, Long> {
}// 인터페이스 선언
설명했듯이 repository를 인터페이스로 하고 JpaRepository 상속받아 사용하고 기본적으로 사용할수 있는 메소드제공됨
package com.pj.portfoliosite.jpa_study.service;
import com.pj.portfoliosite.jpa_study.entity.Department;
import com.pj.portfoliosite.jpa_study.repository.DepartmentRe;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
@RequiredArgsConstructor
public class DepartmentService {
private final DepartmentRe departmentRe;
//조회
public List<Department> findAll() {
return departmentRe.findAll();
}
// 저장
public void save(Department department) {
departmentRe.save(department);
}
// 삭제
public void delete(Department department) {
departmentRe.delete(department);
}
// id로 조회
public Department findById(Long id) {
return departmentRe.findById(id).orElse(null);
}
// 수정
@Transactional
public void updateDepartment(Long id, Department department) {
Department dept = departmentRe.findById(id).orElse(null);
System.out.println(department.getName().toString());
dept.setName(department.getName());
}
}
인터페이스에 구현체가 없어도 제공하는 메서드로 데이터베이스에 데이터를 가져올수있다! 편하긴하네.. ㅎㅎ
@Repository
@Transactional
public class DepartmentRepository{
@PersistenceContext
private EntityManager em;
// 저장하는 메소드
public void save(Department department) {
em.persist(department);
}
//단일 조회
public Department findById(Long id) {
return em.find(Department.class, id);
}
// 삭제
public void delete(Department department) {
em.remove(department);
}
// update
public void updateDepartment(Long id,Department department) {
em.createQuery("UPDATE Department d SET d.name = :name WHERE d.id = :id")
.setParameter("name", department.getName())
.setParameter("id", id);
}
// 전체 조회
public List<Department> findByAll() {
return em.createQuery("select d from Department d", Department.class).getResultList();
}
}
우리가 JPQL를 사용해서 가져오고 평소에쓰는 SQL문과 별칭쓰는거 같다

이것은 EntityManger 를 사용할때 트랜잭션 어노테이션이 없으면 나는 오류이다!
JpaRepository 는 트랜잭션 내부에 동작하고 있어서 없어도 되지만 EntityManger를 사용할때는 @Transactional 를 꼭 써주자!
class 상단에 @Transactional 작성

찾아보니 성능때문에 SELECT NEXTVAL() 를 하지않고 id 값을 캐시 저장해서 50개씩 묶어서 하다보니 서버를 재시작할때 +50개씩 되는것이였다.
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
내가 이전에 entity 설계할때 GenerataionType.Auto로 했는데 이거를 IDENTITY 변경후에는 재 실행해도 내가 원하는 데로 저장이된다.
이게 뭔 차이가 있겠지만 성능차이랑 index 최적화 가지고 활용하는 곳이면 잘 생각해서 써야겠다.

흠.. 저는 mybatis를 주로 써서 그런지, JPQL를 활용할수있는 EntityManager가 쓰는게 좋네요!
Git
https://github.com/spring-projects/spring-data-examples/tree/main/jpa
DOCS
https://spring.io/projects/spring-data-jpa
다음 글에는 주인관계에 대해서 CRUD 활용을 작성하겠습니다.
긴글 읽어 주셔서 감사합니다!