스택
- STS
- Spring Regacy Project
- Java1.8
- Mybatis
- MySQL 5.7
목차
0. 스프링 설치하기
환경 설정하기
- Mybatis와 스프링 연동하기
- Hello Mybatis, Mybatis는 무엇하는 것?
- 왜 Mybatis를 사용하지?
- Mybatis의 구성
- Mybatis 설정
- Mybatis 실제 적용
- Spring lagacy project에 Mybatis 연동하기
설치하고 spring regarcy project 생성하기 오류
어느 블로그를 봐도 제대로된 답을 주는 블로그는 없었다.
에러 내용
building workspace has encountered a problem error during build of project
오류 Detail>>
Errors running builder 'Maven Project Builder' on project 'board'.
Could not calculate build plan: Plugin org.apache.maven.plugins:maven-resources-plugin:2.6 or one of its dependencies could not be resolved: Failed to read artifact descriptor for org.apache.maven.plugins:maven-resources-plugin:jar:2.6
오류 원인
새로 프로젝트를 생성해도 Maven libarary가 생성되지 않는다.
maven-resources-plugin:2.6
- Hello Mybatis, Mybatis는 무엇하는 것인가??
- 객체 지향 언어인 자바의 관계형 데이터베이스 프로그래밍을 좀 더 쉽게 할 수 있게 해주는 프레임워크이다.
- 자바에서는 데이터베이스 프로그래밍을 하기 위해서 JDBC(자바에서 제공하는 데이터베이스 프로그래밍API)를 제공한다.
- JDBC는 Java Database Connectivity의 약자로, 자바로 관계형 데이터베이스를 연결하고, 데이터를 주고받을 수 있는 API를 제공한다.(DriverClass, Connection, PreparedStatement, ResultSet 등..)
Mybatis는 큰 프로젝트에서 그 진위를 발휘하는 것 같다. 일단 내가 간단히 만드는 게시판같은 경우에는 코드의 양이 매우 적고, 유지 관리하기에도 단번에 알아볼 수 있을 정도로 간단한 코드들로 이루어 져있기 때문에 Mybatis를 사용하는 장점인 '애플리케이션 소스코드'와 분리해서 파일로 관리할 수 있기 때문에 SQL 관리가 간편하다는 점. 2) JDBC를 사용하면서 필연적으로 발생하는 코드 반복을 배제할 수 있다는 점. 3) 데이터 접근 속도가 JDBC보다 빠를 수 있다는 점. 을 들 수 있지만, 지금 나의 소규모 토이 프로젝트를 하는데 있어서 이 세가지 장점이 도움이 될거란 생각이 들지 않는다.
이번 토이 프로젝트에서 Mybatis 사용 목적은 Mybatis를 알아가는 목적이다. 고래 잡는 칼로 멸치를 잡는 격이지만, 지 금 고래잡는 칼을 익히면, 다음엔 고래를 잡을 수 있다. 응?ㅋㅋㅋㅋ
실제로! Mybatis를 왜 사용하는지?
Mybatis는 자바로 Database와 연동을 할 때, JDBC 라는 인터페이스를 사용한다. 간단하게 말하면 JDBC를 더 유연하고 쉽게 사용하기 위해서 Mybatis가 Java와 MySQL 사이에서 다리역할을 해준다.
- JDBC만으로 관계형 데이터베이스를 다루는 것은 생산성이 떨어진다고 한다. PreparedStatement와 ResultSet을 이용한 처리가 간단한 설정과 어노테이션으로 해결할 수 있어서 코드량 감소=> 생산성 증가 장점이 있다..
- 성능적인 측면에서도 데이터 접근 속도가 높고, 가져오기 미루기, SQL 줄이는 기법 같은 여러 방식의 데이터를 가져오는 방법이 있다.
- 설계 향상(유지 보수가 쉬움) : 유지보수를 애플리케이션의 소스파일까지 들여다 보면서 SQL문을 수정하거나 변경할 필요없이 Mapper 파일에 등록된 SQL문만 수정해 주면 되므로 유지보수가 간편하다.
- SQL문과 애플리케이션 소스코드로부터 완전 분리가 가능하다. Mybatis를 사용하지 않고 MVC모델로 구현한다면 DAO에 db통신을 통해 데이터를 가져오기 위해서 SQL문을 작성해야 했지만, Mybatis를 사용한다면, Mapper파일에 SQL 코드를 따로 입력해두고 DAO파일에서 필요할 때 SQL문을 골라서 가져다 사용할 수 있다.
- 이식성이 높다.(java, C#, ruby 등)
- 오픈소스이고 무료이다.
Spring lagercy project에 Mybatis 연동하기
1. pom.xml에 Mybatis 등록하기
Mybatis를 연동하기 위해서는 다음과 같이 프로젝트 경로에 있는 pom.xml 에 다음 코드를 추가해 줘야 한다.
Mybatis
- mybatis
- mybatis-spring
- spring-jdbc
- spring-test
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${org.springframework-version}</version>
</dependency>
다음 코드를 pom.xml에 작성하고, 저장하면 프로젝트 내부에 라이브러리가 자동으로 다운로드된다.
2. root-context.xml에 Namespace 등록하기.
src/main/webapp/WEB-INF/spring/root-context.xml 는 스프링 프레임워크 설정 파일이다. 스프링이 사용할 설정을 명시해주는 파일이다. 스프링은 어떤 방식으로 DB통신 을 할 것이고, Mybatis 와는 어떤 방식으로 통신할 것인지 root-context.xml 에 지정해준다. 다음을 추가한다..
* aop
* beans
* context
* jdbc
* mybatis-spring
다음 행위가 뭘 하는 것이냐하면, namespace에 위에 다섯 가지의 namespace를 추가해준 것인데, 이를 추가하는 이유는 설정파일에 다음과 같은 자원을 사용할 것이란 것을 명시해 주는 것이다. 스프링에 aop, beans, context, jdbc, mybatis-스프링이란 자원을 사용한다고 명시하는 것이다. 저걸 지정해 줘야 고래잡이 칼인 Mybatis를 사용할 수 있다.
*주의 : Namespaces탭에서 선택한 체크박스가 없는게 있다면, pom.xml에서 maven 등록을 빼먹은 것이 있는 것이다. 다시확인하기 바란다.
3. 스프링(java)과 MySQL 연결하기.
3-1. DataSource 설정하기
src/main/webapp/WEB-INF/spring/root-context.xml 에 스프링과 데이터베이스 연결을 위해서 다음과 같은 데이터베이스 연결 정보를 작성해 준다.
DataSource 는 보통 데이터베이스 연결과 관련된다. 정확히는 JDBC(java Database Connection)과 연결 정보를 가지고 연결을 처리하는 기능을 가진다. 나는 MySQL과 연동하였기 때문에 MySQL과의 연동 DataSource를 작성하였다.
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/데이터베이스 이름?serverTimezone=UTC"></property>
<property name="username" value="데이터베이스 접속 ID"></property>
<property name="password" value="데이터베이스 접속 PW"></property>
</bean>
4. Mybatis와 MySQL 연결 설정하기
MySQL DataSource를 src/main/webapp/WEB-INF/spring/root-context.xml 에 작성한 것처럼 Mybatis와 MySQL 연결 설정을 해주려면 SqlSessionFactoryBean클래스 를 작성해 줘야 한다. 스프링에 SqlSessionFactory 클래스를 설정하면 SqlSessionFactory 객체를 생성할 수 있게 된다. 그러면, Mybatis가 MySQL과 연결할 수 있고, SQL문을 처리할 수 있게 된다.
/*src/main/webapp/WEB-INF/spring/root-context.xml에 다음을 추가한다.*/
<bean id="sqlsessionfactory" class ="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
</bean>
오탈자에 조심해야 한다. dataSource를 datasource로 대소문자 구분안하면 스프링도 구분없이 오류를 뱉어낸다.
5. 설정 테스트 진행
지금부터는 MySQL에 접근하기 위한 설정이 정상적으로 작동해서 MySQL에 연결이 되는지 테스트를 진행해줘야 한다. 스프링에서는 여러 라이브러리와 설정을 가져다 사용하기 때문에 작은 오타 하나라도 설정이 잘못되면, 스프링이 정상 작동하지 않는다는 것에 주의를 해야한다. 특히 어느 한 기능을 스프링에 추가했다면, 그 기능이 스프링에서 정상 작동하는 지 테스트를 수시로 진행해주는 습관을 들이는 것이 좋다. 그렇지 않고 많은 설정을 테스트 없이 한꺼번에 진행한다면, 오류를 추적해 가는 데 많은 시간을 소비하게 될 것이다. 다행이 스프링에는 테스트를 위한 라이브러리가 존재한다.
spring-test 라이브러리를 사용하여 테스트 할 것이다.
5.1 MySQL에 접속하기 위한JDBC설정이 제대로 이루어 졌는가.
스프링 프로젝트를 생성하면, 여러 파일 구성이 함께 생기지만, test를 위한 파일이 존재한다. src/test/java 하위에 프로젝트 패키지명으로 패키지를 생성하고 Datasourcetest.java 클래스 파일을 생성한다.
MySQL 연동 테스트를 진행하기 위해 Datasourcetest.java에 사용된 어노테이션 .
- @RunWith()
- @ContextConfiguration(locatimons={})
- @Inject
스프링의 DI특성을 나타내는 대표적인 어노테이션이다. Spring bean container에서 DataSource 객체 를 Datasourcetest 클래스에 주입해주는 역할을 한다. 스프링 프로젝트 생성 초기부터 지금 주입되는 DataSource 객체를 알고 있었던 것은 아니다. [위]에 보면 DataSource를 스프링의 설정에 등록해주었다. - @Test
connection 객체 를 생성하고 DataSource 클래스에 getConnection() 메서드를 사용해서 connection 객체의 상태를 출력하는 메소드를 @Test 어노테이션을 통해서 스프링에 알린다.
자주 발생하는 오류.
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataSource' defined in file [C:\workspace-sts-3.9.6.RELEASE\toyBoard\src\main\webapp\WEB-INF\spring\root-context.xml]: Error setting property values; nested exception is org.springframework.beans.PropertyBatchUpdateException; nested PropertyAccessExceptions (1) are:
PropertyAccessException 1: org.springframework.beans.MethodInvocationException: Property 'driverClassName' threw exception; nested exception is java.lang.IllegalStateException: Could not load JDBC driver class [com.mysql.jdbc.Driver]
원인 : pom.xml에 mysql 라이브러리 를 추가하지 않아서 발생하는 문제이다.
해결방법 : pom.xml에 mysql 라이브러리 등록.
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
다음 코드를 실행시키기 위해서 '우클릭 > Run As > JUnit Test' 를 실행시키면,
Loaded JDBC driver: com.mysql.jdbc.Driver
com.mysql.cj.jdbc.ConnectionTmpl@mpl@6a57ae10
두 줄 로그를 보면 MySQL과 연결하는 Connection 객체가 정상적으로 생성된 것을 확인할 수 있고, JDBC가 스프링에 올려진 것을 로그를 통해 확인할 수 있다.
5.2 *_Mybatis *_설정이 제대로 이루어 졌는가.
다음은 Mybatis 설정이 제대로 스프링에서 동작하는지 테스트를 하겠다.
Mybatis는 스프링과도 연결되어 있어야하고, MySQL과 연결되어 있어야 한다.
Mybatis와 MySQL과의 연동은 SqlSessionFactory객체 를 생성하는 것으로 MySQL과의 연결 테스트를 진행한다.
SqlSessionFactory는 Mybatis에게 데이터베이스 연결 및 SQL문 처리를 할 수 있게 해주는 객체이다.
SqlSession은 데이터베이스와의 연결을 담당하는 객체이다.
- 코드로 배우는 스프링 웹 프로젝트(책)
sqlSessionFactory 객체 생성 로그 확인.
testFactory() : org.apache.ibatis.session.defaults.DefaultSqlSessionFactory@5d0bf09b
sqlFactory.openSession() 객체가 만들어짐을 확인.
testSession() : org.apache.ibatis.session.defaults.DefaultSqlSession@6bbe85a8
스프링 MVC 테스트
INFO : org.zerock.web.SampleControllerTest - setup
WARN : org.springframework.web.servlet.PageNotFound - No mapping found for HTTP request with URI [doJSON] in DispatcherServlet with name ''
6. DAO 인터페이스 생성 및 Mybatis Mapper 작성하기
6.1 DAO 인터페이스 생성하기
6.2 Mybatis Mapper 작성하기
스프링이 Mybatis의 Mapper를 인식하게 하기 위해서 root-context.xml에 Mapper의 경로를 잡아준다.
6.3 Mybatis에서 DAO를 이용하면 SqlSessionTemplate를 이용한다.
- SqlSessionTemplate
구현 클래스 작성
memberDAOImple.java
@Repository : DAO를 스프링에 인식시키기 위해 주로 사용하는 어노테이션,
@Repository를 설정하드라도 스프링에서 해당 패키지를 스캔하지 않으면 제대로 스프링의 빈으로 등록되지 않는다.
그래서 root-context.xml에 다음을 추가
<context:component-scan base-package="org.zerock.persistence">
</context:component-scan>
오류 원인
mockMvc.perform(MockMvcRequestBuilders.get("이곳에 들어가는 메소드명"));
get()함수의 파라미터로 들어갈 거면 "/"+"메소드이름" 으로 작성해야 PageNotFound 오류를 일으키지 않는다.
정상 테스트 실행 시
INFO : org.springframework.mock.web.MockServletContext - Initializing Spring FrameworkServlet ''
INFO : org.springframework.test.web.servlet.TestDispatcherServlet - FrameworkServlet '': initialization started
INFO : org.springframework.test.web.servlet.TestDispatcherServlet - FrameworkServlet '': initialization completed in 33 ms
INFO : org.zerock.web.SampleControllerTest - setup.....
INFO : org.zerock.web.SampleControllerTest - bookJSONInfo test....
테스트를 진행하면서 오류가 발생하였다.
1. 오류 내용.
Caused by :
java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'org.apache.ibatis.session.Configuration' for property 'configuration': no matching editors or conversion strategy found
2. 오류 내용.
Caused by :
org.springframework.beans.ConversionNotSupportedException: Failed to convert property value of type 'java.lang.String' to required type 'org.apache.ibatis.session.Configuration' for property 'configuration'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'org.apache.ibatis.session.Configuration' for property 'configuration': no matching editors or conversion strategy found
>> 해결 방법
아래 그래도 코드를 작성해 주어야 한다.! 나는 configLocation이 아닌 configuration으로 써서 위와 같은 오류가 발생하였다.
3. 오류 내용.
public java.lang.String org.zerock.web.SampleController3.doD(org.springframework.ui.Model)
to {[/doC]}: Threr is already 'sampleController2' bean method
public java.lang.String org.zerock.web.SampleController2.doC(java.lang.String) mapped
org.springframework.beans.factory.BeanCreationException : Error creating bean with name 'org.springframework.web.servlet.mvc.method.annotaion..RequestMappingHandlerMapping': Invocation of init method failed; nested exception is java.lang.IllegalStateException : Ambiguous mapping. Cannot map 'sampleController3' method
Caused by :
java.lang.IllegalStateException : Ambiguous mapping. (애매모호한 매핑)Cannot map 'sampleController3' method
public java.lang.String org.zerock.web.SampelController3.doD(org.springframework.ui.Model)
to {[doC]} : There is already 'sampleController2' bean method
public java.lang.String org.zerock.web.SampleController2.doC(java.lang.String) mapped
오류 원인
@RequestMapping()은 특정 URL에 매칭되는 클래스나 메소드임을 명시하는 애노테이션이다.
@RequestMapping("doC")는 doC 메소드를 요청받는 메소드인데, 선언 어노테이션 아래 선언된 메소드는 doD이다.
그래서 위와 같은 오류가 발생했다. @RequestMapping("doD")로 바꿔주면 정상 실행된다.
'spring' 카테고리의 다른 글
[Spring]spring에서 properties 사용하기 (1) | 2020.04.01 |
---|---|
[MacBook]Spring Legacy 프로젝트 생성하고 Tomcat 서버 세팅하기 (6) | 2020.03.28 |
[MacBook]초간단 MacBook에 STS 설치하기 (2) | 2020.03.28 |
[Spring] Annotation 종류와 역할 (0) | 2020.03.17 |
[spring]SVN 프로젝트 받고 안정적으로 Maven 설정하고 관련 라이브러리 받기 (0) | 2020.03.16 |
댓글