티스토리 뷰

spring jdbc를 사용하지 않고 jpa를 이용해 웹에서 입력받은 회원정보를 넣는데 성공했다.

초기설정 찾는제 대략 4일정도 걸린 것 같다.

구글링으로 방법을 찾는데 작성자마다 사용 프레임워크나 라이브러리가 달라서 tomcat이 반응을 안하기도 했고,

local DB에 저장이 안되기도 하고, local DB를 GUI 형식으로 보여주는 프로그램을 찾기위해 애먹고,

다운받은 프로그램 사용법 익히는데 시간 날리고... 참 많은 시간을 소비했다.

 

현재까지 진행 상황을 요약하자면

* 진행상황

- bootstrap을 이용해 적당한 홈페이지 구색을 갖춤

- form 태그로 입력받은(thymeleaf 이용) 데이터를 jpa를 이용해 mysql local DB에 저장하는데 성공

 

* 해결할일

- form 태그 및 thymeleaf 부분 수정하면서 bootstrap 디자인이 display가 안됨

- 회원가입 후 로그인 세션 설계 필요

- 회원정보 테이블 외에 회원가입 시 연차 테이블도 자동으로 생성되게 설계해야함.

- jpa 정확한 원리 및 사용방법 공부 필요

 

* jpa 설정코드

1) memberController

더보기
package com.jun.DowooriVer2.controller;

import com.jun.DowooriVer2.domain.Member;
import com.jun.DowooriVer2.service.MemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import java.util.Map;

@Controller
public class MemberController {
    // autowired : bean으로 등록된 클래스들을 스프링이 시작할때 자동으로 주입
    @Autowired
    MemberService memberService;

    @GetMapping("/login")
    public String login(){
        return "login";
    }

    // 회원가입
    @GetMapping("/register/join")
    public String register(Model model, Member member) {
        model.addAttribute("member",member);
        return "register";
    }

    @PostMapping("/register/new")
    public String joinUs(@ModelAttribute("member") Member member){

        memberService.join(member);

        return "index";
    }


}

2) Member(domain)

더보기
package com.jun.DowooriVer2.domain;

import lombok.Data;

import javax.persistence.*;


// data :getter, setter, constructer 등 한꺼번에 생성해주는 어노테이
// JPA에서는 @entity를 설정해줘야함
@Entity
@Data
@Table(name = "emp_table")
public class Member {

    @Id // PK
    @GeneratedValue(strategy = GenerationType.IDENTITY) // DBMS의 INCREMENT AUTO 사용할 경우
    private Long empNum;
    @Column(name = "email") //이름이 동일하면 생략가능
    private String email;

    private String password;
    @Column(name = "user_name")
    private String userName;
    @Column(name = "dept_name")
    private String deptName;
    private String position;
    @Column(name = "chief_name")
    private String chiefName;

    public Member(Long empNum, String email, String password, String userName, String deptName, String position, String chiefName) {
        this.empNum = empNum;
        this.email = email;
        this.password = password;
        this.userName = userName;
        this.deptName = deptName;
        this.position = position;
        this.chiefName = chiefName;
    }


    // JPA는 'public' 또는 'protected'의 기본 생성자가 필수이다.
    public Member () {

    }


}

3) JpaMemberRepository

더보기
package com.jun.DowooriVer2.repository.jpa;

import com.jun.DowooriVer2.domain.Member;
import com.jun.DowooriVer2.repository.MemberRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import javax.persistence.EntityManager;

@Slf4j //로그 남김
@Repository
@Transactional //JPA모든 데이터 변경은 트랜잭션 안에서 이루어짐. 항상 Transactional이 들어가야함
public class JpaMemberRepository implements MemberRepository {

    // 의존관계 주입 : 이게바로 JPA
    // 저장 조회기능을 해줌
    // 스프링 부트가 em을 만들어줌
    private final EntityManager em;

    // EntityManager 생성자
    public JpaMemberRepository(EntityManager em) {
        this.em = em;
    }

    @Override
    public Member save(Member member) {
        em.persist(member); // 영구히 보존한다
        return member;
    }
}

4) MemberRepository

package com.jun.DowooriVer2.repository;

import com.jun.DowooriVer2.domain.Member;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Optional;

@Repository
public interface MemberRepository{

    Member save(Member member);
}

5) MemberService

더보기
package com.jun.DowooriVer2.service;

import com.jun.DowooriVer2.domain.Member;
import com.jun.DowooriVer2.repository.MemberRepository;
import com.jun.DowooriVer2.repository.jpa.JpaMemberRepository;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
@Transactional
public class MemberService {


    private MemberRepository memberRepository;

    public MemberService(MemberRepository memberRepository) {
        this.memberRepository = memberRepository;
    }

    // 회원가입
    public Member join(Member member) {
        memberRepository.save(member);
        return member;
    }

}

5) SpringConfig

더보기
package com.jun.DowooriVer2;


import com.jun.DowooriVer2.repository.MemberRepository;
import com.jun.DowooriVer2.repository.jpa.JpaMemberRepository;
import com.jun.DowooriVer2.service.MemberService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Controller;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

@Configuration
public class SpringConfig {


    @PersistenceContext // 스프링에서는 생략 가능
    private EntityManager em;

    @Autowired
    public SpringConfig(EntityManager em) {
        this.em = em;
    }

