javaFX 차트

미리 파일 생성

javaFX 라이브러리도 프로젝트 우클릭 - properties 들어가서 미리 추가하기

 

inner 클래스의 간단한 설명

 

chartFXML.fxml 파일 세팅하기

 

각 차트, fxid, Controller class 세팅한 뒤 저장

 

fxml 파일에 반영 됐는지 확인

 

javafx.controls 수기로 추가 ( 차트를 가지고 있는 라이브러리 ) - 자동으로 호출되지 않으므로 직접 호출해줘야 함

 

MainClass 클래스에 세팅

 

Controller 와 각 차트를 어노테이션으로 연동

 

각 차트의 값을 inner 클래스를 사용하여 대입

 

출력되는 데이터

 

버튼 하나 생성

 

버튼이 눌리면 초기화되게끔 설정

 

 

코드 실행 영상

 

Initiallizable 로 자동 초기화 시킨 부분 코드 풀어서 작성

 

코드 실행 영상

 

BarChart 구현

 

BarChart 구현

 

AreaChart 구현

 

AreaChart 구현

 

 

 

 

 

 

 

 

 

 

실습 예제

실습 예제

728x90

 

 

 

 

 

javaFX DB 연동

( 21일차의 회원가입 구현 내용에 이어서 회원 정보를 DB 와 연동 )

 

 

 

DB 에 저장할 테이블과 컬럼 생성

 

MemberDTO 클래스에 자료를 담을 변수를 선언, getter / setter 생성

 

MemberServiceImpl 클래스에 DTO 객체 생성하여 사용자가 입력한 값을 저장 ( 취미는 합으로 결정 : 만약 음악, 영화 두 개를 선택했다면 3 값을 저장 )

 

MemberServiceImpl 에 DAO 변수 선언 및 생성자 선언하여 dao 객체화

 

DAO 객체 생성하여 저장된 값을 가지고 있는 dto 객체를 매개변수로 넘김

 

module-info 에 java.sql 추가 ( import 로 자동으로 추가되지 않으므로 프로젝트 우측 클릭 해서 자동으로 module-info 생성하거나 직접 넣어줘야 함 )

 

위 코드 실행 시 오류코드 발생 ( ojdbc8 을 추가해주지 않았기 때문!!! )

 

ojdbc8 을 추가해줘야 함 ( DB 와 연동하기 위해서 )

 

DB 연결 성공

 

쿼리문 작성하여 dto 객체에 저장된 값을 DB 에 저장

 

코드 실행 영상

 

age 컬럼의 값이 10 바이트라 20대 미만, 50대 이상 은 12 바이트 값이라 저장이 되지 않는 오류가 발생 > age 컬럼의 값을 늘려주면 해결 완료

 

 

 

 

 

- 무한 로딩 오류 발생 -

※ DB 에 데이터를 저장하고 다시 확인하려 sqldeveloper 로 쿼리문을 사용해서 테이블의 행을 삭제한 뒤 다시 데이터 추가를 시도하니 무한 로딩이 발생함 > sqldeveloper 에서 쿼리문을 실행한 뒤 commit 해주지 않아서 eclipse 에서 커밋이 진행될때까지 로딩을 반복함 > sqldeveloper 는 무조건 쿼리문 작성한 뒤 commit 을 해줘야 함!! ※

 

>>> 테이블 생성, 테이블의 정보 수정은 커밋이 필요하지 않지만 값에 대한 수정은 무조건 커밋을 해줘야 한다!!!

 

 

 

 

 

DAO 에서 실행 결과를 성공 : 1 , 실패 : 0 으로 반환받아 MemberServiceImpl 에서 처리

 

 

 

 

 

이제 어제 로그인을 가상의 데이터로 연결해 놓은 부분을 실제 DB 와 연동

 

LoginServiceImpl 에 DAO

 

javaFX 에서 사용자가 입력한 아이디 값을 받아 dao 의 getUser 메소드에 전달하여 확인한 뒤 반환된 dto 값을 저장

 

getUser 메소드를 LoginDAO 클래스에 생성

 

LoginDAO 에 사용자가 존재한다면 값이 담긴 id, pwd, name 이 담긴 dto 값 반환, 사용자가 존재하지 않는다면 null 값이 담긴 dto 를 반환

 

코드 실행 영상

 

알림 창은 모든 클래스에서 동일하게 사용하는 것이니 CommonService 인터페이스로 따로 구현 ( 인터페이스에 메소드를 static 으로 실체화는 할 수 있음, 일반적인 메소드는 구현 불가능 )

 

