
자바의 ORM기술을 쉽게 구현하도록 도와주는 API
- ORM (Objcet-Relation Mapping/ 객체-관계매핑)
- 객체와 DB의 데이터를 자동으로 매핑
- SQL 쿼리가 아닌 메서드로 데이터 조작 가능
- 객체간 관계를 바탕으로 SQL을 자동으로 생성

데이터를 객체지향적으로 관리할 수 있기 때문에 개발자는 비즈니스 로직에 집중할 수 있고 객체지향 개발이 가능하다.
JpaRepository를 상속하는 인터페이스에 메서드 이름만 적어놓으면 구현체 생성, 쿼리문 구현 등을 알아서 다 처리해주는 ORM.
메소드 이름은 findby(필드명), orderby(필드명)처럼 메소드 명칭만 적어주면 SQL을 작성하지 않아도 쿼리문을 만들어준다.
데이터베이스의 CRUD(Create, Read, Update, Delete)작업을 간편하게 수행할 수 있다.
SQL 중심적인 개발에서 객체 중심적인 개발이 가능하다
상속, 연관관계, 객체그래프 탐색 등의 패러다임 불일치 문제를 해결해준다.
유지보수가 쉽다 (기존에는 모든 SQL을 수정했지만 JPA는 필드만 추가하면 된다. SQL은 JPA가 처리함)
관계형 데이터이스는 같은 기능도 벤더마다 사용법이 다른 경우가 많다. 예를 들자면 게시물 페이징처리 쿼리문은 DB마다 달라서 사용법을 각각 배워야 하지만, JPA는 애플리케이션과 DB사이의 추상화된 데이터 접근 계층을 제공해서 애플리케이션이 특정 DB에 종속되지 않는다.
@Entity를 붙여주면 된다. (Entity는 테이블이나 레코드가 될 수 있음)@Entity //Entity class임을 선언
@Table(name="USER_INFO")//매핑될 테이블 이름 지정.
public class UserInfo {
@Id //엔티티 클래스의 주요 식별자(primary key)임을 선언
@GeneratedValue(strategy = GenerationType.IDENTITY) // 식별자 값을 자동으로 생성
@Column(name="seq_no")
private Integer seqNo;
// 해당 엔티티 클래스의 필드가 데이터베이스의 컬럼으로 매핑될 때,
// 해당 컬럼의 제약 조건을 설정하는 어노테이션.
@Column(name="user_name", nullable = false, unique = true)
@Size(min=4, max=10, message="size 4~10")
private String userName;
//getter & setter > lombok 라이브러리에 있는 @Getter / @Setter을 쓰면 자동으로 만들어줌.
}
JpaRepository인터페이스를 상속받아 사용함.
JpaRepository 인터페이스를 상속받기 때문에 따로 구현코드 없이 해당 메서드를 사용할 수 있다.
@Repository
public interface UserInfoRepository extends JpaRepository<UserInfo, Long> {
UserInfo findOneByUserName(String userName); //findOne 하나 find : array
Optional<UserInfo> findByUserName(String userName);
}
application.properties 또는 application.yml파일을 이용하여 JPA설정 정보를 지정.

나는 mysql을 사용했다.
Entity를 사용하는 "비즈니스 로직"을 구현하는 "서비스클래스" 정의.
@Service
@Slf4j
public class UserService {
private final UserInfoRepository userRepository; //인터페이스 주입받아 사용.
public UserService(UserInfoRepository userRepository) {
this.userRepository = userRepository;
}
public String registerUser(UserDTO user){
String clientIp = "";
if(userRepository.findOneByUserName(user.getUserName()) != null)
return ReturnCodes.EXISTS_USER;
userRepository.save(UserInfo.builder()
.userName(user.getUserName())
.regIp(clientIp)
.build());
return "REQUEST_SUCCESS"; //회원가입 성공
}
}
public class UserController {
private final UserService userService;
@PostMapping
public ResponseEntity<String> registerUser(@RequestBody @Valid UserDTO user){
if (userService.registerUser(user).equals("REQUEST_SUCCESS")) { //userService의 registerUser매서드를 호출하고있다.
log.info("User registered successfully: {}", user.getUserName());
return ResponseEntity.ok( "User registered successfully!");
} else {
log.warn("Username already exists: {}", user.getUserName());
return ResponseEntity.badRequest().body("Username "+user.getUserName()+" already exists!");
}
}
}
JPQL을 사용하여 객체를 검색하고 조작하는 등의 작업을 수행할 수 있다.