프로그래밍/Java

intelliJ Springboot + MyBatis + MySQL 셋팅 및 연동(1)

소행성왕자 2023. 8. 18. 13:07

목적 : 쇼핑몰 만들기 위한 기본적인 셋팅을 해본다. 

java 17 버전 사용  -> java 11 로 변경

 java 11 로 변경

 

Selected Dependencies 항목을 모두 체크 해준다.

build.gradle

 

java 11

plugins {
    id 'java'
    id 'war'
    id 'org.springframework.boot' version '2.7.14'
    id 'io.spring.dependency-management' version '1.1.2'
}

group = 'com.naya'
version = '0.0.1-SNAPSHOT'

java {
    sourceCompatibility = '11'
}

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-jdbc'
    implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-web-services'
    implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:2.3.1'
    compileOnly 'org.projectlombok:lombok'
    developmentOnly 'org.springframework.boot:spring-boot-devtools'
    runtimeOnly 'com.mysql:mysql-connector-j'
    runtimeOnly 'org.mariadb.jdbc:mariadb-java-client'
    annotationProcessor 'org.projectlombok:lombok'
    providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testImplementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter-test:2.3.1'
    implementation 'org.bgee.log4jdbc-log4j2:log4jdbc-log4j2-jdbc4.1:1.16'
}

tasks.named('test') {
    useJUnitPlatform()
}

 

 

java 17 

spring boot 버전을 변경해주세요

id 'org.springframework.boot' version '3.0.2'
plugins {
    id 'java'
    id 'war'
    id 'org.springframework.boot' version '3.0.2'
    id 'io.spring.dependency-management' version '1.1.2'
}

group = 'com.naya'
version = '0.0.1-SNAPSHOT'

java {
    sourceCompatibility = '17'
}

configurations {
    compileOnly {
        extendsFrom annotationProcessor
    }
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-jdbc'
    implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-web-services'
    implementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter:3.0.2'
    compileOnly 'org.projectlombok:lombok'
    developmentOnly 'org.springframework.boot:spring-boot-devtools'
    runtimeOnly 'com.mysql:mysql-connector-j'
    runtimeOnly 'org.mariadb.jdbc:mariadb-java-client'
    annotationProcessor 'org.projectlombok:lombok'
    providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testImplementation 'org.mybatis.spring.boot:mybatis-spring-boot-starter-test:3.0.2'
    implementation 'org.bgee.log4jdbc-log4j2:log4jdbc-log4j2-jdbc4.1:1.16'
}

tasks.named('test') {
    useJUnitPlatform()
}

ShopApplication.java 실행

에러발생

Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
2023-08-18T11:18:06.433+09:00 ERROR 46776 --- [  restartedMain] o.s.b.d.LoggingFailureAnalysisReporter   : 

***************************
APPLICATION FAILED TO START
***************************

Description:

Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.

Reason: Failed to determine a suitable driver class


Action:

Consider the following:
If you want an embedded database (H2, HSQL or Derby), please put it on the classpath.
If you have database settings to be loaded from a particular profile you may need to activate it (no profiles are currently active).


Process finished with exit code 0

에러 원인은 데이터 베이스 연결 설정을 해야 한다.

localhost 에 mysql 설치되어 있어야 한다.

src/main/resources/application.properities  

-> 이름 변경

src/main/resources/application.yml

server:
  port: 8080

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/dbname?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Seoul
    username: username
    password: password
    
