Java/JDBC 와 Reflection 적용

직접 만든 JDBC Template 팀 프로젝트에 적용해보기 (절망 ver)

김관현 2024. 8. 6. 20:46

 

 

 

https://khan-0103.tistory.com/24

 

Reflection 으로 JDBC Template 구현해보기 (행복 ver)

데브코스 백엔드 1기 첫번째 팀 프로젝트(토이 프로젝트지만..)를 진행하게 되었다 대충 주제는 'JDBC 를 이용해서 간단한 프로젝트 만들기!' 였다 결국엔 JDBC우리가 ORM 기술을 사용하든 SQL Mapper

khan-0103.tistory.com

 

 

여기서 만든 JDBC Template 조무사를 팀 토이 프로젝트에 적용해보았다

 

처음엔 설렘 반, 두려움 반이었으나 30분정도가 지나고 난 후 절망 99% 로 바뀌게 되었다

 

내가 만든 Utility 클래스(쿼리를 객체로 맵핑, 삽입) 에는 여러가지 문제점이 있었다

 

내가 느끼기에 치명적이었던 문제 순서대로 설명하겠다

 

 

1. Enum 타입은 맵핑하지 못한다 (사전 Test 부족)  

혼자 테스트를 해보았을 때 바보같이 Enum 타입 조회를 고려하지 않았다

 

Date 조회 및 삽입, Enum 타입 삽입까지 정상적으로 동작하였지만

제일 자주 사용하는 조회에서 Enum 타입이 맵핑되지 않는 이슈가 생겨버렸다

 

문제의 원인은 ResultSet 에 있었다!

ResultSet.getObject() 로 데이터를 받아올 때 Enum 타입의 경우 String 으로 받아오게 된다!!

 

결국 Enum 타입인 경우 따로 형변환을 해주어야 했다

 

 

2. 객체가 쿼리에 종속(?)된다

내가 작성한 코드는 객체가 쿼리의 영향을 매우 크게 받는다

 

예를 들어, 쿼리가

"select name, age, hire_date from actor" 인 경우에

객체가 name, age, hire_date 를 제외한 다른 값을 더 가지고 있게 된다면 에러가 생긴다!!

 

내가 직접 코드를 테스트할 때는 대수롭지 않게 느꼈었지만 팀원들이 그 기능을 사용하게 되었을 때 이러한 문제는 정말 크리티컬하게 느껴졌다

 

직접 작성한 나조차도 자주 에러가 나는데 오늘 처음 이 메서드들을 본 팀원들은 얼마나 난처하였을까

 

물론 이러한 문제는 준호님의 아이디어로 해결되었다

(맵핑 과정에서 필드로 인한 예외 발생 시 try - catch 로 잡고 무시해버림)

 

 

3. 결국 어찌되었든 오늘 처음 본 메서드이다

문서화는 도움을 줄 뿐, 문제를 해결할 수 없다!!!

 

팀원들 입장에서 이러한 제약조건을 가진 기능은 오히려 족쇄처럼 느껴질 수 있다

 

낯선 기능, 낯선 메서드, 낯선 매개변수, 낯선 반환값 등등...

제약 조건이 너무나도 많은 이런 기능을 팀 프로젝트에서 적용하는게 과연 옳은가? 라는 생각이 너무나도 늦게 들었던 것 같다

 

편리함을 위해 만들었던 기능이 오히려 편의성을 해치고 있는 느낌을 지울 수 없었다

 

협업과 개인 업무간의 간극이 매우 큼을 깨닫게 되었다

단순히 코드를 줄였다고, 신기한 혹은 어려운 기능을 사용한 것은 '좋은 코드'를 작성하는 것에 전혀 도움을 주지 않는다 

 

 

 

개선점 (스프링 데이터 jpa)

준호님의 코드를 본 후 떠오른 아이디어이다

 

Repository 에서 필요로 하는 기능들은 대부분 정해져있다고 생각한다 (완벽히 고정되어 있지는 않지만)

마치 우리가 스프링 데이터 jpa 를 사용할 때 implement 한 번으로 엄청난 편의성을 누리듯, 이러한 기능을 구현할 수 있지 않을까 하는 생각이 들었다

 

우선, Repository 인터페이스를 하나 만드는 것이다

 

그리고 그 인터페이스에 default 를 사용하여 우리가 필요로 하는 대부분의 기능들을 미리 구현을 해버리는 것이다

(제네릭과 리플렉션을 적절히 활용한다면 크게 어려운 구현일 것 같지는 않다)

 

그리고 우리가 Repository 가 필요로 하게 되었을 때, 구현해놓은 Repository 인터페이스를 implement 하면

다른 메서드를 추가하거나, 오버라이드 하지 않더라도 대부분의 기능을 사용할 수 있게 된다!

 

물론 쿼리 부분은 조금 손을 봐야할 것 같다 (동적으로 객체에 맞게 쿼리 작성하는 기능)

 

나중에 여유가 생기면 개선된 버전의 코드를 공유하겠다