3. Why JPA?
@Bean
public CommandLineRunner demo(CourseRepository repository) {
return (args) -> {
Course course = new Course("웹 개발의 봄, 스프링","코드 오타쿠");
repository.save(course);
// INSERT INTO COURSE ("ID", 'TITLE', 'TUTOR') VALUES (?, ?, ?);
List<Course> courseList = repository.findAll();
// SELECT * FROM COURSE
for(int i=0 ; i<courseList.size() ; i++){
Course course1 = courseList.get(i);
System.out.println("강의 제목: " + course1.getTitle());
System.out.println("담당 튜터: " + course1.getTutor());
}
};
}
왜 JPA인가!
그냥 자바 개발환경에서 SQL문 작성하면 안됨?
공부해야 할 게 또 늘어나는 건 질색인데..
물론 그래도 된다.
하나도 문제될 거 없다.
여태까지 다들 그렇게 개발 하면서 잘 먹고, 잘 살았다.
try{
conn = ds.getConnection();
String sql = "SELECT num, name, password, subject, content, write_date, write_time, ref, step, lev, read_cnt, child_cnt";
sql += " FROM BOARD ORDER BY ref desc, step asc ";
sql += " LIMIT ? , ?";
pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, WRITING_PER_PAGE * (Integer.parseInt(curPage) -1));
pstmt.setInt(2, WRITING_PER_PAGE);
rs = pstmt.executeQuery();
while(rs.next()){
int num = rs.getInt("num");
String name = rs.getString("name");
String password = rs.getString("password");
String subject = rs.getString("subject");
String content = rs.getString("content");
Date writeDate = rs.getDate("write_date");
Time writeTime = rs.getTime("write_time");
int ref = rs.getInt("ref");
int step = rs.getInt("step");
int lev = rs.getInt("lev");
int readCnt = rs.getInt("read_cnt");
int childCnt = rs.getInt("child_cnt");
BoardDTO writing = new BoardDTO();
writing.setNum(num);
writing.setName(name);
writing.setPassword(password);
writing.setSubject(subject);
writing.setContent(content);
writing.setWriteDate(writeDate);
writing.setWriteTime(writeTime);
writing.setRef(ref);
writing.setStep(step);
writing.setLev(lev);
writing.setReadCnt(readCnt);
writing.setChildCnt(childCnt);
list.add(writing);
}
} catch (Exception e){
e.printStackTrace();
}finally{
try{
if(rs != null) rs.close();
if(pstmt != null) pstmt.close();
if(conn != null) conn.close();
}catch (SQLException e){
e.printStackTrace();
}
}
return list;
}
그냥 좀 지저분해 보일 뿐이다.
그리고 야근이 좀 더 늘어날 뿐이고..
점점 목이 거북이처럼 변해갈 뿐이다.
비 올 때마다 승모근이 살려달라고 비명을 지르는 거 말고 뭐가 더 있겠는가?
...
그러니까 도망칠 수 있을 때, 빨리 도망쳐라.
아직 늦지 않았다.
하지만 도망칠 때 치더라도 JPA를 써야하는 당위성을 먼저 듣고 결정하기 바란다.