mybatis:
  mapper-locations: classpath:mapper/**.xml

contorller 패키지 추가 및 TestController.java 추가

TestController.java

package com.naya.shop.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {
    @RequestMapping(value="/", method = RequestMethod.GET)
    public Object test() {
        return "Hello World!";
    }
}

@RestController는 @Controller + ResponseBody 라고 생각하시면 됩니다.

@RequestMapping 은 요청이 들어왔을 때 매핑시켜주는 어노테이션 정도로 일단은 생각해두시면 편할 것 같고, value는 매핑시킬 url패턴이라고 생각하면 됩니다.

지금은 "/" 라고 해놨으니 기본 localhost:8086로 호출을 했을 때 매핑됩니다.

브라우져에서 localhost:8080 확인

Mybatis 설정 및 프로젝트 구조

  • controller
  • dto
  • mapper
  • service
  • resources/mapper

mysql 스키마와 데이터

Dto

TestDto.java

package com.naya.shop.dto;

import lombok.Getter;
import lombok.Setter;

import java.util.Date;

@Getter
@Setter
public class TestDto {
    private int idx;
    private String title;
    private String name;
    private String reg_date;
    private String update_date;
}

Controller

TestController.java

package com.naya.shop.controller;

import com.naya.shop.dto.TestDto;
import com.naya.shop.service.TestService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequiredArgsConstructor
public class TestController {

    private final TestService testService;

    @RequestMapping(value="/", method = RequestMethod.GET)
    public Object test() {
        return "Hello World!";
    }

    @RequestMapping(value = "/user", method = RequestMethod.GET)
    public List<TestDto> getUser() {
        return testService.getUserList();
    }
}

Mapper interface

Mapper 인터페이스만 구현해서 Service에서 바로 사용가능.

TestMapper.java

package com.naya.shop.mapper;

import com.naya.shop.dto.TestDto;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

@Mapper
public interface TestMapper {
    List<TestDto> getUserList();
}

Service

TestService.java  

package com.naya.shop.service;

import com.naya.shop.dto.TestDto;

import java.util.List;

public interface TestService {
    List<TestDto> getUserList();
}

TestServiceImpl.java

package com.naya.shop.service;

import com.naya.shop.dto.TestDto;
import com.naya.shop.mapper.TestMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.List;

@Service
@RequiredArgsConstructor
public class TestServiceImpl implements TestService {

    private final TestMapper testMapper;

    @Override
    public List<TestDto> getUserList() {
        return testMapper.getUserList();
    }
}

resources/mapper

TestMapper.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="com.naya.shop.mapper.TestMapper">

    <select id="getUserList" resultType="com.naya.shop.dto.TestDto">
        SELECT * FROM bbs
    </select>

</mapper>

브라우져 접속 : localhost:8080/user


 

위와 같은 흐름으로 웹 블라우져가 데이터를 요청하면 DB 에서 리턴을 받아 화면에 볼수 있는 것입니다.

큰 틀이니 위 그림을 꼭 기억하세요.

Controller

컨트롤러는 클라이언트의 요청을 받아들이고 해당 요청을 처리하기 위해 서비스와 상호 작용합니다.

package com.naya.shop.controller;

import com.naya.shop.dto.TestDto;
import com.naya.shop.service.TestService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequiredArgsConstructor
public class TestController {

    private final TestService testService;

    @RequestMapping(value="/", method = RequestMethod.GET)
    public Object test() {
        return "Hello World!";
    }

    @RequestMapping(value = "/user", method = RequestMethod.GET)
    public List<TestDto> getUser() {
        return testService.getUserList();
    }
}

controller 에서 Service 를 호출합니다.

return testService.getUserList();

Service

서비스는 비즈니스 로직을 수행하고 컨트롤러에서 받은 요청을 처리합니다.

서비스는 DAO와 상호 작용하여 데이터베이스에서 데이터를 가져오거나 조작합니다.

interface 로 List<TestDto> getUserList() 구현했으니 실제 구현해야겠죠.

 

public interface TestService {
    List<TestDto> getUserList();
}
package com.naya.shop.service;

import com.naya.shop.dto.TestDto;
import com.naya.shop.mapper.TestMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.List;

@Service
@RequiredArgsConstructor
public class TestServiceImpl implements TestService {

    private final TestMapper testMapper;

    @Override
    public List<TestDto> getUserList() {
        return testMapper.getUserList();
    }
}

DAO(Data Access Object)

DAO는 데이터베이스와 직접적으로 상호 작용하는 계층입니다.

데이터베이스에 데이터를 저장하거나 조회하는 역할을 수행합니다.

DB

데이터베이스는 실제 데이터가 저장되는 장소입니다. 서비스와 DAO가 데이터베이스와 상호 작용하여 데이터를 읽고 쓰게 됩니다.

Mapper

마이바티스(Mybais)는 Mapper 인터페이스를 제공합니다. 

우리는 DAO 대신 매퍼를 사용할 것입니다.

mapper를 사용하면 일일이 DAO를 만들지 않고 인터페이스만을 이용해서 좀더 편하게 개발할 수 있습니다.

마이비티스는 자바코드와 SQL문을 분리하여 편리하게 관리하도록 합니다.

SQL문은 *.xml 형식으로 저장합니다.

@Mapper
public interface TestMapper {
    List<TestDto> getUserList();
}

 

@Mapper 어노테이션을 붙이면 Mapper 인터페이스로 인식합니다.

resources/mapper

*.xml 형식의 파일을 만들어 원하는 SQL 문을 작성합니다.

xml 파일에서 중요한것은 아래 3가지 입니다.

  • namespace
  • id
  • resultType 

namespace 는 Mapper 의 전체 경로를 나타냅니다.

id 는 Mapper 인터페이스와 xml 파일을 매칭시키기 위해서 mapper 인터페이스와 같은 이름으로 매치 해줘야 합니다.

@Mapper
public interface TestMapper {
    List<TestDto> getUserList();
}

여기서는 getUserList 입니다.

<?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.naya.shop.mapper.TestMapper">

    <select id="getUserList" resultType="com.naya.shop.dto.TestDto">
        SELECT * FROM bbs
    </select>

</mapper>

resultType 은 SQL문을 실행하고 결과값을 어떤 형식으로 반활할지 나타냅니다. 

여기서는 TestDto 객체로 반환합니다.

DTO

계층 간 데이터 교환을 하기 위해 사용하는 객체로, DTO는 로직을 가지지 않는 순수한 데이터 객체(getter & setter 만 가진 클래스)입니다. DB 필드라 생각하면 되겠습니다.

@Getter
@Setter
public class TestDto {
    private int idx;
    private String title;
    private String name;
    private String reg_date;
    private String update_date;
}