무한루프/개발, 업무

스프링 부트(Spring Boot), 마이바티스(Mybatis), 메이븐(Maven) 백엔드 연동 설정(2)

시원한생맥주 2025. 2. 25. 15:04

스프링 부트(Spring Boot), 마이바티스(Mybatis), 메이븐(Maven) 백엔드 연동 설정(2)

 

1. 프로젝트 생성 및 설정

https://start.spring.io/

 

 

spring initializr 스프링부트 설정
spring initializr 스프링부트 설정

  • 빌드 도구: Maven
  • 언어: Java
  • Spring Boot 버전: 3.4.3
  • 그룹 ID: com.nam.gallery
  • 아티팩트 ID: gallery
  • 패키징: JAR
  • Java 버전: 17
  • 의존성:
    • Spring Web
    • Lombok
    • MyBatis Framework

pom.xml 

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>3.4.2</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.nam</groupId>
	<artifactId>gallery</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>gallery</name>
	<description>gallery project for Spring Boot</description>
	<url/>
	<licenses>
		<license/>
	</licenses>
	<developers>
		<developer/>
	</developers>
	<scm>
		<connection/>
		<developerConnection/>
		<tag/>
		<url/>
	</scm>
	<properties>
		<java.version>17</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.mariadb.jdbc</groupId>
			<artifactId>mariadb-java-client</artifactId>
			<scope>compile</scope>
		</dependency>
		
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		
		<dependency>
	        <groupId>org.mybatis.spring.boot</groupId>
	        <artifactId>mybatis-spring-boot-starter</artifactId>
	        <version>3.0.3</version>
	    </dependency>
	    
	    <!-- HikariCP (기본 데이터베이스 커넥션 풀) -->
	    <dependency>
	        <groupId>com.zaxxer</groupId>
	        <artifactId>HikariCP</artifactId>
	    </dependency>
	    
	    <dependency>
		    <groupId>org.junit.jupiter</groupId>
		    <artifactId>junit-jupiter-api</artifactId>
		    <version>5.11.4</version>  <!-- 최신 버전 확인 후 적용 가능 -->
		    <scope>test</scope>
		</dependency>
		
		<dependency>
		    <groupId>org.junit.jupiter</groupId>
		    <artifactId>junit-jupiter-engine</artifactId>
		    <version>5.11.4</version>
		    <scope>test</scope>
		</dependency>
		
		<dependency>
		    <groupId>com.fasterxml.jackson.core</groupId>
		    <artifactId>jackson-databind</artifactId>
		    <version>2.15.0</version> <!-- 최신 버전 확인 필요 -->
		</dependency>


	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<annotationProcessorPaths>
						<path>
							<groupId>org.projectlombok</groupId>
							<artifactId>lombok</artifactId>
						</path>
					</annotationProcessorPaths>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<configuration>
					<excludes>
						<exclude>
							<groupId>org.projectlombok</groupId>
							<artifactId>lombok</artifactId>
						</exclude>
					</excludes>
				</configuration>
			</plugin>
		</plugins>
	</build>

</project>

2. 주요 프로젝트 구조

com.nam.gallery
├── common
│   ├── ApiResponse.java
│   ├── BaseController.java
│   ├── BaseMapper.java
│   ├── GalleryApplication.java
├── config
│   ├── DatabaseConfig.java
├── controller
│   ├── ItemController.java
├── mapper
│   ├── ItemMapper.java
├── model
│   ├── Item.java
├── service
│   ├── ItemService.java
│   ├── ItemServiceImpl.java

3. 공통 클래스

3.1 ApiResponse<T> (응답 형식 표준화)

package com.nam.gallery.common;

import lombok.Getter;
import lombok.Setter;
import org.springframework.http.HttpStatus;

@Getter
@Setter
public class ApiResponse<T> {
    private int status;  // HTTP 상태 코드
    private String message; // 응답 메시지
    private T data;  // 응답 데이터
    private Object errorDetails; // 에러 세부 정보 (에러 발생 시 포함)

    public ApiResponse() {}

    // 성공 응답 생성
    public static <T> ApiResponse<T> success(T data) {
        ApiResponse<T> response = new ApiResponse<>();
        response.status = HttpStatus.OK.value();
        response.message = "Success";
        response.data = data;
        response.errorDetails = null; // 에러 상세 정보 없음
        return response;
    }

    // 실패 응답 생성
    public static <T> ApiResponse<T> error(String message, HttpStatus status, Object errorDetails) {
        ApiResponse<T> response = new ApiResponse<>();
        response.status = status.value();
        response.message = message;
        response.data = null;
        response.errorDetails = errorDetails; // 에러 세부 정보 포함
        return response;
    }
}

3.2 BaseController (API 공통 응답 제공)

package com.nam.gallery.common;

import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;

public abstract class BaseController {

