본문 바로가기
Spring

[Spring-Boot] 기초 - 프로젝트 생성

by BENGGRI 2022. 7. 28.
반응형

Spring boot 프로젝트 생성

 

사용 중

  • jdk 11
  • Maven 3.8.5
  • intellij CE
  • Windows
  • Spring Boot 2.7.2
  • Spring Web
  • Thymeleaf
  • Lombok
  • MariaDB Driver
  • MyBatis Framework

1. Spring initializr 에서 프로젝트 생성

https://start.spring.io/

 

위 링크에 접속해 Spring boot 프로젝트를 생성합니다.

좌측 영역

  • Project - Maven Project
  • Language - Java
  • Spring Boot - 2.7.2 (기본선택) => 자주 변경되니 크게 신경쓰지 않아도 됩니다
  • Project Metadata
    • Group - com.example(기본 설정) => Java의 패키지 이름 규칙을 따라야 함 즉 제어하는 도메인 이름의 반대로 시작해야합니다  ex ) org.apache.maven, org.apache.commons
    • Artifact - demo => 버전 없는 jar파일의 이름으로 특수 문자를 사용하지 않고 소문자로만 작성해야합니다
    • Name - demo
    • Description - Demo project for Spring Boot
    • Package name - com.example.demo
    • Packaging - Jar
    • Java - 11

 

우측 영역(Dependencires) 에서 

  • Spring Web
  • Thymeleaf
  • Lombok
  • MariaDB Driver(JDBC)
  • MyBatis Framework

를 추가한 후 CENERATE 를 클릭하면 demo.zip 파일이 다운로드됩니다

 

 

 

2. Git 에 프로젝트 소스 등록

다운로드된 demo.zip 파일을 압축해제합니다

이런 구조로 압축해제 됩니다

git 에 소스를 등록하기 위해 https://github.com/ 또는 사용하시는 git 페이지에 접속하여 Repository 를 생성합니다

저는 github를 사용하고 있기 때문에 github ui 를 남겼습니다

New 를 클릭하여 새로운 Repository 를 생성합니다

Repository name : demo

Public 말고 Private 을 선택합니다

(누군가에게는 보여주기 부끄럽기 때문입니다)

Create repository 를 클릭하면 repository 생성은 끝입니다

 

생성 후 command 를 이용한 git init 을 할 수 있습니다

우리는 이미 프로젝트가 존재하기 때문에 빨간 네모 박스에 있는 command 를 실행합니다

 

다시 프로젝트 폴더로 이동하여 마우스 오른쪽 클릭 후 Git Bash Here 를 클릭합니다

