아니지 않을까... 비즈니스 로직이 복잡하다고 해서 SQL이 복잡해 질 필요는 없다.

재고 마감 로직을 생각해보자. 모든 창고에 들어있는 모든 상품들의 전일 재고량, 금일 입고량, 금일 출고량을 가져와서 금일 재고량을 계산한다고 치자. 이걸 가지도 또 상품 카테고리 별로 묶고 창고 별로 묶어서 집계를 내야 하는데.. 일단은 그 전 단계까지만 해보자.
Location - Inventory
Item - Inventory
Item - InvIn
Item - InvOut
Item - InvDailyClosing
이렇게 관계가 맺어져 있으니 SQL로 join을 하던 sub select를 하던 어떻게든 SQL 한방으로 어떤 창고에 있는 어떤 상품의 '전일 재고량', '금일 입고량', '금일 출고량'을 한방에 가져올 수 있을 것 같다.
근데 난 그렇게 하지 않는다. 사실 그렇게 복잡한걸 만들지도 못한다. 만들라면 공부해가면서 만들겠지만 무지 오래 걸릴 것 같다. 그래서 난 그냥 자바 코드로 SQL을 대신한다.
        dao.delelteAllAt(today);
        for(Location location : locationDao.getAll()) {
            // 모든 상품 마다
            for(Item item : itemDao.getAll()){
                // 전일 재고량 조사
                double qtyStart = inventoryDao.getQtyOf(yesterday(today), item, location);
                // 금일 입고량 조사
                double qtyIn = invInDao.getQtyOf(today, item, location);
                // 금일 출고량 조사
                double qtyOut = invOutDao.getQtyOf(today, item, location);
                // 금일 재고량 계산
                double qtyEnd = qtyStart + qtyIn - qtyOut;
               나머진 생략...
            }
        }
즉 이런식으로 짠다. 굵은 글씨 부분은 DAO test를 해서 해당 기능이 내가 원한대로 동작하는지 일일히 확인해다. DBUnit을 사용해서 테스트용 데이터를 넣고 저 기능을 실행해보는 방식이다. 이렇게 구현하니까 상당히 마음이 놓인다. 저걸 만약 한방에 SQL로 구현했다던지.. 테스트 없이 구현했다면.. 글쎄.... 그렇겐 못했을 것 같다.
암튼 이래서.. 복잡한 로직을 처리하는 DAO 코드라 할지라도 단순해진다. 이런걸 디바이드 앤 퀀쿼 라고 하던가.. 몰겠다. 머라하든.
    public double getQtyOf(Date date, Item item, Location location) {
        Object result = getSession().createQuery("select sum(qty) from InvIn where date = :date and item = :item and location = :location group by item")
                .setDate("date", DateUtils.getDateOnly(date))
                .setEntity("item", item)
                .setEntity("location", location)
                .uniqueResult();
        if(result == null)
            return 0.0;
        return (Double) result;
    }
대충 이정도 코드가 생기는데.. 이정도야 뭐.. 초간단 SQL 수준 아닌가..
이렇게 짜면 걱정되는게.. 성능인데... DB에 자주 다녀올수록 더 많은 부하가 생기는건 사실이지만 어차피 복잡한 쿼리 자체도 join 여러번 하면서 부하가 생길테니.. SQL 도사가 아닌 이상 차라리 성능을 조금 포기하고 유지 보수 가능하고 알아보기 쉬운 코드로 나눠서 작성하는게 더 좋치 않을까 싶다.