이번 과제는 과제 4의 UserController를 Controller, Service, Repository로 3단 분리하는 것이다. 그리고 Reposiroty를 메모리에 저장하는 버전과 DB를 이용하는 버전 두 가지로 만들어 편하게 전환하게 만드는 것이다.

분리 방식 자체는 수업과 다르지 않으므로 코드 위주로 작성하고, 추가적인 내용만 따로 기술한다.

이전 과제 피드백

본격적으로 과제를 진행하기 전에, 과제 4에서 코치님께서

@GetMapping("/fruit/stat")
    public SalesFruitResponse salesFruit(@RequestParam(name = "name") String name) {
        String sql = "SELECT SUM(CASE WHEN is_sold='Y' THEN price ELSE 0 END) AS `sum_y`," +
                " SUM(CASE WHEN is_sold='N' THEN price ELSE 0 END) AS `sum_n`" +
                " FROM fruit_info" +
                " WHERE name = ?" +
                " GROUP BY name";

        return jdbcTemplate.queryForObject(sql, (rs,rowNum)->{
            long sales = rs.getLong("sum_y");
            long notSales = rs.getLong("sum_n");
            return new SalesFruitResponse(sales,notSales);
        }, name);

    }

해당 코드의 쿼리 중 case 문 제거하는 것이 좋다고 말씀하셨기 때문에

String sql = "SELECT sum(price) AS `sum` FROM fruit_info WHERE name = ? GROUP BY is_sold";

위 쿼리로 변경하였다. 훨씬 간결해졌다!

하지만 이전에 case로 작성한 이유가 없지는 않았다. rowMapper로 반환 결과를 가져올 때 동일 칼럼의 다른 행에 있는 데이터를 어떻게 동일 객체에 가져갈 수 있을까, 의 고민에 대한 답이 case 문을 이용해 2행1열 테이블에서 1행2열 테이블로 변형하는 것이었다.

지금 생각해보면 그럴 필요가 전혀 없었다.

List<Long> sales = jdbcTemplate.queryForList(sql, Long.class);
SalesFruitResponse salesFruitResponse = new SalesFruitResponse(sales.get(0),sales.get(1) );

쿼리문의 결과가 1열만 나올 때, queryForList 함수를 통해 반환 데이터를 List로 가져올 수 있었다.

queryForList(sql문, list로 받아올 타입)

그 후 get()으로 편리하게 가져왔다.