토이 프로젝트/Spring&Java 갖고놀기

라즈베리파이에서 Spring 구동하기 & 회원가입하기(feat. Mysql 연동)

TerianP 2022. 1. 9.
728x90

2022년 첫 글이네요!! 많이 늦었지만 모두 해피 뉴 이어ㅋㅋ

생각보다 라즈베리로 연결하는데 오래 걸려서 이제야 정리하고 글을 쓰게 되었습니다. git 에도 연동하고 하는데...어디서 막히는지 막혀버려서ㅠㅠ이건 다음글에 조금 더 적어보도록 하겠습니다.

 

오늘은 기존에 만들어두었던 spring 을 Mysql과 연동하도록 하겠습니다. 또한 이 글은 기본적으로 MySQL이 깔려있으며, 외부에서 접속이 가능하다는 가정하에 진행하고 있습니다.

만약 DB가 설치되어 있지 않다면, 글 내용 중 2. Maria DB 설치 를 보고 와주시기 바랍니다!!

https://terianp.tistory.com/3?category=930649 

 

웹 서버 기본 뼈대 구축 : LEMP

첫 시작은 라즈베리 파이에 웹 서버 기본 뼈대 구축에 대한 정리글을 써볼까 합니다. LEMP - Linux + NGINX + MariaDB + PHP/Python/Perl 을 기본으로 구축하였습니다. 여기서 아파치가 아닌 nginx 를 설치하는

terianp.tistory.com

 

 

1. 기본 파일 설정하기 : 설정파일 세팅 및 Mysql 연동 확인

- application.properties

#### IF use application.properties ############

#server.address=localhost
#server.port=8080

# DB setting
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://MySQL DB 주소명/DB 명
spring.datasource.username=DB 로그인 정보
spring.datasource.password=DB 로그인 정보

# JPA settting
spring.jpa.database=mysql
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true

 

-  build gradle

plugins {
   id 'org.springframework.boot' version '2.6.1'
   id 'io.spring.dependency-management' version '1.0.11.RELEASE'
   id 'java'
}

group = 'HJproject'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '15'

repositories {
   mavenCentral()
}

dependencies {
   implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
   implementation 'org.springframework.boot:spring-boot-starter-web'
   testImplementation 'org.springframework.boot:spring-boot-starter-test'

   // H2 DB
// runtimeOnly 'com.h2database:h2'

// // MySQL DB
   runtimeOnly 'mysql:mysql-connector-java'

// // JDBC
   implementation 'org.springframework.boot:spring-boot-starter-jdbc'

// // JPA
   implementation 'org.springframework.boot:spring-boot-starter-data-jpa'

// // AOP
   implementation 'org.springframework.boot:spring-boot-starter-aop'


// testImplementation('org.springframwork.boot:spring-boot-starter-test'){
//    exclude group : 'org.junit.vintage', module: 'junit-vintage-engine'
// }
}

test {
   useJUnitPlatform()
}

 

- Mysql DB 및 테이블 생성

1. create database hjproject;
2. DROP TABLE member;

3. 
CREATE TABLE member
(
   CODE BIGINT PRIMARY KEY auto_increment NULL,
   NAME VARCHAR(255) NOT NULL,
   id VARCHAR(255) NOT NULL,
   passwd VARCHAR(255) NOT NULL,
   sex VARCHAR(100) NULL,
   email VARCHAR(100) NULL,
   emaddress VARCHAR(100) NULL
);

 

- Mysql 연동 확인

위에 2가지 파일 설정을 완료하면 이제 진짜로 DB 와 연동이 되는지 여부를 확인해야 합니다. 이를 위해서 짧막하게 확인할 수 있는 Test 코드를 실행해봅시다.

package HJproject.Hellospring.connSQL;


import HJproject.Hellospring.domain.Member;
import org.hibernate.annotations.common.reflection.XMember;

import java.sql.*;
import java.util.ArrayList;

public class connSQL {

    public static void main(String[] args){


        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        String SQL = "select * from member";

        try {
            System.out.println("연결중1");

            Class.forName("com.mysql.cj.jdbc.Driver");

            System.out.println("연결중2");

            conn = DriverManager.getConnection("jdbc:mysql://MySQL DB 주소명/DB 명","DB로그인 정보","DB로그인 정보");
            System.out.println("접속 성공!! : "+ conn); // 접속 여부 및 정보 확인


            System.out.println("Step 2");

            stmt = conn.createStatement();
            rs = stmt.executeQuery(SQL);

            ArrayList<Member> list = new ArrayList<Member>();

            while(rs.next()){
                Member member = new Member();

                member.setCode(rs.getLong("CODE")); // 테이블에서 code 가져오기
                member.setName(rs.getString("NAME")); // 테이블에서 name 가져오기
                list.add(member);

            }

            for(int i=0; i<list.size(); i++){
                System.out.println("CODE : "+ list.get(i).getCode());
                System.out.println("name : "+ list.get(i).getName());

            }



        }

        catch(Exception e) {
            System.out.println("드라이버 로딩 실패");

            e.printStackTrace();

        }

        finally {
            try {
                if( conn != null && !conn.isClosed()){
                    conn.close();

                }

            }catch (Exception e) {
                e.printStackTrace();

            }

        }

    }
}

 


