[코프링] Kopring 시작해보기

최준호·2022년 8월 29일
0

코프링

목록 보기
2/3
post-thumbnail

📗 Kotlin + Spring

kopring으로 프로젝트를 생성하면 된다.

나의 경우 Spring intializer에서 다음과 같이 프로젝트를 생성했다. restdocs를 추가했었으나 오류가 나더라... 어차피 지금 당장 쓸건 아니니 우선 제외시켜놨다.

아 그리고 참고로 vscode의 경우 kotlin + gradle을 지원하지 않고 있다... 언젠가 해줄지 모르지만 아직 해주지 않으니 intellij를 써야한다.

✍ Controller

📄 Controller

@RestController
@RequestMapping("/v1")
class HelloController {
    @GetMapping("/hello")
    fun hello(): String{
        return "hello"
    }
}

컨트롤러를 테스트용으로 만들어보았다.

결과 값이 잘 나온다.

그럼 객체로 반환은 어떻게 하는지 궁금해졌다. 객체로 반환시켜보자.

class MemberDto (
    val name: String,
    val email: String,
    val phone: String? =null,
)

먼저 MemberDto를 먼저 생성했다. data class로 만들어도 된다.

@RestController
@RequestMapping("/v1")
class HelloController {
    @GetMapping("/hello")
    fun hello(): String{
        return "hello"
    }

    @GetMapping("/user")
    fun user(): ResponseEntity<Any> {
        val user = MemberDto("juno", "juno@mail.com")
        return ResponseEntity.ok(user)
    }
}

controller의 경우 다음과 같이 작성해주면 된다. Any의 경우 반환할 class를 직접 지정해주는게 더 좋을거 같긴하다만 귀찮아서 Any로 써봤다.

Java에서 해봤다면 kotlin 문법만 알면 금방 적을할 수 있었다.

✍ JPA 연동하기

📄 JPA yml 설정

spring:
  h2:
    console:
      enabled: true
      settings:
        web-allow-others: true
      path: /h2-console
  jpa:
    hibernate:
      ddl-auto: create
    show-sql: true
  datasource:
    driver-class-name: org.h2.Driver
    url: jdbc:h2:mem:testdb
    username: sa
    password:

JPA와 H2를 사용하여 DB를 생성해주고 enabled 해준다. 서버를 실행해서 확인해보자!

이 화면이 나오면 잘 설정된 것이다.

✍ Domain

📄 Entity

@Entity
@Table(name = "MEMBER")
class MemberEntity (
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    val id: Long,
    var name: String,
    val email: String,
    val phone: String? =null,
){
    fun changeName(name: String){
        this.name = name
    }
}

📄 Repository

@Repository
interface MemberRepository : JpaRepository<MemberEntity, Long>{
    fun findByName(name: String): Optional<MemberEntity>
}

✍ Service

📄 Service

interface MemberService {
    fun findMember(name: String): Optional<MemberEntity>
}
@Service
class MemberServiceImpl(
    private val memberRepository: MemberRepository,
) : MemberService{
    override fun findMember(name: String): Optional<MemberEntity> {
        return memberRepository.findByName(name)
    }
}

이제 테스트 코드를 통해 확인해보자

✍ 테스트

📄 Service 테스트

@SpringBootTest
class MemberServiceImplTest(
    @Autowired val memberService: MemberService,
    @Autowired val memberRepository: MemberRepository,
){
    @Test
    @DisplayName("member 조회에 성공한다.")
    @Transactional
    fun memberFind(){
        //given
        val member = MemberEntity("juno", "juno@mail.com", "01012341234")
        memberRepository.save(member)
        //when
        val findMember = memberService.findMember("juno").get()
        //then
        assertEquals(findMember.name, member.name)
    }
}

테스트 결과를 보면 insert문과 select 문이 정상적으로 실행되었고 테스트도 정상 실행된것을 확인할 수 있었다.

✍ Controller까지 연결해서 확인

📄 Service

interface MemberService {
    ...
    fun save(memberDto: MemberDto)
}
@Service
class MemberServiceImpl(
	...

    @Transactional
    override fun save(memberDto: MemberDto) {
        memberRepository.save(MemberEntity(memberDto.name, memberDto.email, memberDto.phone))
    }
}

데이터를 넣어야하므로 save를 추가해주었다.

📄 Controller

@RestController
@RequestMapping("/v1/member")
class MemberController (
    private val memberService: MemberService,
){
    @GetMapping("/{name}")
    fun getMember(@PathVariable(value = "name") name: String): ResponseEntity<MemberEntity> {
        return ResponseEntity.ok(memberService.findMember(name).get())
    }

    @PostMapping("")
    fun insertMember(@RequestBody memberDto: MemberDto): ResponseEntity<Any> {
        memberService.save(memberDto)
        return ResponseEntity.status(HttpStatus.CREATED).body("회원가입 완료")
    }
}

다음과 같이 두개의 매핑을 추가해주었고 실행해보자.

✍ 테스트

📄 save

다음과 같이 정상 실행되었고

insert 문도 이쁘게 날아갔다.

또한 우리가 phone은 null을 허용해두었기에 다음과 같이 작성하지 않아도 잘 된다.

📄 findByName

우리가 이전에 만들었던 find도 정상적으로 실행되며

select 문도 이쁘게 날아간다.

profile
코딩을 깔끔하게 하고 싶어하는 초보 개발자 (편하게 글을 쓰기위해 반말체를 사용하고 있습니다! 양해 부탁드려요!) 현재 KakaoVX 근무중입니다!

0개의 댓글