반응형

hello.hellospring.domain이라는 이름으로 새로운 패키지를 생성했다.

그리고 domain 패키지에 Member라는 이름의 클래스를 생성했다.

여기서 id는 임의의 값인데, 데이터 베이스든 데이터에 저장할 때 사용하는 단순 시퀀스로 정해지는 임의의 값이다.
고객이 정하는 id가 아니라 데이터를 구분하기 위해서 시스템이 저장하는 id값이다.

그리고 name은 이름이다.

getter, setter를 만들어 준다.

 

그리고 이번에는 회원 리포지토리 인터페이스를 만들자.

먼저, 패키지를 만들자. 이름은 hello.hellospring.repository로 생성했다.

그리고, MemberRepository 라는 이름의 인터페이스를 만들었다.

 

기능을 만들 것인데,

save를 만든다. 회원을 저장하면, 저장된 회원이 반환된다.

Optional<Member> findById(Long id); 라고 해서, 앞서 생성헀던 id로 회원을 찾는 것을 만들 것이다.

그리고 Optional<Mamber> findByName(String name); 은 name으로 회원을 찾는 기능이다.

List<Member> findAll(); 기능은 지금까지 저장된 모든 회원 리스트를 반환해준다.

Optional은 findById 혹은 findByName을 가져오는데 이것이 Null일 수 도 있는데, 이때 Null을 처리하는 방법중에,
Null을 그대로 반환하는 것보다 Optional 이라는 것으로 감싸서 반환하는 방법을 선호한다. java8에 들어가 있는 기능이다.

 

자, 각 기능을 선언했으므로 이제 구현체를 만들어야 한다.

MemoryMemberRepository 라는 이름의 클래스를 생성했다.

implements MemberRepository를 해준다.


그리고 option + enter 키를 눌러서 MemberRepository의 추상 메서드를 오버라이딩 한다.

이렇게 간편하게 불러올 수 있다.

이제 구현을 해보자.

먼저, save를 할 때, 저장을 어딘가에는 해야 할 것이다.
Map자료구조를 이용해보자. key는 회원의 아이디이므로 Long 타입,  그리고 value는 Member 타입으로 정의한다.
그리고 store라는 참조변수를 만들고, new HashMap<>();을 해준다.
실무에서는 이렇게 공유되는 변수일 때는 동시성 문제가 있을 수 있기 때문에 ConcurrentHashMap(컨커런트 해시맵)을 사용해야 하는데, 예제에서는 단순하게 HashMap을 사용하도록 하겠다.

그리고 sequence를 만들어주는데, sequence는 단순하게 0, 1, 2 이런식으로 ket값을 생성해 주는 것이라고 보면 된다.
이것 또한 실무에서는 Long 보다는 동시성 문제를 고려해서 Atomic Long을 사용해야 하는데, 이 예제에서는 단순하게 Long을 이용하도록 하겠다.

그리고, member.setId(++sequence); 로 시스템이 정해주는 id를 지정해준다. 이렇게 id를 세팅하고,
store에 저장을 한다. map에 저장이 될 것이다.
그리고 저장된 결과를 반환한다.

 

findById는 store에서 꺼내면 된다.
store.get(id);를 하면 된다.그런데 만약에 이 결과가 없으면 어떻게 될까?
없으면 null일 것이다.
과거에는 null을 반환했지만,
요즈음에는 null이 반환 될 가능성이 있으면, Option 이라는 것으로 감싼다.
optional.ofNullable(store.get(id)) 이라고 하면,
store.get(id)가 null이어도, 감쌀수 있다.
감싸서 반환해주면 클라이언트에서 무언가를 할 수 있다.
뭘 할 수 있는지에 대해서는 뒤에서 알아보도록 하자.

 

findByName은 Java의 람다를 이용해서 구현해보자.

return store.values().stream()

 은 루프로 계속 돌린다.

.filter(member -> member.getName().equals(name))

람다를 사용하는데, member에서 member.getName()이 여기에 파라미터로 넘어온 name이랑 같은지 확인한다.

.findAny();

같은 경우에만 필터링이 되고, 그중에서 그냥 찾으면, 반환 하는 것이다.
findAny()는 그냥 하나라도 찾는 것이다.

이것의 결과가 Optional로 반환이 된다.

그러면, Map에서 loop를 다 돌면서 하나라도 찾아지면 개를 그냥 반환해버리는 것이다.
그런데, loop를 끝까지 돌았는데 찾아지는게 없으면 optional에 null이 포함이 되서 반환된다.

 

findAll은 new ArrayList<>(store.values()); 를 반환해 주면 된다.


store에 있는 valuse가 Member들이다.


즉, Member들이 쭉 반환이 된다.

 

간단하게 구현을 마쳤다.

이제, 이것들이 제대로 동작을 하는지 검증을 해봐야 한다.

동작을 검증하는 좋은 방법이 테스트 케이스 작성을 하는 것이다.

다음시간에는 테스트 케이스를 작성 해보도록 하겠다.

 

반응형