[Springboot]MariaDB연동하기

Michelle Kim·2024년 5월 23일

Springboot-Java

목록 보기
2/20
post-thumbnail

💚Springboot - MariaDB연동

🐣MariaDB설치

MariaDB설치

🐣DBTest project생성하기

  • Dependencies각각 사진과 같이 추가!
  • generate생성하기!

spring initializr

🐣logback-spring.xml파일 추가 & application.properties코드 추가

1. logback-spring.xml파일 resources에 추가

  • {LOG_PATH}/info_{type}.%d{yyyy-MM-dd}.log --> .log로 바꾸기!
<configuration>
<property name="LOG_PATH" value="./logs"/>
<!--  Appenders  -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<encoder>
<pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] [%thread] %logger %msg%n</pattern>
</encoder>
</appender>
<appender name="INFO_LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<file>${LOG_PATH}/info.log</file>
<append>true</append>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/info_${type}.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>[%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5level] [%thread] %logger %msg%n</pattern>
</encoder>
</appender>
<!--  TRACE > DEBUG > INFO > WARN > ERROR > OFF  -->
<!--  Root Logger  -->
<root level="INFO">
<appender-ref ref="console"/>
<appender-ref ref="INFO_LOG"/>
</root>
</configuration>

2. application.properties코드 추가

  • username과 password는 database에 설정된 이름과 비번으로 바꾸기
  • port번호도 체크해보기
spring.application.name=DBTest
spring.datasource.driverClassName=org.mariadb.jdbc.Driver
spring.datasource.url=jdbc:mariadb://localhost:3306/springboot
spring.datasource.username=root
spring.datasource.password=password
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true

간단 설명

DB 테이블 설계 - @Entity
- 스프링 프레임웍 구동할때 @Entity속성의 객체를 로드해서 DB 테이블로 생성해 준다
물리적인 DB에 데이터를 조작할수 있는 스프링에서 제공하는 기능
- DB를 좀더 체계적으로 조작 - ORM(MyBatis, JPA....) - JPA
- JPA를 사용하려면 JpaRepository 인터페이스를 상속받은 인터페이스가 필요
---------- DB를 조작할수 있는 인터페이스를 제공 ------------------
실제 DB조작이 이루어지는 DAO ( 복잡한(비지니스로직) )
DAO 로직구현할때 필요한게--> 데이터인데.. 데이터를 체계적으로 관리하기 위해서 객체형태로..--> DTO
DTO는 데이터로만 구성된 클래스
-- 필요한 패키지

  • dao
  • dto
  • entity
  • repository

🐣Package, Class, Interface생성하기

👉data/entity/Product.java

[DB테이블이 생성 됨]

  • @Entity
  • @Id
  • @GeneratedValue
  • @Column
  • @CreationTimestamp
package com.example.jpa.data.entity;

import jakarta.persistence.*;
import org.hibernate.annotations.CreationTimestamp;

import java.time.LocalDateTime;

@Entity
public class Product {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long number;
    @Column(nullable = false, unique = true)
    private String name;
    @Column(nullable = false)
    private int price;
    @Column(nullable = false)
    private int stock;
    @CreationTimestamp
    @Column(updatable = false)
    private LocalDateTime createAt;
    private LocalDateTime modifyAt;
}

JpaApplication 실행(run)하면
MariaDB에 product 테이블 생성된다.

👉data/repository/ProductRepository.java (Interface임!)

  • public interface ProductRepository extends JpaRepository<Product, Long> {} : JpaRepository상속받음 (ORM중 하나), <테이블명, pk키 데이터타입>
package com.example.jpa.data.repository;

import com.example.jpa.data.entity.Product;
import org.springframework.data.jpa.repository.JpaRepository;

public interface ProductRepository extends JpaRepository<Product, Long> {
}

👉data/dto/ProductDto.java

import java.time.LocalDateTime;

@Getter
@Setter
@ToString
@AllArgsConstructor

public class ProductDto {
   
