본문 바로가기
My Project/Pet Shopping Mall GUI Project

[개발 일지] 반려동물 용품 쇼핑몰 GUI 구현 프로젝트 1일차 (03/10)

by 스응 2023. 3. 12.
728x90
728x90

개인 프로젝트 주제

Swing을 이용하여 반려동물 용품 쇼핑몰 DB 접근 프로그램을 GUI로 구현하기

 

프로젝트 기간

시간이 날 때마다 비정기적으로 진행할 예정

 

깃허브 주소

https://github.com/seoyounglee0105/ShopDB_GUI_Project

 

개발 계획

1. 로그인 프레임

  - 회원가입 버튼

  - 비밀번호 찾기 버튼

 

2. 회원가입 프레임 

  - 아이디 중복 확인 기능

  - 항목 형식 힌트 (글자 수 제한 등)

  - member 테이블에 회원 정보를 INSERT하는 기능

  - 필수 값 중 입력되지 않은 값이 있으면 회원가입 거부

 

3. 비밀번호 찾기 프레임

 

4. 마이페이지 프레임

  - 정보 수정 버튼 (비밀번호를 다시 입력받아서 본인 확인)

  - 주문 내역

  - 쿠폰함

  - 장바구니

 

5. 쇼핑몰 홈 프레임

  - 로그아웃 버튼 → 로그인 프레임을 다시 띄움

  - 마이페이지 버튼 

  - 카테고리별로 상품을 출력하는 기능

 

6. 상품 상세 페이지 프레임

  - 장바구니에 넣는 기능

 

 

반응형
728x90

1일차

  - 회원(Member) 테이블 생성

  - 회원가입 기능 구현

  - 로그인 기능 구현

 

회원 테이블 생성

더보기
CREATE TABLE member (
    id VARCHAR(15) PRIMARY KEY,  -- 아이디
    password VARCHAR(20) NOT NULL,  -- 비밀번호
    member_grade VARCHAR(10) NOT NULL DEFAULT '브론즈',  -- 회원 등급 (외래키)
    name VARCHAR(10) NOT NULL,  -- 이름
    phone_number VARCHAR(13) NOT NULL,  -- 전화번호
    address VARCHAR(100) NOT NULL,  -- 주소
    FOREIGN KEY (member_grade) REFERENCES grade(name) 
);

 

  - 처음 가입한 회원들은 자동으로 '브론즈' 등급을 할당받음

 

회원 등급 테이블 생성 및 데이터 삽입

더보기
CREATE TABLE grade (
    name VARCHAR(10) PRIMARY KEY
);

INSERT INTO grade
VALUES
    ('플래티넘'),
    ('골드'),
    ('실버'),
    ('브론즈');

 

DBHelper 클래스 설계

더보기
public class DBHelper {

    private static final String DB_HOST = "localhost";
    private static final String DB_PORT = "3306";
    private static final String DB_DATABASE_NAME = "my_shopdb";
    private static final String DB_CHARSET = "UTF-8";
    private static final String DB_USER = "root";
    private static final String DB_PASSWORD = "1234";

    private Connection connection;

    // 싱글톤 패턴 객체 만들기

    // 1. 
    private static DBHelper dbHelper;

    // 2. private 생성자
    private DBHelper() {

    }

    // 3. 
    public static DBHelper getInstance() {
        if (dbHelper == null) {
            dbHelper = new DBHelper();
        }
        return dbHelper;
    }