기존에 LoginServiceImpl 에서 따로 사용하던 alert 주석 처리 이후 CommonService 에 구현한 alert 로 대체

 

MemberServiceImpl 에서 Alert 가 필요한 부분에 CommonService 인터페이스에 생성한 알림창 메소드 사용

 

MemberServiceImpl 에서 Alert 가 필요한 부분에 CommonService 인터페이스에 생성한 알림창 메소드 사용

 

스테이지를 닫는 코드도 중복되므로 따로 CommonService 인터페이스에 static 으로 구현하여 고용으로 사용

 

LoginServiceImpl 에 기존에 창 닫는 코드 주석처리 후 CommonService 에 구현한 코드 적용

 

MemberServiceImpl  에 기존에 창 닫는 코드 주석처리 후 CommonService 에 구현한 코드 적용

728x90

 

 

 

 

 

javaFX 입력 받기, 창 전환

 

세팅

 

test.fxml 파일 마우스 우클릭하여 scene builder 로 실행

 

AnchorPane 넓이와 높이 설정

 

텍스트 필드와 버튼 추가

 

생성한 버튼 클릭 후 우측에 코드의 On Action 에 btnFunc 입력하여 btnFunc 함수와 연동 ( btnFunc 함수는  연동된 ex01 패키지의 Controller 클래스에 생성해줘야 한다 )

 

텍스트 필드에 fx:id 에 tf 입력

 

좌측 하단의 Controller 에 Controller class 를 ex01.Controller 클래스로 연동 후 저장

 

fxml 파일에 정상적으로 코드가 저장된 것 확인

 

작성한 fxml 파일을 scene 에 등록

 

Controller 에 btnFunc 함수 추가 후 module-info 파일에 직접 controls 추가해줘야 함

 

어노테이션 사용하여 텍스트 필드 와 메소드를 연동

 

.getText() 메소드로 사용자가 입력한 값을 얻어온 뒤 .setText("") 를 이용하여 입력 창을 공백 값으로 비워준다

 

 

코드 실행 모습

 

 

 

 

 

<!-- 오류 발생 --!>

SceneBuilder 에서 버튼과 텍스트 필드를 생성하고 저장했을때 자동으로 import 될때 javafx 패키지의 TextField 가 아닌 다른 패키지의 TextField 가 import 되어 오류가 발생되었으니 저장 후 fxml 파일 확인할때 import 목록을 확인해봐야 한다!!!!

 

 

 

 

 

텍스트 필드 하나 더 추가 후 fx:id 를 tf02 로 설정

 

기존에 생성했던 텍스트 필드의 우측 Properties 열어서 Editable 체크 해제 ( 입력할 수 없게끔 설정, 읽기 전용으로 설정 )

 

tf02 에 입력된 내용을 기존의 텍스트 필드인 tf에 출력

 

Alert 클래스 사용하여 알림창도 출력되게 설정

 

 

코드 실행 영상

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

DAO, DTO, Controller 로 분리하기

파일 세팅

 

패키지 우측클릭해서 module-info 자동 추가

 

fxml 파일 scene builder 로 오픈 후 AnchorPane 크기 설정

 

라벨, 텍스트 필드 생성 후 AnchorPane 안에 HBox 생성하여 아래 버튼 3개 만들 공간 확보

 

생성한 HBox 내에 버튼 3개 생성 ( 확인, 취소, 회원가입 )

 

HBox 의 Properties 에서 정렬을 TOP_CENTER 로 변경

 

버튼들 간의 간격도 HBox 의 Layout 탭에서 Spacing 값 조절하여 설정

 

텍스트 필드의 Properties 탭에서 Prompt Text 에 회색 글씨로 들어갈 글씨 입력 ( 글씨 입력 시 사라질 글씨 )

 

아이디 입력할 텍스트 필드 fx:id 를 fxId 로 설정

 

비밀번호 입력할 텍스트 필드 fx:id 를 fxPwd 로 설정

 

각 버튼별 On Action ( 연결될 메소드 ) 설정

 

각 버튼별 On Action ( 연결될 메소드 ) 설정

 

각 버튼별 On Action ( 연결될 메소드 ) 설정

 

연결될 Controller 클래스 설정

 

fxml 파일에 코드 정상적으로 들어갔는지 확인, Controller 파일에 미리 버튼과 연동될 메소드 생성

 

Main 클래스에 fxml 파일 불러오기