(Git Bash Here 가 보이지 않는 경우는 https://git-scm.com/downloads로 이동하여 Git 을 설치하세요)

아래 명령어를 순서대로 실행하세요

git init

git remote add origin 깃URL

git branch -M main

git add .

git commit -m "init"

git push orign main

다시 깃 페이지로 돌아가 repository 를 확인해보면 아래 사진과 같이 소스 파일이 올라 간 것을 확인할 수 있습니다

 

 

3. Intellij CE 에서 프로젝트 Import

저는 이미 다른 프로젝트가 있기 때문에 Intellij 의 상단 메뉴에서 프로젝트를 import 하였습니다

URL 에 git url을 복사 붙여넣기 한 후 Clone 을 클릭하면 인증 후 Trust Project, New Window 를 선택하시면 됩니다

 

 

 

4. 프로젝트 기본 설정

 

4-1. 기본 폴더 구조

demo
  src
    main
      java
        com.example.demo
      resources
        application.properties

 

4-2. application.properties 파일 수정

# MariaDB
spring.datasource.url=jdbc:mariadb://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver

# MySQL
#spring.datasource.url=jdbc:mysql://localhost:3306/test
#spring.datasource.username=root
#spring.datasource.password=root
#spring.datasource.driver-class-name=com.mysql.jdbc.Driver

# servlet context
server.servlet.context-path=/
server.servlet.servlet-path=/*
server.port=9090

spring.thymeleaf.cache=true
spring.thymeleaf.view-names=html/*
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html

 

4-3. Intellij Maven Run 설정

intellij 에서 프로젝트 실행을 위해 Run Configuration 을 설정합니다

위 이미지를 순서대로 따라하고 Apply 클릭 후 OK 를 클릭합니다

 

 

5. http://localhost:포트/ 진입 시 노출될 페이지 생성

지금 설정한 대로 Run 을 하고 브라우저에서 http://localhost:포트/ 를 입력할 경우 404 오류가 표시됩니다

진입 후 처음 노출될 페이지를 생성합니다

 

demo
  src
    main
      java
        com.example.demo
          home
            HomeController
          DemoApplication
      resources
        static
        templates
          html
            index.html
        application.properties

 

5-1. HomeController 생성

package com.example.demo.home;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import javax.servlet.http.HttpServletRequest;

@Controller
public class HomeController {

    @RequestMapping(value="/", method= RequestMethod.GET)
    public String index(
        HttpServletRequest request
    ) {
        return "html/index";
    }

}

 

5-2. index.html 생성

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

    <h1>Hello, world!</h1>

</body>
</html>

 

5-3. 프로젝트 재기동

HomeController 와 index.html 을 생성 후 프로젝트를 재기동합니다
다시 브라우저에서 http://localhost:포트/ 를 입력 후 화면을 확인합니다

프로젝트 기본 설정은 끝났습니다

 

6. DB 테이블 생성

CRUD 를 위한 테이블을 생성하겠습니다

별도의 툴 설명은 하지 않지만 Eclipse 플러그인으로 사용할 수 있는 exerd를 추천합니다

(https://www.exerd.com/index.do)

 

CREATE TABLE `code` (
  `group_code` varchar(10) NOT NULL COMMENT '그룹_코드',
  `code` varchar(10) NOT NULL COMMENT '코드',
  `code_name` varchar(100) DEFAULT NULL COMMENT '코드_명',
  `insert_date` datetime DEFAULT current_timestamp() COMMENT '입력_일시',
  `update_date` datetime DEFAULT current_timestamp() COMMENT '수정_일시',
  PRIMARY KEY (`group_code`,`code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 

7. CRUD 페이지 및 기능 생성

 

demo
  src
    main
      java
        com.example.demo
          home
            HomeController
          test
            TestController(신규생성)
            TestService(신규생성)
            TestDao(신규생성)
          DemoApplication
      resources
        static
          mapper
            test
              TestDao.xml(신규생성)
        templates
          html
            index.html(수정)
        application.properties(수정)

 

# MariaDB
spring.datasource.url=jdbc:mariadb://localhost:3306/test?useUnicode=true&amp;characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver

# MySQL
#spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&amp;characterEncoding=utf8
#spring.datasource.username=root
#spring.datasource.password=root
#spring.datasource.driver-class-name=com.mysql.jdbc.Driver

# servlet context
server.servlet.context-path=/
server.servlet.servlet-path=/*
server.port=9090

spring.thymeleaf.cache=true
spring.thymeleaf.view-names=html/*
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html

mybatis.mapper-locations: classpath:/static/mapper/*.xml

server.servlet.encoding.charset=UTF-8
server.servlet.encoding.force=true
server.servlet.encoding.force-response=true

spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
spring.http.encoding.force=true

 

package com.example.demo.test;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.Map;

@RestController
@RequestMapping("test")
public class TestController {

    @Autowired
    private TestService testService;

    @RequestMapping(value="getDataList", method= RequestMethod.POST, produces="application/json; charset=utf8")
    public ResponseEntity getDataList (
        HttpServletRequest request,
        @RequestBody Map<String, Object> prmMap
    ) {
        Map<String, Object> result = testService.getDataList(prmMap);
        return ResponseEntity.ok(result);
    }

    @RequestMapping(value="getData", method= RequestMethod.POST, produces="application/json; charset=utf8")
    public ResponseEntity getData (
        HttpServletRequest request,
        @RequestBody Map<String, Object> prmMap
    ) {
        Map<String, Object> result = testService.getData(prmMap);
        return ResponseEntity.ok(result);
    }

    @RequestMapping(value="insertData", method= RequestMethod.POST, produces="application/json; charset=utf8")
    public ResponseEntity insertData (
        HttpServletRequest request,
        @RequestBody Map<String, Object> prmMap
    ) {
        Map<String, Object> result = testService.insertData(prmMap);
        return ResponseEntity.ok(result);
    }

    @RequestMapping(value="updateData", method= RequestMethod.POST, produces="application/json; charset=utf8")
    public ResponseEntity updateData (
        HttpServletRequest request,
        @RequestBody Map<String, Object> prmMap
    ) {
        Map<String, Object> result = testService.updateData(prmMap);
        return ResponseEntity.ok(result);
    }

    @RequestMapping(value="deleteData", method= RequestMethod.POST, produces="application/json; charset=utf8")
    public ResponseEntity deleteData (
        HttpServletRequest request,
        @RequestBody Map<String, Object> prmMap
    ) {
        Map<String, Object> result = testService.deleteData(prmMap);
        return ResponseEntity.ok(result);
    }

}

 

package com.example.demo.test;

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

import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;

@Service
public class TestService {

    @Autowired
    private TestDao testDao;

    public Map<String, Object> getDataList(Map<String, Object> param) {
        Map<String, Object> result = new HashMap<String, Object>();
        result.put("result", testDao.getDataList(param));
        return result;
    }

    public Map<String, Object> getData(Map<String, Object> param) {
        Map<String, Object> result = new HashMap<String, Object>();
        result.put("result", testDao.getData(param));
        return result;
    }

    public Map<String, Object> insertData(Map<String, Object> param) {
        Map<String, Object> result = new HashMap<String, Object>();
        result.put("result", testDao.insertData(param));
        return result;
        
    }

    public Map<String, Object> updateData(Map<String, Object> param) {
        Map<String, Object> result = new HashMap<String, Object>();
        result.put("result", testDao.updateData(param));
        return result;
    }

    public Map<String, Object> deleteData(Map<String, Object> param) {
        Map<String, Object> result = new HashMap<String, Object>();
        result.put("result", testDao.deleteData(param));
        return result;
        
    }

}

 

package com.example.demo.test;

import org.apache.ibatis.annotations.Mapper;

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

@Mapper
public interface TestDao {

    List<Map<String, Object>> getDataList(Map<String, Object> param);
    Map<String, Object> getData(Map<String, Object> param);
    int insertData(Map<String, Object> param);
    int updateData(Map<String, Object> param);
    int deleteData(Map<String, Object> param);
    

}

 

 

<?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.example.demo.test.TestDao">

    <select id="getDataList" parameterType="map" resultType="map">
        /* getDataList */
        select group_code  as group_code
             , code        as code
             , code_name   as code_name
             , insert_date as insert_date
             , update_date as update_date
          from code
         where 1=1
        <if test=' group_code != null and group_code != "" '>
           and group_code = #{group_code} 
        </if>
        <if test=' code != null and code != "" '>
           and code = #{code} 
        </if>
        <if test=' code_name != null and code_name != "" '>
           and code_name = #{code_name} 
        </if>
    </select>

    <select id="getData" parameterType="map" resultType="map">
        /* getData */
        select group_code  as group_code
             , code        as code
             , code_name   as code_name
             , insert_date as insert_date
             , update_date as update_date
          from code
         where 1=1
           and group_code = #{group_code}
           and code = #{code}
    </select>

    <insert id="insertData" parameterType="map" >
        /* insertData */
        insert into code (
             group_code
            ,code
            ,code_name
            ,insert_date
            ,update_date
        ) values (
             #{group_code}
            ,#{code}
            ,#{code_name}
            ,now()
            ,now()
        )
    </insert>

    <update id="updateData" parameterType="map" >
        /* updateData */
        update code
           set update_date=now()
             , code_name=#{code_name} 
         where 1=1 
           and group_code = #{group_code}
           and code       = #{code}
    </update>

    <delete id="deleteData" parameterType="map" >
        /* deleteData */
        delete 
          from code 
         where 1=1
           and group_code = #{group_code} 
           and code       = #{code}
    </delete>

</mapper>

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>
<body>

    <h1>Hello, world!</h1>

    <div>
        <table>
            <tr>
                <th>그룹코드</th>
                <td><input type="text" id="group_code" /></td>
                <th>코드</th>
                <td><input type="text" id="code" /></td>
                <th>코드명</th>
                <td><input type="text" id="code_name" /></td>
                <th>
                    <button id="btn_search">조회</button>
                </th>
                <th>
                    <button id="btn_add">등록</button>
                </th>
            </tr>
        </table>
        <table>
            <thead>
                <tr>
                    <th>그룹코드</th>
                    <th>코드</th>
                    <th>코드명</th>
                    <th>수정</th>
                    <th>삭제</th>
                </tr>
            </thead>
            <tbody id="data_list"></tbody>
        </table>
    </div>

    <script type="text/javascript">
        $(function(){
            console.log('jQuery 시작점');
        });

        $('#btn_search').on('click', (e) => {
            var param = {
                 group_code : $('#group_code').val()
                ,code       : $('#code').val()
                ,code_name  : $('#code_name').val()
            };

            $.ajax({
                  url         : '/test/getDataList'
                , async       : true
                , type        : 'POST'
                , dataType    : "json"
                , contentType : "application/json; charset=utf-8"
                , data        : JSON.stringify(param)
                , success     : function( res ) {
                    $('#data_list').children().remove();
                    res.result.forEach((result) => {
                        var tr = $('<tr></tr>').appendTo( $('#data_list') );
                        var groupCodeEle = $('    <td><input type="text" value="'+result.group_code+'" readonly /></td>').appendTo( tr );
                        var codeEle      = $('    <td><input type="text" value="'+result.code      +'" readonly /></td>').appendTo( tr );
                        var codeNameEle  = $('    <td><input type="text" value="'+result.code_name +'"          /></td>').appendTo( tr );
                        var updateBtn    = $('    <td><button>수정</button></td>').appendTo( tr );
                        var deleteBtn    = $('    <td><button>삭제</button></td>').appendTo( tr );

                        $(updateBtn).children('button').on('click', () => {
                            updateCode($(groupCodeEle).find('input'), $(codeEle).find('input'), $(codeNameEle).find('input'));
                        });
                        $(deleteBtn).children('button').on('click', () => {
                            deleteCode($(groupCodeEle).find('input'), $(codeEle).find('input'));
                        });
                    });
                }
                , error       : function( xhr ) {
                    console.log(xhr);
                }
            });
        });

        $('#btn_add').on('click', (e) => {
            var param = {
                 group_code : $('#group_code').val()
                ,code       : $('#code').val()
                ,code_name  : $('#code_name').val()
            };

            $.ajax({
                  url         : '/test/insertData'
                , async       : true
                , type        : 'POST'
                , dataType    : "json"
                , contentType : "application/json; charset=utf-8"
                , data        : JSON.stringify({
                     group_code : $('#group_code').val()
                    ,code       : $('#code').val()
                    ,code_name  : $('#code_name').val()
                })
                , success     : function( res ) {
                    console.log(res);
                }
                , error       : function( xhr ) {
                    console.log(xhr);
                }
            });
            
        });

        function updateCode(groupCodeEle, codeEle, codeNameEle) {
            $.ajax({
                  url         : '/test/updateData'
                , async       : true
                , type        : 'POST'
                , dataType    : "json"
                , contentType : "application/json; charset=utf-8"
                , data        : JSON.stringify({
                     group_code : $(groupCodeEle).val()
                    ,code       : $(codeEle).val()
                    ,code_name  : $(codeNameEle).val()
                })
                , success     : function( res ) {
                    console.log(res);
                }
                , error       : function( xhr ) {
                    console.log(xhr);
                }
            });
        }

        function deleteCode(groupCodeEle, codeEle) {
            $.ajax({
                  url         : '/test/deleteData'
                , async       : true
                , type        : 'POST'
                , dataType    : "json"
                , contentType : "application/json; charset=utf-8"
                , data        : JSON.stringify({
                     group_code : $(groupCodeEle).val()
                    ,code       : $(codeEle).val()
                })
                , success     : function( res ) {
                    console.log(res);
                }
                , error       : function( xhr ) {
                    console.log(xhr);
                }
            });
        }

    </script>

</body>
</html>

 

반응형

댓글