    public Connection getConnection() {
        if (connection == null) {
            String urlFormat = "jdbc:mysql://%s:%s/%s?serverTimezone=Asia/Seoul&characterEncoding=%s";
            String url = String.format(urlFormat, DB_HOST, DB_PORT, DB_DATABASE_NAME, DB_CHARSET);

            // 동적 로딩 (리플렉션 기법)
            try {
                Class.forName("com.mysql.cj.jdbc.Driver");
                connection = DriverManager.getConnection(url, DB_USER, DB_PASSWORD);
                System.out.println("Connection Success");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return connection;
    } // end of getConnection

    public void closeConnection() {
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

 

MemberDTO 클래스 설계

더보기
public class MemberDTO {

    // member 테이블의 컬럼 값을 받을 멤버 변수
    private String id;
    private String password;
    private String member_grade;
    private String name;
    private String phone_number;
    private String address;

    // 생성자
    public MemberDTO(String id, String password, String member_grade, String name, 
                     String phone_number, String address, String email) {
        this.id = id;
        this.password = password;
        this.member_grade = member_grade;
        this.name = name;
        this.phone_number = phone_number;
        this.address = address;
    }

    // get, set 메서드
}

 

MemberDAO - 회원 가입 기능

더보기
// 회원 가입 기능
@Override
public int memberSignUp(String id, String password, String name, String phoneNumber, String address) {
    result = 0; // 초기화

    String sql = " INSERT INTO member(id, password, name, phone_number, address) " 
               + " VALUES (?, ?, ?, ?, ?) ";

    try {
        pstmt = conn.prepareStatement(sql);
        pstmt.setString(1, id);
        pstmt.setString(2, password);
        pstmt.setString(3, name);
        pstmt.setString(4, phoneNumber);
        pstmt.setString(5, address);
        result = pstmt.executeUpdate();

    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        try {
            pstmt.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    return result;
}

// 아이디 중복 확인 기능
@Override
public int memberIdCheck(String id) {
    result = 0; // 초기화

    String sql = " SELECT * FROM member WHERE id = ? ";

    try {
        pstmt = conn.prepareStatement(sql);
        pstmt.setString(1, id);
        rs = pstmt.executeQuery();

        // 행이 존재한다면 while문으로 들어감
        while (rs.next()) {
            result = 1; // 아이디 중복
        }

    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        try {
            rs.close();
            pstmt.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    return result;
}

 

MemberDAO - 로그인 기능

더보기
// 로그인 기능
@Override
public int memberLogin(String id, String password) {
    result = 0; // 초기화

    String sql = " SELECT * FROM member " + " WHERE id = ? AND password = ? ";

    try {
        pstmt = conn.prepareStatement(sql);
        pstmt.setString(1, id);
        pstmt.setString(2, password);
        rs = pstmt.executeQuery();

        // 행이 존재한다면 while문으로 들어감
        while (rs.next()) {
            result = 1;
        }

    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        try {
            rs.close();
            pstmt.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    return result;
}

 

LoginFrame (Main)

더보기
public class LoginFrame extends JFrame implements ActionListener {

    private JPanel panel1;
    private JLabel idLabel; // 아이디
    private JTextField idTextField; // 아이디 입력창
    private JLabel pwLabel; // 비밀번호
    private JPasswordField pwPasswordField; // 비밀번호 입력창
    private JButton loginButton; // 로그인 버튼

    private JPanel panel2;
    private JButton signUpButton; // 회원가입 버튼
    private JButton pwFindButton; // 비밀번호 찾기 버튼

    private Color backgroundColor;
    private int isSuccess = 0;

    public LoginFrame() {
        initData();
        setInitLayout();
        addEventListener();
    }

    private void initData() {
        setTitle("로그인");
        setSize(400, 300);

        panel1 = new JPanel();
        idLabel = new JLabel("    아이디");
        idTextField = new JTextField(10);
        pwLabel = new JLabel("비밀번호");
        pwPasswordField = new JPasswordField(10);
        loginButton = new JButton("로그인");

        panel2 = new JPanel();
        signUpButton = new JButton("회원 가입");
        pwFindButton = new JButton("비밀번호 찾기");
    }

    private void setInitLayout() {
        setLayout(null);
        setResizable(false);	
        setLocationRelativeTo(null);
        Color backgroundColor = new Color(200, 235, 226);
        getContentPane().setBackground(backgroundColor);

        // panel1
        panel1.setSize(200, 55);
        panel1.setLocation(40, 70);
        panel1.setBackground(backgroundColor);
        add(panel1);

        panel1.add(idLabel);
        panel1.add(idTextField);
        panel1.add(pwLabel);
        panel1.add(pwPasswordField);

        loginButton.setSize(80, 40);
        loginButton.setLocation(240, 77);
        add(loginButton);	

        // panel2
        panel2.setSize(400, 100);
        panel2.setLocation(0, 180);
        panel2.setBackground(backgroundColor);
        add(panel2);

        panel2.add(signUpButton);
        panel2.add(pwFindButton);

        setVisible(true);
    }

    private void addEventListener() {
        signUpButton.addActionListener(this);
        loginButton.addActionListener(this);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        JButton targetButton = (JButton) e.getSource();

        if (targetButton == signUpButton) {
            new SignUpFrame();

        } else if (targetButton == loginButton) {
            String id = idTextField.getText();
            char[] pwChar = pwPasswordField.getPassword();
            String pw = new String(pwChar);

            MemberDAO memberDAO = new MemberDAO();
            isSuccess = memberDAO.memberLogin(id, pw);

            if (isSuccess == 1) {
                System.out.println("로그인에 성공했습니다!");
                // 확인을 누르면 로그인 프레임 종료
                JOptionPane.showMessageDialog(null, "로그인 완료", "로그인 성공", JOptionPane.PLAIN_MESSAGE);
                System.exit(0);
            } else {
                System.out.println("로그인에 실패했습니다.");
                JOptionPane.showMessageDialog(null, "아이디나 비밀번호를 확인해주세요.", "로그인 실패", JOptionPane.PLAIN_MESSAGE);				
            }
        }
    }

    public static void main(String[] args) {
        new LoginFrame();
    }
}

 

SignUpFrame

더보기
public class SignUpFrame extends JFrame implements ActionListener, MouseListener {

    private JPanel parentPanel1;

    private JPanel panel1;
    private JLabel idLabel; // 아이디
    private JTextField idTextField; // 아이디 입력창
    private JButton idCheckButton; // 중복확인 버튼

    private JPanel panel2;
    private JLabel pwLabel; // 비밀번호
    private JPasswordField pwPasswordField; // 비밀번호 입력창

    private JPanel panel3;
    private JLabel nameLabel; // 이름
    private JTextField nameTextField; // 이름 입력창

    private JPanel panel4;
    private JLabel phoneLabel; // 전화번호
    private JTextField phoneTextField; // 전화번호 입력창

    private JPanel panel5;
    private JLabel addrLabel; // 주소
    private JTextField addrTextField; // 주소 입력창

    private JPanel parentPanel2;

    private JPanel panel6;
    private JButton signUpButton; // 회원가입 버튼
    private Color backgroundColor;

    private JTextField[] textFields = new JTextField[4];
    private int phoneNumberHintCount = 0;

    public SignUpFrame() {
        initData();
        setInitLayout();
        addEventListener();
    }

    private void initData() {
        setTitle("회원가입");
        setSize(400, 350);

        parentPanel1 = new JPanel();
        panel1 = new JPanel();
        idLabel = new JLabel("     아이디");
        idTextField = new JTextField("", 10);
        idCheckButton = new JButton("중복 확인");

        panel2 = new JPanel();
        pwLabel = new JLabel("비밀번호");
        pwPasswordField = new JPasswordField(10);

        panel3 = new JPanel();
        nameLabel = new JLabel("        이름");
        nameTextField = new JTextField("", 10);

        panel4 = new JPanel();
        phoneLabel = new JLabel("전화번호");
        phoneTextField = new JTextField("010-0000-0000", 10);

        panel5 = new JPanel();
        addrLabel = new JLabel("        주소");
        addrTextField = new JTextField("", 20);

        parentPanel2 = new JPanel();
        panel6 = new JPanel();
        signUpButton = new JButton("회원가입");

        textFields[0] = idTextField;
        textFields[1] = nameTextField;
        textFields[2] = phoneTextField;
        textFields[3] = addrTextField;

    }

    private void setInitLayout() {
        add(parentPanel1, BorderLayout.CENTER);
        parentPanel1.setBackground(backgroundColor);
        add(parentPanel2, BorderLayout.SOUTH);
        parentPanel2.setBackground(backgroundColor);

        parentPanel1.setLayout(new FlowLayout(FlowLayout.LEFT, 40, 18));
        setResizable(false);
        // 뜨는 위치 지정하는 법 알아보기
        setLocationRelativeTo(null); // JFrame 가운데 배치
        Color backgroundColor = new Color(200, 235, 226);
        getContentPane().setBackground(backgroundColor);

        parentPanel1.add(panel1);
        panel1.add(idLabel, FlowLayout.LEFT);
        panel1.add(idTextField);
        panel1.add(idCheckButton);
        panel1.setBackground(backgroundColor);

        parentPanel1.add(panel2);
        panel2.add(pwLabel);
        panel2.add(pwPasswordField);
        panel2.setBackground(backgroundColor);

        parentPanel1.add(panel3);
        panel3.add(nameLabel);
        panel3.add(nameTextField);
        panel3.setBackground(backgroundColor);

        parentPanel1.add(panel4);
        panel4.add(phoneLabel);
        panel4.add(phoneTextField);
        panel4.setBackground(backgroundColor);

        parentPanel1.add(panel5);
        panel5.add(addrLabel);
        panel5.add(addrTextField);
        panel5.setBackground(backgroundColor);

        parentPanel2.add(panel6);
        panel6.add(signUpButton);
        panel6.setBackground(backgroundColor);

        setVisible(true);
    }

    private void addEventListener() {
        signUpButton.addActionListener(this);
        idCheckButton.addActionListener(this);
        phoneTextField.addMouseListener(this);
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        JButton targetButton = (JButton) e.getSource();
        int result = 0;

        // 아이디 중복확인 버튼
        if (targetButton == idCheckButton) {
            // 방어적 코드 (입력되지 않은 값이 있다면 실행 X)
            if (idTextField.getText().isEmpty()) {
                System.out.println("값이 입력되지 않았습니다.");
                return;
            }
            String id = textFields[0].getText();

            MemberDAO memberDAO = new MemberDAO();
            result = memberDAO.memberIdCheck(id);

            // 아이디가 중복되었다면
            if (result == 1) {
                JOptionPane.showMessageDialog(null, "이미 존재하는 아이디입니다.", "", JOptionPane.PLAIN_MESSAGE);	
            } else {				
                JOptionPane.showMessageDialog(null, "사용 가능한 아이디입니다.", "", JOptionPane.PLAIN_MESSAGE);	
            }

        // 회원가입 버튼
        } else if (targetButton == signUpButton) {
            // 방어적 코드 (입력되지 않은 값이 있다면 실행 X)
            for (int i = 0; i < textFields.length; i++) {
                if (textFields[i].getText().isEmpty()) {
                    System.out.println("모든 값을 입력해주세요.");
                    JOptionPane.showMessageDialog(null, "모든 값을 입력해주세요.", "회원가입 실패", JOptionPane.PLAIN_MESSAGE);
                    return;
                }
            }
            if (new String(pwPasswordField.getPassword()).isEmpty()) {
                System.out.println("모든 값을 입력해주세요.");
                JOptionPane.showMessageDialog(null, "모든 값을 입력해주세요.", "회원가입 실패", JOptionPane.PLAIN_MESSAGE);
                return;
            }

            String id = textFields[0].getText();
            char[] pwChar = pwPasswordField.getPassword();
            String pw = new String(pwChar);
            String name = textFields[1].getText();
            String phoneNumber = textFields[2].getText();
            String address = textFields[3].getText();

            MemberDAO memberDAO = new MemberDAO();
            result = memberDAO.memberSignUp(id, pw, name, phoneNumber, address);

            if (result == 1) {
                System.out.println("회원가입에 성공했습니다!");
                // 확인을 누르면 회원가입 프레임 종료
                JOptionPane.showMessageDialog(null, "회원가입에 성공했습니다!", "회원가입 성공", JOptionPane.PLAIN_MESSAGE);
                this.dispose();
            } else {
                JOptionPane.showMessageDialog(null, "중복되거나 입력되지 않은 값이 있는지 확인해주세요.", "회원가입 실패", JOptionPane.PLAIN_MESSAGE);				
            }
        }
    } // end of method

    @Override
    public void mouseClicked(MouseEvent e) {
    }

    @Override
    public void mousePressed(MouseEvent e) {
        JTextField targetTextField = (JTextField) e.getSource();

        if (targetTextField == phoneTextField) {
            phoneNumberHintCount++;

            // 처음 눌렀을 때만 힌트가 없어지도록
            if (phoneNumberHintCount == 1) {
                targetTextField.setText("");
            }
        }
    }

    @Override
    public void mouseReleased(MouseEvent e) {
    }

    @Override
    public void mouseEntered(MouseEvent e) {
    }

    @Override
    public void mouseExited(MouseEvent e) {
    }

}

 

 


실행

 


개선할 것

  1) member 테이블

      - '생일'을 NULL 허용 컬럼으로 추가

          → 나중에 쿠폰함을 만들어서 CURDATE()로 오늘 생일이면 쿠폰을 주는 기능을 추가하고 싶음

      - phone_number를 UNIQUE로 변경

  2) SignUpFrame

      - 아이디, 비밀번호도 전화번호처럼 힌트가 표시되도록 하기 (글자 수 제한)

          → 힌트인 상태로 회원가입되지 않도록 조건도 달아야 함

      - 힌트는 버튼을 한 번 클릭하면 사라지도록 하려고 int 변수를 활용했는데,

         그 대신에 Boolean 변수를 활용하는 게 좀 더 직관적일 것 같음

      - 비밀번호 확인 기능 만들기

          → 회원 가입 버튼을 눌렀을 때 비밀번호 칸과 비밀번호 확인 칸의 값이 서로 다르면 경고 메시지

      - 형식에 맞지 않는 값을 입력하면 회원가입이 되지 않도록 하기

  3) LoginFrame

      - Login 메서드의 반환 값을 DTO 객체로 해서, 쇼핑몰 홈 프레임의 매개변수로 넣기

 

320x100
반응형

댓글