fxml 파일과 MainClass 의 패키지를 분리하였으므로 기존의 getClass() 메소드로는 경로를 load 할 수가 없다.

Paths 클래스를 사용하여 경로를 불러온 뒤 뒤에 추가적인 경로들을 직접 붙여준다.

※ Paths.get("").toAbsolutePath().toString() 을 사용하여 현재 프로젝트의 절대 경로를 가져온 것 ※

 

프로젝트 하위의 bin 폴더까지의 경로는 계속 사용할 것이므로 login.url interface 에 선언

 

인터페이스에 설정한 경로로 MainClass 에서 bin 까지는 대체해서 사용

 

Controller 클래스에 Initializable 를 implements, 초기화 메소드를 오버라이딩

 

컨트롤러에 fxml 파일에 생성한 텍스트 필드를 연동

 

컨트롤러 객체를 생성

 

취소버튼 눌렀을때 실행되는 메소드 작성

 

임의로 담아둘 id, pwd, name 생성 및 setter / getter 생성

 

임시 데이터를 저장할 Map 생성 및 데이터 저장

 

입력 값이 확인 누르면 잘 받아와지는지 확인

 

키 값 입력시 객체값이 나오는지 확인 ( aaa3 은 없는 아이디 이기 때문에 null 반환 ) DAO 에 생성한 키는 aaa0 ~ aaa2 까지

 

로그인 구현 ( 알림창으로 로그인 성공, 실패, 비밀번호 틀렸을 경우 출력 )

 

코드 실행 화면

 

Controller 클래스에 구현해놓은 서비스 메소드를 LoginService 로 옮길 것임

 

기존에 Controller 클래스에 있던 메소드들을 LoginServiceImpl 로 필요한 매개변수들을 전달하여 사용

 

 

 

 

회원가입 부분 구현

회원가입 fxml 생성하여 기능 추가하기 ( 각 클래스, 인터페이스 파일과 fxml 위와 같이 세팅하기 )

 

LoginService 클래스의 registerFunc 메소드를 사용하면 회원가입 클래스의 메소드를 호출

 

MemberMain 클래스에 스테이지를 하나 새로 생성 후 member.fxml 를 씬에 등록 및 show 로 회원가입 버튼 누를 시 출력되게 설정

 

MemberController 에 회원가입 버튼, 취소 버튼 누를 때 실행될 메소드 미리 선언

 

사용중인 스테이지를 그대로 사용하며 회원가입 클릭 시 새 창을 띄우지 않고 창을 전환시키는 방법

LoginService 에 registerFunc 메소드 실행될때 root 값을 전달

 

컨트롤러에서도 registerFunc 실행할때 root 값 전달하게끔 설정

 

인터페이스에도 root 값을 받는 메소드 추가

 

회원가입을 눌러 MemberMain 클래스의 viewFx 가 호출될때 root 값을 넘겨받으므로 해당 값으로 처리하면 됨

 

기존엔 창이 하나 더 생성되며 회원가입 창이 열렸으나, 위와 같이 Main 에서 사용하던 root 의 값을 받아서 처리하니 새로운 stage 가 생성되어 열리는게 아닌 기존의 stage 가 변환되는 모습

 

연령선택 콤보 박스에 텍스트 추가

 

회원가입 버튼 클릭 시 콤보 박스의 값 잘 받아오는 것 확인

 

컨트롤러에서 받아올 값들 전부 객체로 생성 ( 어노테이션으로 fxml 과 객체명을 동일하게 하여 연동 )

 

콤보박스가 체크되지 않았거나 아이디가 입력되지 않으면 해당 창으로 이동하게끔 세팅, 각 입력 값 출력

 

코드 실행 영상

 

컨트롤러에 만들어 놓은 서비스 부분을 모드 MemberServiceImpl 로 옮겨서 사용할 것임 ( 이때, 각 매개변수를 따로 전달하는게 아니라 모든 입력 값을 가진 root 를 넘겨 받아서 값들을 처리할 것임 )

 

MemberMain 의 viewFx 메소드가 호출될 때 컨트롤러에 root 값을 전달

 

Controller 클래스는 전달받은 root 값을 MemberService 인터페이스로 전달

 

MemberService 인터페이스에서 root 를 전달받는 메소드를 정의

 

MemberService 에서 넘겨받은 root 값을 1 에서 저장, 2 에서 각 값을 저장받을 변수를 생성, 3 에서 root 에서 각 값을 Id 를 일치시켜 받아와 저장

 

 

코드 정상 작동 확인
728x90

 

 

 

 

 

