5/9 개발일기
스프링 부트로 옮겨타면서 기본적으로 셋업해두었던 것들을 다시 다 갈아엎었다. 스프링 부트의 장점은 이미 기본 설정들이 모두 패키징되어 있어서 건드릴 게 없다는 건데.. 뭐 web.xml 같은게 없어서 확실히 손은 덜 가긴 하지만 익숙치가 않아서 오랜 시간이 걸린다.
스프링 부트는 다른 DB 플랫폼들을 많이 지원하지만 Mybatis 는 지원하지 않는다. 그래서 개인적으로 셋팅해주어야 한다. 여기에서 오랜 시간이 걸렸다. 예제들은 꽤 있었지만 내가 이해를 못하는게 가장 큰 걸림돌이었다. =_= 식당개 삼년이면 라면도 끓인다고.. 어쨌든 계속 보면서 오류를 접하니, 조금씩 조금씩 눈이 트인다. 고생고생한 스프링 부트 + Mybatis 연동은, 이전에 스프링 셋팅할 때 따라했던던 블로그로부터 큰 도움을 받았다.
1. pom.xml 에 mybatis/oracle 디펜던시 추가
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.0</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</version>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc14</artifactId>
<version>10.2.0.4.0</version>
</dependency>
2. application.properties 파일에 DB 연결 정보 삽입
#Database
spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
spring.datasource.url=jdbc:oracle:thin:@000.000.000.000:port:SID
spring.datasource.username=username
spring.datasource.password=password
3. Mapper.xml 파일 생성
쿼리를 xml에 담아주면 된다.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="sampleMapper">
<select id="selectBoardList" parameterType="hashmap" resultType="hashmap">
<![CDATA[
SELECT
*
FROM
SAMPLE_BOARD
WHERE
ROWNUM <= 10
]]>
</select>
</mapper>
4. Database configuration 파일 생성
이 부분에서 아래 링크로부터 도움을 많이 받았다. 1~2야 뭐 그냥 복+붙하면 되니까 쉬웠는데 Spring boot 예제는 대체로 configruation 파일을 class로 설정해놔서 개념이 헷갈렸다. Database configuration class파일에, 아래 링크 블로그에서 설명하고 있는 context-mapper.xml 내용을 작성해야 한다.
SqlSession 연결부를 정의하고, mybatis의 query 를 담은 mapper.xml 파일의 위치를 지정해주어야 하는 것이다. 위 블로그에는 xml 파일로 예제가 나와있는데 이것을 참고하여 class 파일로 전환했다. 코드는 아래와 같다.
@Configuration
public class DatabaseConfig {
@Bean
public SqlSessionFactory sqlSessionFatory(DataSource datasource) throws Exception{
SqlSessionFactoryBean sqlSessionFactory = new SqlSessionFactoryBean();
sqlSessionFactory.setDataSource(datasource);
sqlSessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:/mappers/*.xml"));
return (SqlSessionFactory) sqlSessionFactory.getObject();
}
@Bean
public SqlSessionTemplate sqlSession(SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
5. Common\AbstractDAO.java 생성
이건 위 링크 블로그의 예제를 그대로 복+붙 했다.
6. Controller-Service-Mapper 생성
아마 기존의 DAO를 Spring boot에서는 Mapper 로 다루는 지, spring boot 예제를 찾아봤을 때 많이들 Mapper로 네이밍하여 쓰길래 나도 BoardMapper.java 라고 네이밍을 했다. (소스는 링크한 블로그의 예제 DAO와 똑같다)
BoardController.java
@Controller
public class BoardController {
@Autowired
BoardService boardService;
@RequestMapping(value="/board/list")
public String selectBoardList(Model model){
List<Map<String,Object>> resultList = boardService.selectBoardList();
model.addAttribute("list", resultList);
return "board";
}
}
BoardService.java
@Service
public class BoardService {
@Autowired
BoardMapper boardMapper;
public List<Map<String,Object>> selectBoardList(){
List<Map<String, Object>> resultList = boardMapper.selectBoardList();
return resultList;
}
}
BoardMapper.java
@Repository("boardMapper")
public class BoardMapper extends AbstractDAO {
public List<Map<String, Object>> selectBoardList(){
return (List<Map<String, Object>>)selectList("sampleMapper.selectBoardList");
}
}
board.jsp
<body>
<H2>공지사항</H2>
<c:choose>
<c:when test="${fn:length(list) > 0}">
<div class="panel-group" id="accordion" role="tablist"
aria-multiselectable="true">
<c:forEach items="${list }" var="row" varStatus="status">
<div class="panel panel-default">
<div class="panel-heading" role="tab" id="headingOne">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion"
href="#collapse${status.index}" aria-expanded="true"
aria-controls="collapseOne">
${row.TITLE }
</a>
</h4>
</div>
<div id="collapse${status.index}"
class="${status.index eq 0 ? 'panel-collapse collapse in':'panel-collapse collapse ${i}'}" role="tabpanel" aria-labelledby="headingOne">
<div class="panel-body">
<c:out escapeXml="false"
value="${fn:replace(row.CONTENT,ENTER,'<br>')}" />
</div>
</div>
</div>
</c:forEach>
</div>
</c:when>
</c:choose>
</body>
부트스트랩 적용 예제라 다소 소스가 복잡하다. 위 jsp는 부트스트랩 아코디언으로 게시물을 출력하기 위해 만들어진 소스다. jsp 소스 설명은 아래 링크 참고.