springboot 개발을 할 때 늘 mybatis를 사용하여 mapper.xml에 SQL쿼리를 작성해 database 로직을 구현했었다.
언제부턴가 JPA라는 말이 자주 들려오고 있는데, 이제야 테스트를 해본다.
JPA(Java Persistence API)와 mybatis와 비교하자면
먼저 Mybatis 는 SQL자체로 xml 파일을 분리할 수 있으며, 복잡한 쿼리 작성의 장점이 있지만,
간단한 쿼리들을 많이 작성하여 코드가 길어지는 단점이 있다.
JPA 는 CRUD 메소드가 이미 정의되어있어 sql을 직접 구현할 필요가 없기 때문에 소스코드의 양이 적어지는 점, 또 database 와 연결되어 table 생성을 자동으로 할 수도 있다.
하지만, 복잡한 쿼리의 사용은 JPQL 또는 Query dsl 을 사용하여야 하기때문에 불편할 수 있다.
기존에 사용하던 mybatis의 style은 app과 db가 따로 작성되는 불편함?이 있었다 볼 수 있고
JPA 방식을 사용하면 app과 db가 서로 연결되어 app에서 테이블 정의, 컬럼 정의 등 많은 부분을 구현할 수 있어 좋다.
그렇다고 JPA 방식만 써야하는 건 아니고, 비즈니스 로직에 복잡한 쿼리가 많다면 mybatis를 쓰는게 좋다고한다.
그럼 JPA를 적용해보자.
POM.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
application.properties
필자는 local 에 postgreSQL db를 올렸다.
# postgres db setting
spring.datasource.url: jdbc:postgresql://localhost:5432/yehan
spring.datasource.username: postgres
spring.datasource.password: joon1234!@#$
spring.datasource.show-sql: true
spring.jpa.properties.hibernate.dialect: org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-auto: create
spring.jpa.generate-ddl: true
spring.jpa.properties.hibernate.show_sql: true #콘솔에 SQL을 띄울 것인지
spring.jpa.properties.hibernate.format_sql: true #콘솔에 SQL을 보기 좋게 띄울 것인지
logging.level.org.hibernate.SQL: debug
logging.level.org.hibernate.type: trace
Entity 정의
테스트용 테이블은 간단히 User 정보를 담는다.
table name : user_tbl
Long Id(PK), email, password
컬럼을 가지도록 정의했다.
@Getter
@Entity(name = "user_tbl") // 사용할 테이블명
@NoArgsConstructor // 생성자 자동 완성(Lombok필요)
@AllArgsConstructor
public class User {
@Id // PK를 가지는 변수를 뜻함 필수
@GeneratedValue(strategy = GenerationType.IDENTITY) // Id 값을 어떻게 생성할지 전략을 지정 AUTO 도 있음
private Long id;
@Column(length = 100, nullable = false, unique = true) // @Column : 선택형 선언, DB컬럼명과 현재변수명을 다르게 할 때 사용
private String email;
@Column(length = 300, nullable = false)
private String password;
}
JpaRepository 정의
기본이 되는 사항(CRUD)은 자동으로 생성되어 있으며,
추가로 커스텀 쿼리를 생성해본다.(ex: Email로 데이터를 검색하는 쿼리)
@Repository
public interface UserRepository extends JpaRepository<User, Long>{
// 커스텀 쿼리 사용방법
@Query(value = "select * from user_tbl where email = :email", nativeQuery=true)
List<User> searchEmail(@Param("email") String email);
}
Service 정의
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
public List<User> getUsers() {
return userRepository.findAll();
}
public List<User> getSearchEmail(String email) {
return userRepository.searchEmail(email);
}
public User addUser(User user) {
return userRepository.save(user);
}
public User updateUser(User user) {
return userRepository.save(user);
}
public void deleteUser(Long id) {
userRepository.deleteById(id);
}
}
Controller 정의
@Slf4j
@RestController
@RequestMapping("/user")
public class UserController{
@Autowired
UserService userService;
// 전체 조회
@GetMapping
public ResponseEntity<List<User>> index() {
ResponseEntity<List<User>> res;
res = new ResponseEntity<List<User>>(userService.getUsers(), HttpStatus.OK);
return res;
}
// 단일 조회
@GetMapping("/{email}")
public ResponseEntity<List<User>> searchEmail(@PathVariable String email) throws Exception {
ResponseEntity<List<User>> res;
res = new ResponseEntity<List<User>>(userService.getSearchEmail(email), HttpStatus.OK);
return res;
}
// 등록
@PostMapping
public ResponseEntity<User> addUser(@RequestBody User user) throws Exception{
ResponseEntity<User> res;
res = new ResponseEntity<User>(userService.addUser(user), HttpStatus.OK);
return res;
}
// 수정
@PutMapping
public ResponseEntity<User> updateUser(@RequestBody User user) throws Exception{
ResponseEntity<User> res;
res = new ResponseEntity<User>(userService.updateUser(user), HttpStatus.OK);
return res;
}
// 삭제
@DeleteMapping("/{id}")
public ResponseEntity<ApiException> deleteUser(@PathVariable Long id) throws Exception{
ResponseEntity<ApiException> res = new ResponseEntity<ApiException>(HttpStatus.OK);
userService.deleteUser(id);
return res;
}
}
폴더구조
Entity : /com/mtp/auth/entity/User.java
JpaRepogitory : /com/mtp/auth/repository/UserRepository.java
Service : /com/mtp/auth/service/UserService.java
Controller : /com/mtp/auth/controller/UserController.java
나머지는 테스트하고 있는 부분이라 무시해라
테스트
유저등록
유저수정
유저목록
유저검색(email)
유저삭제
이렇게 JPA 테스트를 해보았다!
끝!
'개발' 카테고리의 다른 글
[Springboot] Authorization Code 방식의 인증구현 (Spring Security 2.5.2) (0) | 2022.08.04 |
---|---|
[Springboot] swagger 3.0 설정 (0) | 2022.08.04 |
[Springboot] CSRF Token 설정 시 Postman 테스트 방법(Spring Security) (0) | 2022.08.04 |