Scene Builder

 

Scene Builder - Gluon

Drag & Drop,Rapid Application Development. Download Now   Integrated Scene Builder works with the JavaFX ecosystem – official controls, community projects, and Gluon offerings including Gluon Mobile, Gluon Desktop, and Gluon CloudLink.   Simple Drag

gluonhq.com

 

Scene Builder - Windows Installer 다운로드

 

다운로드된 파일 실행

 

설치 경로만 변경 > 인스톨

 

C드라이브 하위에 SceneBuilder 폴더가 생성되고 그 안에 설치된 것 확인

 

Ctrl + n 클릭하여 fxml 파일 프로젝트에 추가

 

Name : 이름 설정, Root Element : Pane 설정 후 Finish

 

Window - Preference 클릭

 

JavaFX - SceneBuilder executable 항복 Browse 클릭

 

설치한 SceneBuilder 경로로 이동하여 SceneBuilder.exe 선택

 

Apply and Close 클릭

 

아까 생성한 fxml 파일 우측클릭 - Open with SceneBuilder 클릭

 

연동 완료

 

AnchorPane 클릭 후 우측의 Layout 창 열어서 크기 설정

 

SceneBuilder 를 사용하여 폼을 제작

 

module-info.java 에 직접 2줄 추가

 

ScnenBuilder 로 제작하여 저장한 내용을 불러와서 생성한 Pane 의 클래스로 받아 Scene 에 등록

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

실습 예제

728x90

 

 

 

 

 

javaFX 설치 및 설정

 

 

 

 

 

- eclipse 용 JavaFX 플러그인 설치 -

help - Install New Software 클릭

 

Add 클릭

 

이름 아무거나 설정

Location : https://download.eclipse.org/efxclipse/updates-nightly/site/

 

e(fx)clipse - install, e(fx)clipse - single components 두 개다 체크 후 Next > Next > Install

 

다운로드 완료되면 이클립스 재부팅 창 나옴 > 재부팅

 

※ 설치 도중에 에러 창이 발생한다면 eclipse 를 관리자 권한으로 실행하여 시도하면 된다 ※

 

eclipse 용 fx 파일이 설치되었는지 확인

Help - Eclipse Marketplace...

 

e(fx)clipse 3.8.0 이 설치되어 있는지 확인

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

- javaFX 라이브러리 설치 url -

 

JavaFX - Gluon

Roadmap Release GA Date Latest version Minimum JDK Long Term Support Extended or custom support Details 23 September 2024 early access 17 no 22 March 2024 early access 17 no 21 September 2023 21.0.2 (January 2024) 17 yes upon request details 20 March 2023

gluonhq.com

 

사용중인 Java 버전에 맞는 Windows 용 SDK 다운로드

 

openjfx-21.0.2_windows-x64_bin-sdk.zip 압축 해제

 

사용할 프로젝트 우클릭 - Properties 클릭

 

Java Build Path - Libraries - Add External JARs... 클릭

 

아까 설치한 javaFX sdk 폴더에 lib 의 모든 파일을 선택한 뒤 열기

 

정상적으로 모든 라이브러리 올라온것 확인 후 Apply and Close

 

javaFX 는 Application 을 상속받아서 사용해야 한다. ( 오류 발생 )

 

사용 프로젝트 우클릭 - Configure - Create module-info.java 클릭

 

Yes 클릭

 

Create 클릭

 

module-info.java 파일에 javaFX 추가된 모습

 

추상화 메소드가 존재해서 오버라이딩을 해줘야 함 - Add unimplemented mehtods 클릭

 

오버라이딩 이후 클래스를 구현할때 Lanch(args); 코드를 사용하면 Application 의 기능이 호출되며, Application 의 기능이 호출될 때 오버라이딩된 start 메소드가 실행된다

 

javaFX Stage

 

 

 

- Scene 레이아웃 옵션 -

 

레이아웃 설정 및 버튼 생성 - FlowPane 사용

 

결과물

 

 

 

 

 

 

 

 

 

 

실습 예제

실습 예제

 

실습 풀이

 

 

 

 

 

 

 

 

 

 

FowPane 옵션

 

 

 

 

 

 

 

 

 

 

각 옵션들 위치 설정 및 텍스트 입력 창 만들기
결과물

 

 

 

 

 

 

 

 

 

 

add 옵션으로 라벨, 버튼 추가 및 위치 지정
결과물

 

 

 

 

 

 

 

 

 

 

