보라코딩

스프링부트 spring mvc 기본 구조 (MyBatis, Oracle DB 연동) 본문

코딩/Spring

스프링부트 spring mvc 기본 구조 (MyBatis, Oracle DB 연동)

new 보라 2023. 5. 19. 15:17

 

java

 

 

 

 

com/tastemate/controller/StroreController

 

store부분을 맡아서 StoreController.java를 생성했다.

controller에서는 service를 @autowired

 

 

package com.tastemate.controller;

import com.tastemate.domain.StoreVO;
import com.tastemate.service.StoreService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.List;

@Controller
@RequestMapping("/store/*")
public class StoreController {

@Autowired
private StoreService service;


public String get(Model model){

List<StoreVO> storeVO = service.store_get();

model.addAttribute("storeList", storeVO);

return "/store/list";
}

}

 

 

 

 

 

com/tastemate/domain/StoreVO

 

DB 확인만 하기 위해 간단하게 만들었다.

@Data 어노테이션 사용시 toString, 생성자, getter setter 모두 해결됨

 

package com.tastemate.domain;

import lombok.Data;

@Data
public class StoreVO {

private int storeIdx;
private String name;


}

 

 

 

 

 

 

 

 

com/tastemate/mapper/StoreService 

 

서비스에서는 mapper을 @autowired 하였다.

 

package com.tastemate.service;

import com.tastemate.domain.StoreVO;
import com.tastemate.mapper.StoreMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class StoreService {

@Autowired
private StoreMapper mapper;


public List<StoreVO> store_get() {

List<StoreVO> storeList = mapper.store_getList();

return storeList;
}
}

 

 

 

 

 

 

 

com/tastemate/mapper/StoreMapper   (인터페이스!!!)

 

package com.tastemate.mapper;

import com.tastemate.domain.StoreVO;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

@Mapper
public interface StoreMapper {


public List<StoreVO> store_getList();



}

 

 

 

 

 

 

application.properties

 

 

 

url과 username, password는 알맞게 바꿔주기

 

# Setting for Oracle
spring.datasource.driver-class-name=oracle.jdbc.driver.OracleDriver
spring.datasource.url=jdbc:oracle:thin:@localhost:1521/xe
spring.datasource.username=mystudy
spring.datasource.password=mystudypw