Mysql 이 정상적으로 연결된 상태!! 접속 확인과 함께 DB 테이블 정보를 확인 가능


 

2. DB 테이블에 맞게 코드 수정

이번에는 DB 테이블에 맞게 코드를 수정해보겠다. 수정되는 파일과 수정 내용은 아래와 같다. 자세한 내용은 주석 참고.

- MemberForm : 추가되는 부분 - 성별(sex) , email(이메일 아이디) , emadress(이메일 주소) - 들에 대해서 정의하고 추가하기 위한 getter , setter 메서드를 생성한다.

- MemberController : 멤버 컨트롤러에서 회원 가입, 로그인 시 넘어가는 view 를 설정하고, 회원 저장 시 필요한 정보들을 set 으로 설정한다. 여기서 중요한 것은 return 시 맨 앞에 루트 "/" 는 필요없다는 점. 이거 있으면 에러난다.

- Member : DB와 연동되어 저장하는 기능을 도와줄 Entity 로 설정된 클래스 파일. 추가되는 부분에도 마찬가지로 Column 을 붙이고 어떤 컬럼인지 명시해준다.

- 실제 회원 가입 시 회원가입을 위한 데이터(이름, 아이디, 비밀번호, 이멜주소 등) 의 전달 과정은 다음과 같다.

=> newregisters 페이지에서 내용 작성후 '회원가입하기' 버튼 클릭 -> MemberForm 페이지에서 getter 로 가져와진 데이터들이 settter 메서드를 통해 member 객체에 저장됨 -> memberService join 메서드 실행(중복 아이디 검사) -> JpamemberRepository 의 save 메서드 실행. JPA entitiyManager 를 통해서 MySQL DB에 persist 즉, 영구 저장됨

 

 

- MemberForm

package HJproject.Hellospring.Controller;

public class MemberForm {
    private String name;
    private String userid; // 고객 id
    private String userpw; // 고객 passwd

    /* 6. 내 맘대로 구현하기 step 2 */
    private String sex;
    private String email;
    private String emaddress;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getUserid() {
        return userid;
    }

    public void setUserid(String userid) {
        this.userid = userid;
    }

    public String getUserpw() {
        return userpw;
    }

    public void setUserpw(String userpw) {
        this.userpw = userpw;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getEmaddress() {
        return emaddress;
    }

    public void setEmaddress(String emaddress) {
        this.emaddress = emaddress;
    }
}

 

- MemberController

package HJproject.Hellospring.Controller;

import HJproject.Hellospring.domain.Member;
import HJproject.Hellospring.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.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;

import java.util.List;

@Controller
public class MemberController {

    private final memberService memberService;

    @Autowired
    // Bean 으로 설정되었던 memberService 를 넣어줌. 의존성 주입
    public MemberController(memberService memberService) {
        this.memberService = memberService;
        System.out.println("memberService = " + memberService.getClass()); // AoP 프록시 동작 확인하기
    }


    @GetMapping("/members/newregisters") // http 에서 get 으로 넘어올때 -> 주로 값을 출력하는 경우
    public String createForm(){
        return "members/newregisters";
    }

    @PostMapping("/members/new") // http 에서 members/new 페이지에 대해 post 로 넘어올 때 -> 주로 값을 등록하는 경우
    public String create(MemberForm form){
    // 내맘대로 수정하기 6.
        Member member = new Member(); // member 객체 생성
        member.setName(form.getName()); // member name 에 form 에서 받아온 name 을 넣어준다
        member.setId(form.getUserid());
        member.setPasswd(form.getUserpw());
        member.setSex(form.getSex());
        member.setEmail(form.getEmail());
        member.setEmaddress(form.getEmaddress());

        memberService.join(member);
        //member service 를 사용해 member 객체에 대해 join 메서드를 실행한다.

//        System.out.println("member : "+member.getName());
//        System.out.println("member : "+member.getPasswd());
//        System.out.println("member : "+member.getId());


        return "redirect:/"; // 회원가입이 끝나서 가입하기를 누르면 home(root page) 으로 설정된 페이지로 돌아감
    }

    @GetMapping("/members/member_List") // members 페이지에 대해 Get 으로 넘어올 때 -> 주로 값을 불러오는 하는 경우
    public String list(Model model){ // Model 사용을 list 로 사용
        List<Member> members = memberService.findMembers(); // memberService.findMembers() 를 list 형식으로 저장
        model.addAttribute("members", members);
        // 파라미터로 넘어온 members 을 model에 담아서 members/members_list 의 members 로 넘긴다.

        return "members/members_List"; // return 시에는 앞에  " / " 가 없어야함
    }
}

 

 

- Member

package HJproject.Hellospring.domain;

import javax.persistence.*;

@Entity
public class Member {