try{
conn = ds.getConnection();
String sql = "SELECT num, name, password, subject, content, write_date, write_time, ref, step, lev, read_cnt, child_cnt";
sql += " FROM BOARD ORDER BY ref desc, step asc ";
sql += " LIMIT ? , ?";
(중략)
catch(){
(중략)
}
finally{
(중략)
}
}
자바 교과서 가장 마지막 파트에 나오는 Try ~ Catch 구문이다.
거기에 SQL문을 때려 박아놓는 구조지.
doWhile 처럼 닥치고 try {...} 중괄호 이하를 실행부터 하라는 것이다.
오타가 없다면 특별한 에러 없이 잘 실행이 될 것이다.
그런데 딱 봐도 오타가 있을 것 같지 않읆..?
꼼꼼하게 작업했기 때문에 오타 따위는 존재하지 않는다고 가정을 해보자.
그래도 퇴근하기 전에 최종적으로 로컬 테스트는 해봐야겠지?
으.. 으응???
???
도대체 뭐가 문제일까?
필자도 모른다.
...
모른다고.. ㅡㅡ
예를 들기 위해 올려놓은 사진이지만 본인부터 데미지를 입고 말았다.
차라리 컴파일 에러 같으면 어디서 잘못되었는지 금방 눈에 보인다.
그리고 대가리를 책상에 들이 받으면 끝이지.
하지만 NullPointer이나 IllegalArgs 예외처리는 정말 답이 없다.
디버깅을 해봐도 오류를 발견하기가 쉽지 않다.
어쨌든 오늘도 야근각이라는거지.. ㅋㅋㅋㅋㅋㅋ
필자의 경험상 거의 대부분의 경우에는 SQL문에서 무언가가 잘못된 것이다.
NullPointer Exception만 하더라도 '지칭하는 객체가 보이지 않는걸요?' 라는 식의 예외처리 문구이다.
저게 가끔 일어나는 일 같은가?
웃기지 말아라.
웹 개발을 시작하면 저 화면과 눈싸움 하는 게 절반이다.
미심쩍으면 구글링을 해봐라.
미리견 성님들도 분명 SQL문을 먼저 살펴보라고 조언해줄 것이다.
필자는 분명 글의 서두에서부터 그렇게 말했다.
자바 개발환경에서 SQL문을 쓰는 건 아무 문제가 없다고..
근데 지금 보니까 문제 투성이잖아? 이 찌발럼아!!!
워워.. 진정해라.
정말이다.
IDE에서 SQL문을 쓰는 그 자체는 정말 문제가 없다니까?
야근각이니, 거북목이니, 라운드 숄더니.. 하는 것도 다 농담 따먹기지..
정말로 여러분더러 뺑이나 치라고 그랬겠는가?
문제는 좀 더 구조적인 부분에 있다.
뺑이를 쳤으면 ㅆ발 소스코드를 작성한 필자가 쳤지, 당신들이 쳤겠나?
지금 우리는 웹 / 앱을 개발하기 위해 Java 기반의 IDE를 쓰고 있다.
그리고 좀 있어보이는 말로 그 녀석들을 컴파일러 (Compiler) 라고 퉁쳐서 부른다.
모든 불행은..
이 멍청한 컴파일러가 SQL문을 문자열 (String) 로 인식하는 것에서부터 시작한다.
뭐라고?
문자열이라고 했다.
String sql = "SELECT num, name, password, subject, content, write_date, write_time, ref, step, lev, read_cnt, child_cnt";
sql += " FROM BOARD ORDER BY ref desc, step asc ";
sql += " LIMIT ? , ?";
문제는 자바와 SQL은 서로 아무런 접점이 없는 별개의 언어라는 것이다.
자바는 자바고, SQL은 SQL일 뿐이다.
그러니까 우리가 아무리 폼 잡고 SQL문을 작성해줘도
결국에는 문자열일 뿐이지..
그렇기 때문에 컴파일러 자체적으로 무언가 대책을 강구해야 한다.
DB 서버에서 뭘 할 수 있겠는가?
대책을 세워도 우리 쪽에서 세워야지..
전통적인 해결방안으로는 DB 커넥션 풀을 만들어주는 것이다.
그 기능을 수행하기 위해 xml 파일을 수정하는 과정이 있기는 한데..
굳이 깊이 들어가려고 하지 말아라.
그냥 IDE와 MySQL 사이에서 실시간 통 / 번역을 수행할 컨버터를 만들어주는 게 전부이다.
말은 쉽게 했지만 사실 엄청 번거롭고 귀찮음..
문제는 그렇게 난리법석을 떨어도 저 좆같은 예외처리는 뜨기 마련이라는 거다.
왜냐?
고작 컴파일러에 불과한 IDE에서 인터프리터 (Interpreter) 역활까지 담당해야 하니까!
그래서 앞으로 필자와 함께 JPA를 공부 해보자는 것이다.
JPA는 스프링부트에 들어있는 라이브러리 패키지에 불과하다고 했지?
하지만 희생정신이 뛰어난 이름 모를 개발자 분들이 만든 이 라이브러리 덕분에..
순수하게 자바 언어로만 SQL 기능까지 구축할 수 있는 것이다.
사실 From Java to SQL은 언어체계 자체를 뒤집어버리는 매우 복잡한 작업이라고 할 수 있다.
하지만 JPA는 간결하고, 완벽하다.
간결하다고 했지, 쉽다고 한 적은 없다..
그렇지만 문법구조만 토 달지 않고 준수한다면 사실상 자바에서 파이썬 함수를 쓰는 꼴이다.
repository.save(course);
repository.findAll();
봐라.
한 눈에 봐도 직관적인 것이 세미콜론만 빠지면 영락없는 파이썬 함수같지 않은가?
우리는 이참에 이 녀석을 확실하게 해부 해보려는 것이다.
더 이상의 거북목, 라운드숄더, 승모근 통증은 NAVER...
이제 도망 안갈꺼지?