이전 포스트에 이어 Spring Boot에서 JPA/Hibernate를 사용하여 도메인 객체를 삽입하고, 조회하는 테스트를 진행합니다.
도메인 객체는 이전 포스트에서 생성한
User
객체를 사용합니다.
User API를 작성하여, 웹 기반으로 데이터 삽입, 조회 기능을 구현합니다.
@Repository
public interface UserRepository extends JpaRepository<User, String> {
List<User> findAll();
User findById(Long id);
User save(User user);
}
@Repository
: Repository 빈으로 등록될 수 있도록 지정JpaRepository
: JPA 레포지토리를 상속받아 사용findAll()
, findByName()
, save()
@Service
public class UserService {
@Autowired
private UserRepository userRepository;
public List<User> retrieveAllUser() {
return userRepository.findAll();
}
public User retrieveUser(Long userId) {
return userRepository.findById(userId);
}
public User registerUser(User user) {
return userRepository.save(user);
}
}
@Service
: Service 빈으로 등록될 수 있도록 지정@Autowired
: 빈 등록된 객체 주입retrieveAllUser()
, registerUser()
@RestController
@RequestMapping("/api/v1/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping(value="")
public List<User> getAllUsers() {
return userService.retrieveAllUsers();
}
@GetMapping(value="/{user_id}")
public User getUser(@PathVariable("user_id") Long userId) {
return userService.retrieveUser(userId);
}
@PostMapping(value="")
public User createUser(@RequestBody User user) {
return userService.registerUser(user);
}
}
@RestController
: Controller 빈으로 등록될 수 있도록 지정@RestController
를 사용 시 각 메서드의 응답이 자동으로 @ResponseBody
가 적용되어 View가 아닌 HTTP Body로 응답@RequestMapping
: 요청을 받을 URL 경로를 설정@GetMapping
, @PostMapping
: @RequestMapping
를 대체하여, Method가 적용되어 있는 URL Mapping Annotation@PathVariable
: URL 경로로 전달된 값을 사용하기 위한 AnnotationSpring Boot에서는
spring-boot-starter-web
을 사용하면 Jackson 라이브러리가 기본 포함되어 있습니다.
또한, 대부분의 환경 설정은 코드로 구현됩니다.
@Configuration
public class JacksonConfigurer {
@Bean
public ObjectMapper objectMapper() {
return Jackson2ObjectMapperBuilder.json()
.modules(new JavaTimeModule())
.propertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE)
.featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
.featuresToEnable(SerializationFeature.WRAP_ROOT_VALUE)
.featuresToEnable(MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS)
.build();
}
}
@Configuration
: Spring boot 실행 시 환경 설정에 사용될 수 있도록 지정JavaTimeModule()
: 자바 시간 모듈 추가PropertyNamingStrategy.SNAKE_CASE
: 객체->JSON 변환 시 camelCase를 snake_case로 변환SerializationFeature.WRITE_DATES_AS_TIMESTAMPS
: Datetime 기록시 Epoch 시간으로 기록되는 기능 해제SerializationFeature.WRAP_ROOT_VALUE
: 도메인 클래스 이름을 JSON 객체의 root 이름으로 사용하도록 설정MapperFeature.ACCEPT_CASE_INSENSITIVE_ENUMS
: Enum 타입의 필드 값에 대해서 대/소문자 구분하지 않도록 설정@Entity
@Table
@Getter
@Setter
@JsonPropertyOrder({
"id",
"email",
"password",
"name",
"birth",
"cellPhone",
"gender"
})
@JsonRootName("user")
public class User {
@Id
@Column(name = "user_id", nullable = false)
@GeneratedValue(strategy = GenerationType.IDENTITY)
@JsonProperty("user_id")
private Long id;
@Column(nullable = false, length = 50)
private String email;
@Column(nullable = false, length = 20)
private String password;
@Column(nullable = false, length = 20)
private String name;
@Column(name = "birthday")
@JsonProperty("birthday")
@JsonFormat(pattern = "yyyy-MM-dd")
private LocalDate birth;
@Column(name = "cell_phone", nullable = false, length = 20)
private String cellPhone;
@Enumerated(EnumType.STRING)
@Column(nullable = false, columnDefinition = "enum('FEMALE', 'MALE')")
private Gender gender;
}
@JsonPropertyOrder
: JSON 변환 시 출력될 프로퍼티 순서 지정@JsonRootName
: JSON 객체의 root 이름 지정@JsonProperty
: 필드명 대신 출력할 프로퍼티 이름 지정@JsonFormat
: JSON 값을 받거나, 출력할 때 Date 타입에 대한 포멧 지정@JsonRootName("users")
public class Users extends ArrayList<User> {
}
List<User>
-> Users
로 반환 값 변경API 클라이언트 도구인 Postman을 사용하여 테스트 하였습니다.
샘플로 삽입된 cURL 코드를 사용하면 Postman에 바로 삽입할 수 있습니다.
curl -X POST http://localhost:8080/api/v1/users \
-H 'Content-type':'application/json' \
-d \
'{
"name": "graceful",
"email": "grace@wisestudy.com",
"password": "temp",
"birthday": "2020-06-16",
"cell_phone": "010-0001-0001",
"gender": "female"
}'
curl -X GET http://localhost:8080/api/v1/users \
-H 'Content-type':'application/json'