    // 성공 응답
    protected <T> ResponseEntity<ApiResponse<T>> success(T data) {
        return ResponseEntity.ok(ApiResponse.success(data));
    }

    // 실패 응답 (기본 메시지만 포함)
    protected ResponseEntity<ApiResponse<Object>> error(String message, HttpStatus status) {
        return ResponseEntity.status(status).body(ApiResponse.error(message, status, null));
    }

    // 실패 응답 (에러 상세 정보 포함)
    protected ResponseEntity<ApiResponse<Object>> error(String message, HttpStatus status, Object errorDetails) {
        return ResponseEntity.status(status).body(ApiResponse.error(message, status, errorDetails));
    }
}

4. MyBatis 설정

4.1 DatabaseConfig.java (HikariCP 데이터베이스 설정)

package com.nam.gallery.config;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.zaxxer.hikari.HikariDataSource;

@Configuration
//@PropertySource("classpath:application.properties") // 프로퍼티 파일에서 설정 값 로드
public class DatabaseConfig {

	@Value("${spring.datasource.url}")
	private String url;

	@Value("${spring.datasource.username}")
	private String username;

	@Value("${spring.datasource.password}")
	private String password;

	@Value("${spring.datasource.driver-class-name}")
	private String driverClassName;

	// HikariCP를 이용한 DataSource Bean 생성
	@Bean
	public DataSource dataSource() {
		HikariDataSource dataSource = new HikariDataSource();
		dataSource.setJdbcUrl(url);
		dataSource.setUsername(username);
		dataSource.setPassword(password);
		dataSource.setDriverClassName(driverClassName);
		dataSource.setMaximumPoolSize(10);
		return dataSource;
	}
}

5. Mapper 계층

5.1 BaseMapper<T> (공통 CRUD 인터페이스)

package com.nam.gallery.common;

import java.util.List;
import java.util.Map;

import org.springframework.stereotype.Repository;

@Repository
public interface BaseMapper<T, ID> {
	T selectOne(Map<String, Object> params);

	List<T> selectList(Map<String, Object> params);

	int insert(T entity);

	int update(T entity);

	int delete(ID id);
}

5.2 ItemMapper (특정 엔티티에 대한 쿼리 인터페이스)

package com.nam.gallery.mapper;

import java.util.List;

import org.apache.ibatis.annotations.Mapper;

import com.nam.gallery.model.Item;

@Mapper
public interface ItemMapper extends BaseMapper<Item>{
    List<Item> getItemList();
    Item findItemById(int id);
}

6. Service 계층

6.1 ItemService.java

package com.nam.gallery.service;

import java.util.List;

import com.nam.gallery.model.Item;

public interface ItemService {
	public List<Item> getItemList();

	public Item findItemById(int id);
}

6.2 ItemServiceImpl.java

package com.nam.gallery.service;

import java.util.HashMap;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.nam.gallery.mapper.ItemMapper;
import com.nam.gallery.model.Item;

@Service
public class ItemServiceImpl implements ItemService {

	@Autowired
	ItemMapper itemMapper;

	public Item getItemById(Long id) {
		HashMap<String, Object> params = new HashMap<>();
		params.put("id", id);
		return itemMapper.selectOne(params);
	}

	public List<Item> getAllItems() {
		return itemMapper.selectList(new HashMap<>());
	}

	public boolean insertItem(Item user) {
		return itemMapper.insert(user) > 0;
	}

	public boolean updateItem(Item user) {
		return itemMapper.update(user) > 0;
	}

	public boolean deleteItem(Long id) {
		return itemMapper.delete(id) > 0;
	}

	@Override
	public List<Item> getItemList() {
		return itemMapper.getItemList();
	}

	@Override
	public Item findItemById(int id) {
		return itemMapper.findItemById(id);
	}
}

7. Controller 계층

7.1 ItemController.java

package com.nam.gallery.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.nam.gallery.common.BaseController;
import com.nam.gallery.service.ItemService;

@RestController
@RequestMapping("/api/item")
public class ItemController extends BaseController {

	@Autowired
	ItemService itemService;

	@GetMapping("/getItemList")
	public ResponseEntity<?> getItemList() {
		return success(itemService.getItemList());
	}

	@GetMapping("/findItemById")
	public ResponseEntity<?> findItemById(@RequestParam int id) {

		return success(itemService.findItemById(id));
	}

}

8. Model

8.1 Item.java

package com.nam.gallery.model;

import lombok.Data;

@Data
public class Item {
	private int id;
	private String name;
	private String imgPath;
	private int price;
	private int discountPer;
}

 

마무리

스프링부트 백엔드 설정 완료
스프링부트 백엔드 설정 완료

 

HikariCP 설정까지 추가..

이렇게 하고 부팅하면 그래도 정상적으로 서버가 올라간다..

휴... 힘들었다...