    private String name;

    private int price;

    private int stock;
}

👉data/dto/ProductResponseDto.java

package com.example.jpa.data.dto;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@ToString
@AllArgsConstructor
public class ProductResponseDto {
    private Long number;
    private String name;

    private int price;

    private int stock;
}

👉data/dto/ChangeProductNameDto.java

package com.example.jpa.data.dto;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@ToString
@AllArgsConstructor
public class ChangeProductNameDto {
    private Long number;
    private String name;
}

👉data/dao/ProductDao.java

package com.example.jpa.data.dao;

import com.example.jpa.data.dto.ProductDto;
import com.example.jpa.data.entity.Product;

/*
* C : 생성
* R : 조회
* U : 업데이트
* D : 삭제
* */
public interface ProductDao {
    Product insertProduct(Product product);

    Product selectProduct(long number) throws Exception;

    Product updateProductName(long number, String name) throws Exception;

    void deleteProduct(long number) throws Exception;

}

👉data/dao/impl/ProductDaoImpl.java

  • @Component 추가
package com.example.jpa.data.dao.impl;

import com.example.jpa.data.dao.ProductDao;
import com.example.jpa.data.entity.Product;
import com.example.jpa.data.repository.ProductRepository;
import lombok.AllArgsConstructor;

import java.time.LocalDateTime;
import java.util.Optional;

@AllArgsConstructor
@Component

public class ProductDaoImpl implements ProductDao {
    private final ProductRepository productRepository;

    @Override
    public Product insertProduct(Product product) {
        return productRepository.save(product);
    }

    @Override
    public Product selectProduct(long number) throws Exception {
        Optional<Product> selectProduct = productRepository.findById(number);
        if (selectProduct.isPresent()){
            return selectProduct.get();
        }
        throw new Exception();
    }

    // 기존데이터를 가져와서 값을 변경하고 save한다
    @Override
      public Product updateProductName(long number, String name) throws Exception {
          Product product = this.selectProduct(number);
          if(product != null){
              product.setName(name);
              product.setModifyAt(LocalDateTime.now());
              productRepository.save(product);
          }else{
              throw new Exception();
          }
         return product;
      }

    @Override
    public void deleteProduct(long number) throws Exception {
        Product product = this.selectProduct(number);
        productRepository.delete(product);
    }
}

👉 service/ProductService.java (Interface임!)

package com.example.jpa.service;

import com.example.jpa.data.dto.ProductDto;
import com.example.jpa.data.dto.ProductResponseDto;

/*
실제 사용자로부터 데이터를 받고 전달하는 역할
DAO에서는 Entity타입의 데이터를 사용했다면
여기서는 상황에 맞는 데이터 객체 사용
*/
public interface ProductService {
    ProductResponseDto saveProduct(ProductDto productDto);
    ProductResponseDto getProduct(long number);

    ProductResponseDto changeProductName(long number, String name);

    void deleteProduct(long number);
}

👉 service/impl/ProductServiceImpl.java

  • @Service 추가
package com.example.jpa.service.impl;

import com.example.jpa.data.dao.ProductDao;
import com.example.jpa.data.dto.ProductDto;
import com.example.jpa.data.dto.ProductResponseDto;
import com.example.jpa.data.entity.Product;
import com.example.jpa.service.ProductService;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;

@AllArgsConstructor
@Service
public class ProductServiceImpl implements ProductService {
    private final ProductDao productDao;

    @Override
    public ProductResponseDto saveProduct(ProductDto productDto) {
        Product product = new Product();
        product.setName(productDto.getName());
        product.setPrice(productDto.getPrice());
        product.setStock(productDto.getStock());
        Product insertedProduct = productDao.insertProduct(product);
        ProductResponseDto productResponseDto
                = new ProductResponseDto(insertedProduct.getNumber(), insertedProduct.getName(),
                insertedProduct.getPrice(), insertedProduct.getStock());

        return productResponseDto;
    }