# XML location
mybatis.mapper-locations=classpath:mappers/*.xml

#MYBATIS
mybatis.type-aliases-package=com.tastemate.domain
mybatis.configuration.map-underscore-to-camel-case=true

 

 

스프링부트의 Thymeleaf 템플릿 결과는 캐싱하는 것이 디폴트 값이다.

즉, 개발할 때 Thymeleaf를 수정하고 브라우저를 새로고침하면 바로 반영이 되지 않는다.

따라서 개발을 할 때에는 false로 해 주는 것이 재시작  없이 새로고침만으로 반영되게 하는 것이 편하다.

spring.thymeleaf.cache=false

 

 

 

 

 

 

 

resources 내 mapper.xml

 

 

 

 

 

 

 

 

resources/com/tastemate/mapper/StoreMapper.xml

 

mapper.xml 생성필요

이때 이름은 위에 인터페이스로 만든 mapper와 이름 동일하게 해준다.

 

우선 select로 list 가져오는 것만!

 

<?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="com.tastemate.mapper.StoreMapper">

<select id="store_getList" resultType="com.tastemate.domain.StoreVO">
select * from store
</select>

</mapper>

 

id를 mapper 인터페이스와 동일하게 해야함!!!

 

 

 

 

 

 

 

 

view 화면

 

resources/templates/store/list.html

 

 

templates 에 view 파일을 생성해준다.

내 경우는 store 밑에 list.html을 만들어주었다.

 

 

그래서 앞에 controller에서 아래와 같은 어노테이션을 사용했었다.

 

@RequestMapping("/store/*")

@GetMapping("/list")

 

 

 

 

 

 

list.html 파일의 경우

맨위에 이렇게 써주면 타임리프로 사용가능!

 

<!DOCTYPE html>
<html lagn="ko"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">

 

 

타임리프로 잘 가져올 수 있는지만 확인해보았다.

 

<!DOCTYPE html>
<html lagn="ko"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">

<th:block th:replace="header_footer/header :: headerFragment"></th:block>


<head>
<meta charset="UTF-8">
<title>store list</title>
</head>
<body>

<div>
<h5 th:text="${storeList}"></h5>
</div>


<div th:each="storeVO : ${storeList}">
<span th:text="${storeVO.storeIdx} + ' & ' + ${storeVO.name}"></span>
</div>


<th:block th:replace="header_footer/footer :: footerFragment"></th:block>

</body>
</html>

 

 

 

header.html

 

<html lagn="ko" xmlns:th="http://www.thymeleaf.org">
<!--headerFragment 선언-->
<div th:fragment="headerFragment">

<!doctype html>
<html lang="ko">

<head>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">

<!-- Bootstrap CSS -->
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet">

<style>
.navbar {
background-color: #fff;
box-shadow: 0 0.5px 0 0 #dee2e6;
}

.navbar-brand,
.nav-link {
color: #343a40;
}

.navbar .navbar-brand {
font-weight: 600;
}

.navbar .navbar-nav .nav-link {
font-weight: 500;
}

.navbar .btn-outline-dark {
margin-left: auto;
}
</style>

<title>TasteMate</title>
</head>

<body>

<nav class="navbar navbar-expand-lg navbar-light">
<a class="navbar-brand" href="#">TasteMate</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNav"
aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item active">
<a class="nav-link" href="#">커뮤니티</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">맛집</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">내강의장</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">꿀팁</a>
</li>
</ul>
<form class="form-inline mx-auto">
<input class="form-control mr-sm-2" type="search" placeholder="검색" aria-label="Search">
<button class="btn btn-outline-dark my-2 my-sm-0" type="submit">검색</button>
</form>
<div class="ml-auto">
<button class="btn btn-outline-dark ml-2" type="button">회원가입</button>
<button class="btn btn-outline-dark ml-2" type="button">로그인</button>
</div>
</div>
</nav>

 

 

 

 

footer.html

 

<html lagn="ko" xmlns:th="http://www.thymeleaf.org">
<!--footerFragment 선언-->
<div th:fragment="footerFragment">

<!-- Footer -->
<footer class="page-footer font-small blue pt-4" style="background-color: #f8f9fa; border-top: 0.5px solid #dee2e6;">

<!-- Footer Links -->
<div class="container text-center text-md-left mt-5">

<!-- Grid row -->
<div class="row mt-3">

<!-- Grid column -->
<div class="col-md-3 col-lg-4 col-xl-3 mx-auto mb-4">

<!-- Content -->
<h6 class="text-uppercase font-weight-bold">TasteMate</h6>
<hr class="deep-purple accent-2 mb-4 mt-0 d-inline-block mx-auto" style="width: 60px;">
<p>Find friends, enjoy food. This is the TasteMate community. Let's enjoy it together.</p>

</div>
<!-- Grid column -->

<!-- Grid column -->
<div class="col-md-2 col-lg-2 col-xl-2 mx-auto mb-4">

<!-- Links -->
<h6 class="text-uppercase font-weight-bold">Products</h6>
<p>
<a href="#!">커뮤니티</a>
</p>
<p>
<a href="#!">맛집</a>
</p>
<p>
<a href="#!">내강의장</a>
</p>
<p>
<a href="#!">꿀팁</a>
</p>

</div>
<!-- Grid column -->

<!-- Grid column -->
<div class="col-md-3 col-lg-2 col-xl-2 mx-auto mb-4">

<!-- Links -->
<h6 class="text-uppercase font-weight-bold">Useful links</h6>
<p>
<a href="#!">Your Account</a>
</p>
<p>
<a href="#!">Become an Affiliate</a>
</p>
<p>
<a href="#!">Shipping Rates</a>
</p>
<p>
<a href="#!">Help</a>
</p>

</div>
<!-- Grid column -->

<!-- Grid column -->
<div class="col-md-4 col-lg-3 col-xl-3 mx-auto mb-md-0 mb-4">

<!-- Links -->
<h6 class="text-uppercase font-weight-bold">Contact</h6>
<p>
<i class="fas fa-home mr-3"></i> New York, NY 10012, US</p>
<p>
<i class="fas fa-envelope mr-3"></i> info@example.com</p>
<p>
<i class="fas fa-phone mr-3"></i> + 01 234 567 88</p>
<p>
<i class="fas fa-print mr-3"></i> + 01 234 567 89</p>

</div>
<!-- Grid column -->

</div>
<!-- Grid row -->

</div>
<!-- Footer Links -->

<hr>

<!-- Call to action -->
<ul class="list-unstyled list-inline text-center py-2">
<li class="list-inline-item">
<h5 class="mb-1">Register for free</h5>
</li>
<li class="list-inline-item">
<a href="#!" class="btn btn-outline-dark">Sign up!</a>
</li>
</ul>
<!-- Call to action -->

<hr>

<!-- Social buttons -->
<ul class="list-unstyled list-inline text-center">
<li class="list-inline-item">
<a class="btn-floating btn-fb mx-1" href="#!">
<i class="fab fa-facebook-f"> </i>
</a>
</li>
<li class="list-inline-item">
<a class="btn-floating btn-tw mx-1" href="#!">
<i class="fab fa-twitter"> </i>
</a>
</li>
<li class="list-inline-item">
<a class="btn-floating btn-gplus mx-1" href="#!">
<i class="fab fa-google-plus-g"> </i>
</a>
</li>
<li class="list-inline-item">
<a class="btn-floating btn-li mx-1" href="#!">
<i class="fab fa-linkedin-in"> </i>
</a>
</li>
<li class="list-inline-item">
<a class="btn-floating btn-dribbble mx-1" href="#!">
<i class="fab fa-dribbble"> </i>
</a>
</li>
</ul>
<!-- Social buttons -->

<hr>

<!-- Copyright -->
<div class="text-center py-3">
© 2023 TasteMate Inc.
</div>
<!-- Copyright -->

</footer>
<!-- Footer -->


<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
</body>

</html>

 

 

 

 


 

 

 

 

 

다음 참고하면 좋은 글 :)

 

 

스프링부트 게시판 CRU (타임리프 사용)

READ BoardController @Autowired private BoardService service; @GetMapping("/list") public String getList(Model model){ List boardList = service.board_getList(); model.addAttribute("boardList", boardList); return "/board/list"; } @GetMapping({"/get", "/upda

boracoding.tistory.com