    // JPA에서 사용하기위해 필수 설정해줌(이것때문에 계속 실행 안됐음...)
    @Bean
    public MemberService memberService(){
        return new MemberService(memberRepository());
    }

    @Bean
    public MemberRepository memberRepository(){
        return new JpaMemberRepository(em);
    }

}

6) register.html(회원가입 페이지)

더보기
<!DOCTYPE html>
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
<head th:fragment="head(title)">

    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="description" content="">
    <meta name="author" content="">

    <title>SB Admin 2 - Register</title>

    <!-- Custom fonts for this template-->
    <link href="vendor/fontawesome-free/css/all.min.css" rel="stylesheet" type="text/css">
    <link
        href="https://fonts.googleapis.com/css?family=Nunito:200,200i,300,300i,400,400i,600,600i,700,700i,800,800i,900,900i"
        rel="stylesheet">

    <!-- Custom styles for this template-->
    <link href="css/sb-admin-2.min.css" rel="stylesheet">

</head>

<body class="bg-gradient-primary">

    <div class="container">

        <div class="card o-hidden border-0 shadow-lg my-5">
            <div class="card-body p-0">
                <!-- Nested Row within Card Body -->
                <div class="row">
                    <div class="col-lg-5 d-none d-lg-block bg-register-image"></div>
                    <div class="col-lg-7">
                        <div class="p-5">
                            <div class="text-center">
                                <h1 class="h4 text-gray-900 mb-4">Create an Account!</h1>
                            </div>

<!--      form 태그                      -->
                            <form class="user" th:action="@{/register/new}" method="post" th:object="${member}">
                                <div class="form-group row">
                                    <div class="col-sm-6 mb-3 mb-sm-0">
                                        <input type="text" class="form-control form-control-user" name="userName"
                                            placeholder="이름을 입력해주세요" th:field="*{userName}">
                                    </div>
                                    <div class="col-sm-6">
                                        <select class="form-group" th:field="*{deptName}">
                                            <option selected value="null">부서선택</option>
                                            <option value="인사총무부">인사총무부</option>
                                            <option value="경영회계부">경영회계부</option>
                                            <option value="IT솔루션개발부">IT솔루션개발부</option>
                                        </select>
                                    </div>

                                </div>
                                <div class="form-group row">
                                    <div class="col-sm-6 mb-3 mb-sm-0">
                                        <input type="text" class="form-control form-control-user" name="userId" id="userId"
                                            placeholder="email을 입력해주세요" th:field="*{email}">
                                    </div>
                                    <div class="col-sm-6">
                                        <input class="btn btn-primary" type="button" id="usernameOverlay" onclick="usernameCheck()" value="중복 체크"/>
                                    </div>
                                </div>

                                <div class="form-group row">
                                    <div class="col-sm-6 mb-3 mb-sm-0">
                                        <input type="password" class="form-control form-control-user"
                                            id="password" placeholder="비밀번호를 입력해주세요" th:field="*{password}">
                                    </div>
                                    <div class="col-sm-6">
                                    <select class="form-group" th:field="*{chiefName}">
                                        <option selected value="">직책</option>
                                        <option value="부서장">부서장</option>
                                        <option value="파트장">파트장</option>
                                        <option value="null">해당없음</option>
                                    </select>
                                    <select class="form-group" th:field="*{position}">
                                        <option selected value="">직급</option>
                                        <option value="사원">사원</option>
                                        <option value="대리">대리</option>
                                        <option value="과장">과장</option>
                                        <option value="부장">부장</option>
                                    </select>
                                    </div>

                                </div>
                                <hr>
                                <button class="btn btn-primary btn-user btn-block" id="registerButton">
                                    Register Account
                                </button>
                            </form>

                            <hr>
                            <div class="text-center">
                                <a class="small" href="forgot-password.html">Forgot Password?</a>
                            </div>
                            <div class="text-center">
                                <a class="small" href="login.html">Already have an account? Login!</a>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>

    </div>

    <!-- Bootstrap core JavaScript-->
    <script src="../vendor/jquery/jquery.min.js"></script>
    <script src="vendor/bootstrap/js/bootstrap.bundle.min.js"></script>

    <!-- Core plugin JavaScript-->
    <script src="vendor/jquery-easing/jquery.easing.min.js"></script>

    <!-- Custom scripts for all pages-->
    <script src="js/sb-admin-2.min.js"></script>

</body>

</html>

 

8) 프로젝트 클래스 및 html 위치

9)application.properties

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/Dowoori_ver2
spring.datasource.username=root
spring.datasource.password=1012

# mysql 사용
spring.jpa.database=mysql
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect

# 하이버네이트가 실행한 모든 SQL문을 콘솔로 출력
spring.jpa.properties.hibernate.show_sql=true
# SQL문을 가독성 있게 표현
spring.jpa.properties.hibernate.format_sql=true
# 디버깅 정보 출력
spring.jpa.properties.hibernate.use_sql_comments=true
spring.jpa.hibernate.ddl-auto=none

 

 


오늘도 고생많았다~

'지식 한줌' 카테고리의 다른 글

WebSocket 개념정리  (0) 2023.12.24
JWT? 장단점? 왜쓸까?  (2) 2023.12.02
개발/검증 서버 작업 계획서 Sample  (0) 2023.10.18
Nexacro와 Oracle  (0) 2023.03.13
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/07   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31
글 보관함