병합
결과물

 

 

 

 

 

 

 

 

 

 

BorderPane 사용
결과물

 

 

 

 

 

 

 

 

 

 

결과물

728x90

 

 

 

 

[JAVA] 파일 입, 출력을 이용한 회원 관리 프로그램

1. 회원을 생성할때 회원의 정보(아이디, 비밀번호, 닉네임)를 객체화하여 파일 출력 스트림을 사용해 파일로 저장한다.

2. 회원 생성 / 로그인 / 비밀번호 초기화 / 회원 삭제 기능을 구현한다.

3. 아이디에 공백이 존재할 수 없게 구현한다.

4. 메인 클래스 / 서비스 구현 클래스 / DTO 클래스 / DAO 클래스 를 각각 구현하여 클래스별로 기능을 나누어 구현한다.

 

package loginMain;

import loginDTO.LoginDTO;
import loginService.LoginServiceImpl;

public class Main {
    public static void main(String[] args) {
        LoginServiceImpl service = new LoginServiceImpl();
        while(true){
            int choice = service.MainDisplay();
            if(choice == 5){
                System.out.println("프로그램을 종료합니다.");
                break;
            }

            switch(choice) {
                case 1:
                    service.CreateUser();
                    break;
                case 2:
                    service.logIn();
                    break;
                case 3:
                    service.reset();
                    break;
                case 4:
                    service.remove();
                    break;
                default:
                    System.out.println("잘못 입력하셨습니다.");
                    break;
            }
        }
    }
}

Main 클래스

 

package loginService;

import loginDTO.LoginDTO;

public interface LoginService {
    public int MainDisplay();
    public void CreateUser();
}

LoginService 인터페이스

 

package loginService;

import loginDAO.LoginDAO;
import loginDTO.LoginDTO;

import java.io.File;
import java.util.Objects;
import java.util.Scanner;

public class LoginServiceImpl implements LoginService{
    static Scanner sc;

    @Override
    public int MainDisplay() {
        sc = new Scanner(System.in);
        System.out.println("=================");
        System.out.println("1. 회원가입");
        System.out.println("2. 로 그 인");
        System.out.println("3. 비밀번호 초기화");
        System.out.println("4. 회원 삭제");
        System.out.println("5. 종 료");
        System.out.println("=================");
        System.out.print(">>> : ");
        int choice = sc.nextInt();
        return choice;
    }

    @Override
    public void CreateUser() {
        sc = new Scanner(System.in);
        LoginDAO DAO = new LoginDAO();
        boolean bool = false;
        System.out.print("아이디를 입력하세요 : ");
        String id = sc.nextLine();
        if(id.contains(" ")){
            System.out.println("아이디는 공백을 포함할 수 없습니다!!!");
            return;
        }
        if(DAO.duplicationCheck(id)){
            System.out.print("이름을 입력하세요 : ");
            String name = sc.next();
            System.out.print("비밀번호를 입력하세요 : ");
            String pwd = sc.next();
            LoginDTO DTO = new LoginDTO(id, name, pwd);
            bool = DAO.createId(DTO);
            if(bool){
                System.out.println(name + " 님 계정생성 완료!!!");
            }else {
                System.out.println("계정 생성 실패!!!");
            }
        }else {
            System.out.println("이미 존재하는 아이디입니다!!!");
        }
    }

    public void logIn(){
        sc = new Scanner(System.in);
        LoginDAO DAO = new LoginDAO();
        String id, pwd;
        System.out.print("아이디를 입력하세요 : ");
        id = sc.nextLine();
        if(DAO.duplicationCheck(id)){
            System.out.println("존재하지 않는 아이디 입니다.");
        }else{
            System.out.print("비밀번호를 입력하세요 : ");
            pwd = sc.next();

            String result = DAO.logIn(id, pwd);
            if(result != null) System.out.println("\"" + result + "\" 님 로그인 완료!!!");
            else System.out.println("비밀번호를 확인해주세요.");
        }
    }

    public void reset(){
        sc = new Scanner(System.in);
        LoginDAO dao = new LoginDAO();
        String id, name, pwd;
        System.out.print("비밀번호를 초기화할 아이디를 입력하세요 : ");
        id = sc.next();
        if(dao.duplicationCheck(id)) {
            System.out.println("해당 아이디는 존재하지 않습니다.");
            return;
        }
        System.out.print("닉네임을 입력하세요 : ");
        name = sc.next();
        String result = dao.resetCheck(id, name);
        if(result==null){
            System.out.println("닉네임을 다시 확인하세요.");
        }else {
            System.out.println("비밀번호가 {" + result + "} 로 초기화되었습니다.");
        }

    }


