[AXBoot] MyBatis, 디버깅하기

yesjm·2021년 4월 21일
0

mybatis 파라미터로 String을 넘겼을 때 오류 해결
한건의 데이터만 가져오는것 보완
디버깅 하는 방법
junit 단위 테스트

오전 수업

MyBatis 파라미터로 String을 넘겼을 때 오류 해결

기존 수업에서 <select id="selectBy" resultType="company" parameterType="String" statementType="PREPARED"> 파라미터 타입을 String을 넘겼을 때 오류가 발생해 company 객체를 만들어 전송했다.

자바에서 String은 무조건 오브젝트(객체)로 인식을 하지만, 변수는 하나의 값일 뿐이지 오브젝트의 역할을 하지 못한다.
String, Int, Long등의 오브젝트가 좀 더 다양한 처리를 할 수 있게끔 되어있다.
MyBatis에서 파라미터는 무조건 오브젝트로 받아서 처리하는데, where 문에서 사용하는 명칭이 무조건 오브젝트여야하기 때문이다.

파라미터로 String을 넘기기 위한 작업을 진행한다.

CompanyService.java
selectBy 메소드를 수정하고

    //MyBatis
    public List<Company> selectBy(RequestParams<Company> requestParams) {
        List<Company> companyList = this.companyMapper.selectBy(requestParams.getString("company", ""));
        return companyList;
    }

CompanyMapper.java
Company -> String으로 변경

public interface CompanyMapper extends MyBatisMapper {

    List<Company> selectBy(String company);

CompanyMapper.xml
mybatis안에 where절이 들어가게 되면 오브젝트 객체안의 항목으로만 인식하게 된다. 객체를 찾으려니까 setter, getter가 없다고 에러가 나오게 된다.

where 절을 삭제하고 아래 코드로 수정한다.

    <select id="selectBy" resultType="company" parameterType="String" statementType="PREPARED">
        SELECT
            ID AS id,
            COMPANY_NM AS companyNm,
            CEO AS ceo,
            BIZNO AS bizno,
            TEL AS tel,
            ZIP AS zip,
            ADDRESS AS address,
            ADDRESS_DETAIL AS addressDetail,
            EMAIL AS email,
            REMARK AS remark,
            USE_YN AS useYn
        FROM
            COMPANY_M
        WHERE COMPANY_NM = #{companyName}

수정을 마치면 이전 기능과 같이 작동한다.


다시 수정하기 전 상태로 돌아와서

하나의 객체만 가져오기

하나의 객체만을 가져오는 Swagger 추가를 해보자

아래 코드들을 추가한다.

CompanyController.java
기존의 기능과 겹치기 때문에 RequestMapping의 value는 꼭 변경해 줘야 Swagger에서 기능을 사용할 수 있다.
리스트가 아닌 객체이기 때문에 List<> 관련 문구는 없다.

    @RequestMapping(value = "/MyBatis/view", method = RequestMethod.GET, produces = APPLICATION_JSON)
    @ApiImplicitParam(name = "id", value = "ID", dataType = "Long", paramType = "query")
    public Company view3(RequestParams<Company> requestParams) {
        Company company = companyService.selectOne(requestParams);
        return company;
    }

CompanyService.java

    public Company selectOne(RequestParams<Company> requestParams) {
        return this.companyMapper.selectOne(requestParams.getLong("id",0));
    }

CompanyMapper.java

    Company selectOne(long id);

CompanyMapper.xml

    <select id="selectOne" resultType="company" parameterType="Long" statementType="PREPARED">
        SELECT
            ID AS id,
            COMPANY_NM AS companyNm,
            CEO AS ceo,
            BIZNO AS bizno,
            TEL AS tel,
            ZIP AS zip,
            ADDRESS AS address,
            ADDRESS_DETAIL AS addressDetail,
            EMAIL AS email,
            REMARK AS remark,
            USE_YN AS useYn
        FROM
            COMPANY_M
        WHERE ID = #{id}
    </select>

이 과정을 마치면 새로운 Swagger가 추가된 것을 확인할 수 있고

id값을 입력받아 하나의 객체만 확인할 수 있게 된다.


앞으로 더 집중해야 할건 JPA와 QueryDSL,,

JPA나 QueryDSL의 경우 Swagger에서 동작시켰을 때 자동으로 쿼리문을 생성해서 데이터를 가져오는 것을 확인할 수 있는데

MyBatis는 작성한 쿼리문을 그대로 날리기 때문에 시각적으로 확인하기는 더 좋다.

쿼리문이 복잡해지다보면 사람이 직접 쿼리문을 작성하는 MyBatis가 성능면에서 좋을 수 있지만, JPA나 QueryDSL에 성능적인 문제가 크게 없다는게 보여지고 있으니 잘 선택하자


오후 수업

디버깅

디버깅할 코드 라인에 점을 찍고 디버그 모드(shift+f9)로 실행시킨다.

swagger에서 테스트를 해보면 아래와 같은 화면이 나온다.
C에서 디버깅할때랑 비슷하다.

JUnit 단위 테스트

서비스단의 업무 영역을 단위 테스트의 주 영역으로 한다.
뭔가 github에서 clone한 프로젝트들에는 test 폴더가 없는 듯한 느낌..? 왜인지는 잘 모르겠지만,, 일단 test 폴더를 만들어준다

project structure에서 새로 생성해준다.

테스트 코드를 동작시키려면 사전작업으로 MyBatis와 관련된 코드는 주석처리 해준다. 주석은 다시 없앨 예정인데,, 일단 JUnit 동작시키려면 수정이 필요해서 한것,,,,

테스트 코드 경로는 테스트하고자 하는 파일의 경로와 맞춰주자
좋은 개발자가 되기 위해서는 단위 테스트와는 항상 친하게 지내자!
그렇지 않으면 백발이 될때까지 단순한 코더로 남아있을지도 모른다,,

CompanyServiceTest.java 파일을 생성하고 테스트 코드의 기본 틀을 작성한다.

@Log
@RunWith(SpringRunner.class)
@SpringBootTest(classes = AXBootApplication.class)
public class CompanyServiceTest {

    @Autowired
    private CompanyService companyService;

    @Test
    public void test메소드명(){
        //given : 사전 준비

        //when : 실제 액션

        //then : 결과 확인
    }
}

각 어노테이션에 관한 자세한 설명은 책 61p~

CompanyServiceTest.java

    @Test
    public void testGetQueryDsl(){ //test + test할 메소드명
        //given : 사전 준비
        RequestParams<Company> requestParams = new RequestParams<Company>();
        requestParams.put("company","네이버");
        requestParams.put("ceo","");
        requestParams.put("bizno","");

        //when : 실제 액션
        List<Company> result = this.companyService.getByQueryDsl(requestParams);

        //then : 결과 확인
        assertTrue(result.size() == 1);
    }

결과가 참이면 이런 화면을 만나볼 수 있다.

  • assert는 종류가 많으니 찾아보고 필요한 것을 잘 이용하자

assertTrue(result.size() < 0);으로 변경하면 값이 참이 아니게 된다. assert의 결과가 참이 아닌 경우 프로그램을 실행했을 땐 에러가 발생한다.
조건을 정확하게 줘야 테스트가 성공했다고 볼 수 있으니 신경쓰자

TDD의 항상 실패하는 코드를 먼저 작성하고 -> 일어나지도 않을 것을 채우려고 고민하다가 정작 하려던 목적을 잃어버리고 진도가 안나간다. 하나씩 채워가면서 성공하는 코드로 바꿔가자

profile
yesjm's second brain

0개의 댓글