    @Override
    public ProductResponseDto getProduct(long number) throws Exception {
        Product product = productDao.selectProduct(number);
        ProductResponseDto productResponseDto
                = new ProductResponseDto(product.getNumber(), product.getName(),
                product.getPrice(), product.getStock());
        return productResponseDto;
    }

    @Override
    public ProductResponseDto changeProductName(long number, String name) throws Exception {
        Product product = productDao.updateProductName(number, name);
        ProductResponseDto productResponseDto
                = new ProductResponseDto(product.getNumber(), product.getName(),
                product.getPrice(), product.getStock());
        return productResponseDto;

    }

    @Override
    public void deleteProduct(long number) throws Exception {
        productDao.deleteProduct(number);

    }
}

👉controller/ProductController.java

  • service/impl/ProductServiceImpl.java: @Service 추가
  • data/dao/impl/ProductDaoImpl.java: @Component 추가
package com.example.jpa.controller;

import com.example.jpa.data.dto.ChangeProductNameDto;
import com.example.jpa.data.dto.ProductDto;
import com.example.jpa.data.dto.ProductResponseDto;
import com.example.jpa.service.ProductService;
import lombok.AllArgsConstructor;
import lombok.SneakyThrows;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/product")
@AllArgsConstructor
public class ProductController {
    private final ProductService productService;

    @SneakyThrows
    @GetMapping
    public ResponseEntity<ProductResponseDto> getProduct(long number) {
        ProductResponseDto productResponseDto =  productResponseDto = productService.getProduct(number);
        return ResponseEntity.status(HttpStatus.OK).body(productResponseDto);
    }

    @PostMapping
    public ResponseEntity<ProductResponseDto> createProduct(
            @RequestBody ProductDto productDto
    ) {
        ProductResponseDto productResponseDto = productService.saveProduct(productDto);
        return ResponseEntity.status(HttpStatus.OK).body(productResponseDto);
    }

    @PutMapping
    public ResponseEntity<String> changeProductName(
            @RequestBody ChangeProductNameDto changeProductNameDto
    ) {
        try {
            ProductResponseDto productResponseDto
                    = productService.changeProductName(changeProductNameDto.getNumber(), changeProductNameDto.getName());
            return ResponseEntity.status(HttpStatus.OK).body(productResponseDto.toString());
        }catch (Exception e){
            return ResponseEntity.status(HttpStatus.OK).body("업데이트도중 에러가 발생했습니다.");
        }

    }

    @SneakyThrows
    @DeleteMapping
    public ResponseEntity<String> deleteProduct(long number) {
        productService.deleteProduct(number);
        return ResponseEntity.status(HttpStatus.OK).body("정상적으로 삭제 되었습니다.");
    }
}

👉pom.xml에 붙이기

SpringDoc OpenAPI Starter WebMVC UI

<!-- https://mvnrepository.com/artifact/org.springdoc/springdoc-openapi-starter-webmvc-ui -->
<dependency>
    <groupId>org.springdoc</groupId>
    <artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
    <version>2.5.0</version>
</dependency>

👉application.properties

  • swaagger-ui custom path 추가
spring.application.name=jpa
spring.datasource.driverClassName=org.mariadb.jdbc.Driver
spring.datasource.url=jdbc:mariadb://localhost:3306/springboot
spring.datasource.username=root
spring.datasource.password=password
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true

# swagger-ui custom path
springdoc.swagger-ui.path=/swagger-ui.html

👉config/SwaggerConfiguration.java

package com.example.jpa.config;

import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Configuration;

@Configuration
@OpenAPIDefinition
@RequiredArgsConstructor
public class SwaggerConfiguration {
}

🐣값들어오는지 확인

  • POST: 값 넣어보기

Swagger-ui

  • MariaDB table 확인해보기
profile
🇬🇧영국대학교)Computer Science학과 졸업 📚Data, AI, Backend 분야에 관심이 많습니다. 👉Email: kimbg9876@gmail.com

0개의 댓글