    public void remove() {
        sc = new Scanner(System.in);
        LoginDAO DAO = new LoginDAO();
        String id, pwd;
        System.out.print("아이디를 입력하세요 : ");
        id = sc.nextLine();
        if(DAO.duplicationCheck(id)) {
            System.out.println("존재하지 않는 아이디 입니다.");
            return;
        }
        System.out.print("비밀번호를 입력하세요 : ");
        pwd = sc.next();
        String removeCheck = DAO.logIn(id, pwd);
        if(removeCheck==null){
            System.out.println("비밀번호가 일치하지 않습니다!!");
            return;
        }
        boolean result = DAO.removeId(id);
        if(!result){
            System.out.println("삭제 실패!!!");
        }else {
            System.out.println("회원 삭제 성공!!!");
        }
    }
}

LoginServiceImpl 클래스

 

package loginDTO;

import java.io.Serializable;

public class LoginDTO implements Serializable {
    private String id, name, pwd;

    public LoginDTO() {
    }

    public LoginDTO(String id, String name, String pwd) {
        this.id = id;
        this.name = name;
        this.pwd = pwd;
    }

    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getPwd() {
        return pwd;
    }
    public void setPwd(String pwd) {
        this.pwd = pwd;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

LoginDTO 클래스

 

package loginDAO;

import loginDTO.LoginDTO;

import java.io.*;
import java.util.Random;

public class LoginDAO {
    public boolean duplicationCheck(String id) {
        // 아이디가 존재하면 false, 존재하지 않으면 true
        File path;
        path = new File("/Users/jyh/Desktop/be/java/java-start/회원정보/" + id);
        return !path.exists();
    }

    public boolean createId(LoginDTO DTO) {
        File path = new File("/Users/jyh/Desktop/be/java/java-start/회원정보/" + DTO.getId());
        try {
            FileOutputStream fos = new FileOutputStream(path);
            BufferedOutputStream bos = new BufferedOutputStream(fos);
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(DTO);

            oos.close(); bos.close(); fos.close();
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    public String logIn(String id, String pwd){
        File path;
        path = new File("/Users/jyh/Desktop/be/java/java-start/회원정보/" + id);
        String name = null;

        try {
            FileInputStream fis = new FileInputStream(path);
            ObjectInputStream ois = new ObjectInputStream(fis);
            LoginDTO dto = (LoginDTO) ois.readObject();

            if(pwd.equals(dto.getPwd())){
                name = dto.getName();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return name;
    }


    public String resetCheck(String id, String name) {
        File path = new File("/Users/jyh/Desktop/be/java/java-start/회원정보/" + id);
        Random random = new Random();
        String pwd = null;
        try {
            FileInputStream fis = new FileInputStream(path);
            BufferedInputStream bis = new BufferedInputStream(fis);
            ObjectInputStream ois = new ObjectInputStream(bis);
            LoginDTO dto = (LoginDTO) ois.readObject();

            if(name.equals(dto.getName())){
                pwd = Integer.toString(random.nextInt(100000));
                dto.setPwd(pwd);

                FileOutputStream fos = new FileOutputStream(path);
                BufferedOutputStream bos = new BufferedOutputStream(fos);
                ObjectOutputStream oos = new ObjectOutputStream(bos);
                oos.writeObject(dto);

                oos.close(); bos.close(); fos.close();
            }
            ois.close(); bis.close(); fis.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return pwd;
    }

    public boolean removeId(String id) {
        File path = new File("/Users/jyh/Desktop/be/java/java-start/회원정보/" + id);
        boolean result = path.delete();
        return result;
    }
}

LoginDAO 클래스

 

 

 

 

- 메모 -

1. 작성한 코드 중 중복하여 작성한 코드가 있는가 확인

2. 예외 처리를 구조화하여 발생할 수 있는 예외를 모두 생각해보기

3. 맥북에 DB를 설치하여 파일 입, 출력이 아닌 실제 데이터 베이스에 접근하여 쿼리문으로 데이터를 처리해보기

 

 

 

 

 

코드 동작

728x90

 

 

 

 

 

Local망 내에서 DB 접근하기

 

프로젝트를 진행하기 위해 같은 망에 연결되어 있는 PC 한 대에 Oracle DB 를 구축하고 다른 PC 로 Oracle DB 에

접근을 시도하였다.

( 클라우드에 DB 를 올리면 되지만 그건 다음 프로젝트때.... )

 

예를 들어 192.168.1.42 IP 를 할당받은 PC 에 Oracle DB 를 구축해놓고 192.168.1.13 을 사용하는 PC 에서 sqldeveloper 및 java 코드로 접속을 시도

 

 

첫 접속 시도 : 실패

- Oracle DB 에서 default 로 사용하는 포트번호인 1521 포트를 방화벽에서 오픈하지 않아 생기는 오류라고 생각

포트번호 1521 로 들어오는 TCP 접속을 허용으로 설정

 

 

두번째 접속 시도 : 실패

- 분명 방화벽은 열어줬는데 접속이 되지 않고 접속 오류문구가 출력된다...

- Oracle DB 자체 설정파일에 IP 관련 설정파일이 있을 것으로 보임

- Oracle DB 설치 파일 내부에 접속하는 IP 관련 파일을 검색하여 찾아봄

- ( C:\app\WINDOWS.X64_193000_db_home\network\admin ) 해당 위치에 있는 listner.ora 파일이 인입 IP 관련 설정 파일...

- 해당 파일의 default 값은 localhost 값만 적용되어 있으므로 현재 사용중인 IP 로도 접근이 가능하게 설정

- 해당 파일을 수정할때는 무조건 backup 파일을 생성해놓고 작업한다

- 무조건 값을 입력할때 기존 값을 복사하여 사용해야 한다 ( Linux 에서 작성된 파일로 사용되는 공백 등의 키 값이 다르기 때문...!!! )

원본 파일                                                       >                                                       수정 파일

 

 

세번째 접속 시도 : 실패

- 분명 설정파일까지 변경해줬는데도 로컬망 내에서 접속이 불가능.....

- 혹시 설정 파일을 변경 해줬는데 프로그램(서비스)는 계속 동작중이니 변경사항이 데몬에 적용되지 않아 발생되는 문제인가 생각...

- Oracle DB 와 관련된 서비스 검색하여 전부 중지 > 시작 과정 진행

Oracle 관련 활성 서비스 모두 중지 > 시작

 

 

네번째 접속 시도 : 성공

- sqldeveloper 및 이클립스, intelliJ 에서 정상적으로 접속되는 것 확인!!!

intelliJ 접속 확인

 

 

sqldeveloper 접속 확인

 

728x90

 

 

 

 

 

DB 연동 실습

 

eclipse 파일 세팅

 

 

!! DB 는 기존에 생성해놨던 member_test 테이블을 사용 !!

 

 

                             

DB 연동 순서

프로젝트 라이브러리에 jdbc 를 추가 (위 동영상 참고) > module-info 에 라이브러리 추가 문구 작성 > 오라클 명령어를 사용할 수 있게 드라이버를 연동 ( Class.forName("oracle.jdbc.driver.OracleDriver") > Connection 객체를 통해 DB 연결 > PreparedStatement 객체를 통해 명령어를 DB 에 전송 > ResultSet 객체를 통해 명령어 수행 결과를 저장하여 출력

                             

 

package ex01.service;

public interface MemberService {
	// 회원 보기 기능 구현
	public void memberView();
	// 회원 수정 기능 구현
	public void modify();
}

MemberService 인터페이스

 

package ex01.service;

import java.util.ArrayList;
import java.util.Scanner;

import ex01.dao.MemberDAO;
import ex01.dto.MemberDTO;

public class MemberServiceImpl implements MemberService {
	private MemberDAO dao;
	public MemberServiceImpl() {
		// 기본 생성자를 통해 db 서버에 접속
		dao = new MemberDAO();
	}
	
	public void memberView() {
		System.out.println("회원 보기 기능");
		ArrayList<MemberDTO> members = dao.getMembers();
		if(members.size() == 0) {
			System.out.println("등록된 정보가 없습니다.");
		}else {
			for(int i=0; i<members.size(); i++) {
				MemberDTO m = members.get(i);
				System.out.println();
				System.out.println("id : " + m.getId());
				System.out.println("pwd : " + m.getPwd());
				System.out.println("name : " + m.getName());
				System.out.println("age : " + m.getAge());
				System.out.println();
			}
		}
	}
	public void modify() {
		System.out.println("수정 기능");
		Scanner input = new Scanner(System.in);
		String id, pwd, name;
		int age;
		
		while(true) {
			System.out.print("수정할 아이디 입력 : ");
			id = input.next();
			MemberDTO m = dao.memberChk(id);
			if(m != null) {
				break;
			}else {
				System.out.println("존재하지 않는 id 입니다....");
			}
		}
		
		System.out.print("수정할 패스워드 입력 : ");
		pwd = input.next();
		System.out.print("수정할 이름 입력 : ");
		name = input.next();
		System.out.print("수정할 나이 입력 : ");
		age = input.nextInt();
		
		MemberDTO dto = new MemberDTO();
		dto.setId(id);
		dto.setPwd(pwd);
		dto.setName(name);
		dto.setAge(age);
		//int result = dao.modify(dto);
		int result = dao.modify(id,pwd, name, age);
		
		if(result == 1) {
			System.out.println("수정되었습니다.");
		}else {
			System.out.println("수정 실패!!!");
		}
	}
}

MemberServiceImpl 클래스

 

package ex01.main;

import java.util.Scanner;

import ex01.service.MemberService;
import ex01.service.MemberServiceImpl;

public class MainClass {
	public static void main(String[] args) {
		Scanner input = new Scanner(System.in);
		// 생성자 호출하여 db 로 연결
		MemberService ms = new MemberServiceImpl();
		int num;
		while(true) {
			System.out.println();
			System.out.println("1. 회원 보기");
			System.out.println("2. 회원 수정");
			System.out.println("3. 종 료");
			System.out.print(">>> : ");
			num = input.nextInt();
			switch(num) {
			case 1: 
				ms.memberView();
				break;
			case 2: 
				ms.modify();
				break;
			case 3: 
				System.out.println("프로그램 종료!!!");
				return;
			}
		}
	}
}

MainClass 클래스

 

package ex01.dto;

public class MemberDTO {
	private String id, pwd, name;
	private int age;
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getPwd() {
		return pwd;
	}
	public void setPwd(String pwd) {
		this.pwd = pwd;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
}

MemberDTO 클래스

 

package ex01.dao;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

import ex01.dto.MemberDTO;

public class MemberDAO {
	private Connection con;
	private PreparedStatement ps;
	private ResultSet rs;
	public MemberDAO() {
		try {
			// oracle 드라이버 호출
			Class.forName("oracle.jdbc.driver.OracleDriver");
			// db 경로
			String url = "jdbc:oracle:thin:@localhost:1521:orcl";
			// db 계정정보 확인
			String id = "c##youngho3358", pwd = "1234";
			con = DriverManager.getConnection(url, id, pwd);
		}catch(Exception e) {
			e.printStackTrace();
		}
	}


	public ArrayList<MemberDTO> getMembers() {
		String sql = "select * from member_test";
		ArrayList<MemberDTO> mem = new ArrayList<>();
		try {
			ps = con.prepareStatement(sql);
			rs = ps.executeQuery();

			while(rs.next()) {
				MemberDTO dto = new MemberDTO();
				dto.setId(rs.getString("id"));
				dto.setPwd(rs.getString("pwd"));
				dto.setName(rs.getString("name"));
				dto.setAge(rs.getInt("age"));
				mem.add(dto);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return mem;
	}


	public MemberDTO memberChk(String id) {
		String sql = "select * from member_test where id=?";
		MemberDTO dto = null;
		try {
			ps = con.prepareStatement(sql);
			ps.setString(1, id);
			rs = ps.executeQuery();
			if(rs.next()) {
				dto = new MemberDTO();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return dto;
	}


	public int modify(MemberDTO dto) {
		String sql = "update memebr_test set pwd=?, name=?, age=? where id=?";
		int result = 0;
		try {
			ps = con.prepareStatement(sql);
			ps.setString(1, dto.getPwd());
			ps.setString(2, dto.getName());
			ps.setInt(3, dto.getAge());
			ps.setString(4, dto.getId());

			// executeUpdate 는 쿼리문이 정상적으로 실행되면 1 반환, 오류면 0 반환
			result = ps.executeUpdate();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}


	public int modify(String id, String pwd, String name, int age) {
		System.out.println("매개변수 4개 modify 실행!!!!!!");
		String sql = "update member_test set pwd=?, name=?, age=? where id=?";
		int result = 0;
		try {
			ps = con.prepareStatement(sql);
			ps.setString(1, pwd);
			ps.setString(2, name);
			ps.setInt(3, age);
			ps.setString(4, id);

			// executeUpdate 는 쿼리문이 정상적으로 실행되면 1 반환, 오류면 0 반환
			result = ps.executeUpdate();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return result;
	}
}

MemberDAO 클래스

728x90

+ Recent posts