    // @Id : DB 에서 primary key 로 설정된 컬럼 맵핑
    // @GeneratedValue : pk 값의 생성 방식 -> 현재는 DB 에서 자동 생성임으로 이에 해당하는 Identity
    @Id @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long code; // 시스템에서 저장 & 식별 구분 하기 위한 code

    // @Column : 컬럼명 코드 변수 매핑 -> name = "컬럼명"
    @Column(name = "name")
    private String name; // 고객 이름


    @Column(name = "id")
    private String id; // 고객 id

    @Column(name = "passwd")
    private String passwd; // 고객 passwd

/* 6. 내 마음대로 구현하기 step 2 */

    @Column(name = "sex")
    private String sex;

    @Column(name = "email")
    private String email;

    @Column(name = "emaddress")
    private String emaddress;



    public Long getCode() {
        return code;
    }

    public void setCode(Long code) {
        this.code = code;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getPasswd() {
        return passwd;
    }

    public void setPasswd(String passwd) {
        this.passwd = passwd;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getEmaddress() {
        return emaddress;
    }

    public void setEmaddress(String emaddress) {
        this.emaddress = emaddress;
    }
}

실제로 동작할까? 바로 build 후에 테스트해보자

FTP를 사용 라즈베리파이에 업로드 후 다음 명령어로 실행한다.

아래 명령어는 spring 을 백그라운드에서 실행시켜주는 명령어이다. 

java -jar Hello-spring-0.0.5-SNAPSHOT.jar &

명령어 사용시 아래와 같이 한번 출력되는데 종료할때는 아래 프로세스 넘버를 kill로 죽여주면 된다.

 

이렇게 하면 스프링이 다음 화면처럼 스프링이 실행되는 모습을 확인 할 수 있다. 기기 성능에 따라서 시간이 다소 걸릴수 있으니 기다림은 필수!

본인은 1분정도 걸린다.


메인 페이지 및 로그인 페이지, 회원 가입 페이지는 프론트를 공부하는 친구가 도와주었다. 너무 감사하다.

이전에 그 이상한...페이지들은 이제 없다ㅋㅋ

1. 메인 페이지

 

2. 로그인 화면

아주 깔끔하다. 매우 만족스럽다

3. 회원가입 화면 

역시나 심플하고 깔끔하다. 너무 감사해요

 

 

4. 회원 리스트 확인

리스트도 잘 나온다.

 

 

마지막 번외!! 빌드 시 테스트 부분에서 다음과 같은 오류가 발생했다.

2021-12-30 15:27:52.033 ERROR 6799 --- [nio-8080-exec-8] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.thymeleaf.exceptions.TemplateInputException: Error resolving template [/members/members_List], template might not exist or might not be accessible by any of the configured Template Resolvers] with root cause​

이는 앞에서 잠깐 설명하였듯이 return 부분에 / 가 맨 앞에 껴있어서 그런것으로 보인다. 이를 지워주니 정상적으로 빌드가 완료되었다.

@GetMapping("/members") // members 페이지에 대해 Get 으로 넘어올 때 -> 주로 값을 불러오는 하는 경우
public String list(Model model){ // Model 사용을 list 로 사용
    List<Member> members = memberService.findMembers(); // memberService.findMembers() 를 list 형식으로 저장
    model.addAttribute("members", members);
    // 파라미터로 넘어온 members 을 model에 담아서 members/members_list 의 members 로 넘긴다.

    return "/members/members_List";
}
return "members/members_List"

 

 

이로써 가장 해보고 싶었던 spring 과 Mysql 을 연동하여 회원가입 하는 것이 가능해졌다. 앞으로 추가할 것은 회원 가입 입 후 로그인 기능 구현, 로그인 후 웹 메일 발송 기능 구현 등을 해볼 예정이다.

 


- 참고 사이트

 

https://stackoverflow.com/questions/6865538/solving-a-communications-link-failure-with-jdbc-and-mysql

 

Solving a "communications link failure" with JDBC and MySQL

I'm trying to connect to the local MySQL server but I keep getting an error. Here is the code. public class Connect { public static void main(String[] args) { Connection conn = null;...

stackoverflow.com

 

https://pby0716.tistory.com/32

 

JAVA에서 JDBC로 SELECT 조회하는 방법(Statement)

JAVA에서 프래그램을 작성하다보면 DB에 연결하여 데이터를 가져와야하는 경우가 많다. 해당 방법을 위하여 Connection 부터 데이터 처리까지의 방법을 확인해보자. JdbcConnector.java package com.util; import

pby0716.tistory.com

 

https://elfinlas.github.io/2018/06/08/spring-boot-exception-template/

 

Thymeleaf에서 TemplateInputException 발생의 원인

org.thymeleaf.exceptions.TemplateInputException 발생…Spring Boot의 프로젝트를 진행하던 중 화면을 하나 추가하고 서버를 올린 뒤 해당 뷰로 접근하는 순간…아래와 같은 에러가 발생하였다. 123452018-05-28 01:3

elfinlas.github.io

 

댓글