새프로젝트에서 실습한다면 (포트번호 설정을 유의 할것!)
application properties에 server.port:10001과 같이 바꿔줄것! (주석은 #을 사용한다.)
[JDBC datasource]
커넥션 풀을 도와주는 hikari를 통해서 설정할 예정!
커넥션풀과 마이바티스를 사용할 예정이며, 커넥션풀에서는 datasource [url, username, pw등의 필드가 있다.] 라는것이 필요!
위와 같이 작성해주나 이렇게만 해주면 실행이 되지 않는다 추후에 더 추가적인 설정이 필요하다.
그러므로 드라이버 설정이 잘되어있는지 확인은 아래의 주석으로 작성하여 실행해보고 오류가 없으면 다음단계로 넘어간다. 오류시 드라이버 설정을 다시 확인 해보아야한다. (주로 오타일 확률도 있으니.... 확인 또 확인)
Mapper라는 인터페이스 생성
.java에 mapper인터페이스의 경로와 쿼리문이 작성된 xml 파일의 경로를 이어주어 자동으로 실행되게 해줄것이다.
※ 마이바티스의 목적은 자바단과 쿼리단을 분리하기위함! (.xml의 파일을 .java의 파일과 연동을 해주어야 한다.)
-> JSP에서는 컨트롤러단에서 SqlSessionFactory를 만들어서 했지만 이번 스프링 부트에서는 SqlSessionFactory관련 설정을 따로 만들어서 관리한다! (결국 Mapper인터페이스와 쿼리가 적혀있는 .xml파일을 자동으로연결시켜 준다!)
=> 설정시 필요사항!
1. 설정시 필요한 Mapper인터페이스와 .xml의 경로 (Mapper인터페이스를 만들고 그 경로를 자바파일로 지정)
2. 위의 경로로 Sqlsession이 자동으로 만들어지게 설정!
결과물 확인이 제일 쉬운 시간을 뽑기 위해 mapper라는 패키지를 만들고, TimeMapper라는 인터페이스 파일을 아래와 같이 만들어준다.(인터페이스인 이유는 쿼리문 결과가 늘 달라지기 때문에 결과를 받아온 후(주입을 받으면서) 객체구현을 해야하기 때문)
매핑을 위해 어노테이션 설정 해주어야 한다. @Mapping (xml에 있는 아이디를 연결해주는 역할!)
시간을 받아오기 위해 메소드 하나를 사용한다. (추상메소드 : 구현 되지 않은 메소드)
★★★★★
xml에서 셀렉트를 한 쿼리문의 id의 값과 getTime 즉, 실행 메소드와 이름이 동일해야 매핑이 가능해진다.
(JSP에서 마이바티스를 했다면 이해하기 수월하다)
또한 xml에서 nameSpace[ (member.getid();)이었을때 사용한 member ] 에 선언한 TimeMapper의 경로를 넣어주어 매핑을 시킬수 있도록 설정한다. => 경로는 맨윗줄의 pakage 경로이다.
아래의 사진과 같이 mybatis패키지와 MyBatisCoinfig.java 파일을 만들어 준다.
※설정에 관련된 파일은 어노테이션을 정확히 붙여주어야 Spring이 인식할 수 있다.
(똑같은 자바 클래스 일지라도, 설정에 관련된 파일들은 어노테이션을 정확히 지정해줘야 스프링이 이 파일은 설정파일이구나? 라고 이해할 수 있다) → @Configuration을 지정
MyBatisConfig에서 인터페이스의 경로와 xml의 경로를 알아야 맵핑을 할 수 있다.
(이 설정 파일은 ApplicationContext가 아니기 때문에 해당 경로에 있는걸 Bean으로 등록 시키기 위해선 이 설정파일이 직접 스캔해야한다.) -> @MapperScan에 경로를 지정해 준다. => mapper라는 클래스에서 Mapper라고 지정한것 다 가지고와 라는 뜻
여기의 Config파일이 applicationContext의 역할을 대신하고 있다. (하지만 진짜는 Config안에서 applicationContext를 직접 불러서 사용해야한다. -> 그러면 Bean을 등록할 수 있다.)
그러므로 ApplicationContext를 직접 선언하고, 주입을 해야한다. (경로가 바뀌면 안되므로 생성자 주입방식을 사용한다.)
=> 이 파일이 ApplicationContext의 역할을 대신해주어야 하기 때문!
스프링 컨테이너에 이 ApplicationContext를 주입해달라고 해야하기 때문에 주입을 시키는 어노테이션을 붙여준다.
(단, ApplicationContext는 주소가 바뀌면 안되기 때문에(초기화가 또 일어나면 안된다.) @Autowired보다는 @RequireArgsConstructor를 사용해주자!)
원래는 주석으로 되어있는 경로이지만 우리는 커넥션 풀을 사용할 hikari를 통하기 때문에 경로 설정을 추가적으로 해주어야 한다.
히카리의 경로를 지정해서 받아오며 받아진 config는 hikariConfig의 객체로 반환한다. (hikari를 JDBC로 인식시키기 위함!)
★hikariConfig를 실행하면 application properties를 들리고(@ConfigurationProperties라는 어노테이션이 있기 때문이고, prefix로 설정을 해주었기 때문에 application properties에서 spring.datasource.hikari로 시작하는 모든 설정을 가져온다), 위의 경로와 맞는것을 모두 가져와라, 그럼 그 설정을 모두 주입하여 객체로 반환한다. 그 반횐된 값을 datasource에 넣어주면 설정에 맞게 생성이 된다.
HikariConfig는 application properties에 있는 설정을 가져오기 위해서 만든것!, 그 설정을 dataSource의 필드에 맵핑에서 넣고(설정한 정보들이 들어감) , 이설정이 SqlSessionFactory로 가야하는데 직접 설정을 할 수 없으니 SqlSessionFactoryBean을 선언하여 설정하고 xml의 경로를 받아서 넣어주면 된다.
(SqlSessionFactoryBean : SqlSessionFactory를 만들기 전에 설정해줄수 있는 객체)
xml 만들기 (mapper디렉토리를 먼저 만들고, 그안에 xml파일을 만든다. xml파일이 따로 없기 때문에 File을 만들고 확장자를 xml로 해주면 된다.)
디렉토리로 mapper라는 폴더 만들기! (xml이 들어갈 위치이다.) 이를 SessionFactoryBean에 경로를 지정해준다.)
classpath*:/mapper/*.xml로 사용해야 mapper에 있는 모든 xml을 가져올수 있고, 모든 xml을 가져오기 위해 classpath뒤에 *를 붙여주어야 한다. 그리고 applicationContext.getResource(단수)에 모든 xml(복수)이 들어가기때문에 applicationContext.getResources (복수)로 꼭 선언해야 한다.
※ 경로에서 xml을 가져오는것은 applicationContext가 리소스를 가져올수 있기 때문에 applicationContext.getResources()메소드를 사용하여 경로를 지정해준다.(복수 확인!)
그다음에 SqlSessionFactory를 만드는데 여기서 new를 하면 지금까지 한 설정을 넣을 수 없다!
sqlSessionFactoryBean에서 설정내용을 넣어놓은 Object를 받아온다.
카멜표기법이아닐수도 있기 때문에 한번 내용을 변경해주고 시작한다.
★익셉션이 문제가 생길것이기 때문에 전체 Exception이 아닌 IOException만 잡아주고, 팩토시 설정에서 문제 생기는 것은 try - catch문으로 잡아준다. (제대로 됐다면 Factory를 반환하고, 안됐으면 null을 반환한다.)
생성 했으니 테스트 해보자! 이렇게 작성하고 hikari가 인식을 못하는 오류를 추가로 해결하자!
아직도 이오류가 날것이다! 오류를 해결해보자!
url을 모른다고 오류가 나온다! 이유는 factory를 만들때 사용하는 모든 메소드들을 applicationContext가 모르기 때문!
각 메도스마다 @Bean을 선언해준다.
이제 설정을 마쳤으니 테스트를 해보자!
MyBatisConfigTest파일에서 testSqlSession에서 추가로 작성하고 테스트 해보자!
(Connection을 테스트 할때는 Statement로 테스트해보자!)
실행하고 아래의 출력문을 확인하면 된다.
여기서의 세션 커넥션에서는 Proxy라는 단어가 있는데 이거는 AOP할때 추가로 설명할 예정이다.
+) com.example.ex01.mapper.TimeMapper.java 로 다시 돌아와서 여기의 인터페이스는 구현이 되어있지 않다.
여기에서 구현되어있지 않은 인터페이스는 SQL문의 결과가 구현을 해준다. (xml 파일을 연동해서 사용하면 쿼리에 대한 결과가 구현을 해준다. - 위의 getTime()메소드를 실행하면 쿼리가 실행되고 그 쿼리의 결과가 이 인터페이스를 구현해준다.)
-> 하지만 xml이 필요하지 않을정도로 쿼리가 간단하다면 어노테이션으로 자동 주입시켜 사용이 가능하다. (그러나 xml을 사용하는것을 추천한다.)
※ 주의할 점! 쿼리의 결과와 메소드의 리턴타입이 동일해야 한다. (여기서는 Date타입이지만 String도 먹기 때문에 문제없다.)
이 내용도 테스트 해보자!
테스트라는것을 알리기 위해 @SpringBootTest어노테이션을 붙이고, 출력을 하기위해 @Slf4j를 붙여준다.
getTime()을 사용하기위해 TimeMapper를 선언하고 주입을 주기위해 @Autowired를 붙여준다.
테스트를 진행하면 아래와 같은 결과가 나온다.
@Select~... 의 어노테이션 없이 사용하려면 resources.mapper.TimeMapper.xml을 만들고 그안에 아래의 소스를 작성하면 미리 작성한 MyBatisConfig.java에 넣어 놓은 경로와 매칭이 되어 연결이 되고 xml안에 작성한 쿼리문의 결과가 인터페이스를 구현해준다.
위의 갈색영역은 select 태그의 영역이다. 여기서 주석은 <!-- -->이 아니라 데이터 베이스의 주석인 /**/로 작성해야 한다.
★ 여기서 이 동작이 안된다면 target.classes.mapper안에 xml 파일 빌드 되어 있는지 확인해보자!
-> 안되어 있다면 porm.xml에서 맨마지막 build 태그에 강제로 xml을 넣어줄수 있다.
위치는 <build> 안에, <plugins> 밖에 작성해야하고, 아래와 같이 작성해주면 된다.
이것을 작성하면 우측에 업데이트 하라는 버튼이 나오고 눌러서 업데이트 해준다.
의미는 여러가지 리소스 파일을 빌드할때 main에서 .xml로 끝나는거 찾아라, 리소스에서 .xml, .properties, .setting 관련 파일이 있으면 전부 찾아서 빌드해라! (강제 명령어!)
'프로그래밍 공부 > Spring-Boot' 카테고리의 다른 글
[lesson] Spring - REST (0) | 2023.01.10 |
---|---|
[작성][Error] 메소드 오버라이딩때 Throw문 동작 안됨 (0) | 2022.05.10 |
[lesson] Spring - @ [어노테이션] (0) | 2022.02.04 |
[lesson] Spring-boot - 프로젝트 생성 및 의존성 주입(DI) (0) | 2021.10.06 |
[lesson] Spring-boot - 프레임 워크 (0) | 2021.10.06 |