본문 바로가기

STUDY/국비과정

[JAVA 웹 개발 공부] 국비지원 45일차 - 회원가입 프로그램, GeneratedKeys, regex(Regular expression)

회원가입, 회원탈퇴 프로그램 

 

 

 

 

package main;
import java.util.Scanner;

import exceptions.DataIOException;
import exceptions.InputNotValidException;
import user.UserinfoRepositoryImpl;
import user.UserinfoService;
import user.UserinfoServiceImpl;

// 간단한 입력(콘솔 입력)

// 1. 회원가입
// email 서식
// @가 하나는 포함되어있어야 함.
// @앞은 영소문자만 1~15자 문자열
// @뒤는 영소문자 or . 의 1~15자 문자열

// 이름, 성 서식
// 영소/대문자 및 한글로 표현된 1~15자 문자열

// 2. 회원탈퇴

public class Main {
	public static void main(String[] args) {
		Scanner scan = new Scanner(System.in);
		UserinfoService service = new UserinfoServiceImpl(new UserinfoRepositoryImpl());

		System.out.println("1. 회원가입 / 2. 회원탈퇴");
		int input = scan.nextInt();
		scan.nextLine();
		
		if (input == 1) {
			System.out.println("이메일, 이름, 성 입력");
			String email = scan.nextLine();
			String firstname = scan.nextLine();
			String lastname = scan.nextLine();
			
			try {
				int result = service.userin(email, firstname, lastname);
				if (result > 0) {
					System.out.println("회원가입 성공. 당신의 아이디는 " + result);
				} else if (result == UserinfoService.EMAIL_DUPLICATED) {
					System.out.println("이메일이 중복되었습니다.");
				}
//				else if (result == UserinfoService.INPUT_NOT_VALID) {
//					System.out.println("입력값 잘못됨.");
//				}
			} catch(InputNotValidException e) {
				System.out.println(e.getMessage());
			} catch (DataIOException e) {
//				Throwable t = e.getCause();
//				System.out.println(t instanceof SQLException);
//				System.out.println(t.getMessage());
				System.out.println("시스템 장애가 발생했습니다. 나중에 다시 시도해주세요.");
			}
		} else if (input == 2) {
			System.out.println("아이디 번호 입력");
			int id = scan.nextInt();
			
			int result = service.userout(id);
			
			System.out.println(result == 1 ? "삭제됨" : "삭제안됨");
		}
	}
}

 

package main;
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;

import exceptions.InputNotValidException;
import user.UserinfoRepositoryImpl;
import user.UserinfoService;
import user.UserinfoServiceImpl;

public class MainFrame extends JFrame {
	private UserinfoService service;
	
	private JPanel contentPane;
	private JTextField textField;
	private JTextField textField_1;
	private JTextField textField_2;

	private JLabel lblNewLabel_3;

	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					MainFrame frame = new MainFrame();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	private void drawResult(int result) {
		lblNewLabel_3.setText("완료 : " + result);
	}
	
	private void drawError(InputNotValidException e) {
		lblNewLabel_3.setText(e.getMessage());
	}
	
	private void userin() {
		String email = textField.getText();
		String firstname = textField_1.getText();
		String lastname = textField_2.getText();
		try {
			int result = service.userin(email, firstname, lastname);
			drawResult(result);
		} catch (InputNotValidException e) {
			drawError(e);
		}
	}
	
	public MainFrame() {
		service = new UserinfoServiceImpl(new UserinfoRepositoryImpl());
		
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 450, 300);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		contentPane.setLayout(new BorderLayout(0, 0));
		setContentPane(contentPane);
		
		JPanel panel = new JPanel();
		contentPane.add(panel, BorderLayout.CENTER);
		GridBagLayout gbl_panel = new GridBagLayout();
		gbl_panel.columnWidths = new int[]{50, 36, 116, 24, 116, 12, 0};
		gbl_panel.rowHeights = new int[]{21, 21, 0, 0};
		gbl_panel.columnWeights = new double[]{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE};
		gbl_panel.rowWeights = new double[]{0.0, 0.0, 0.0, Double.MIN_VALUE};
		panel.setLayout(gbl_panel);
		
		JLabel lblNewLabel = new JLabel("이메일");
		GridBagConstraints gbc_lblNewLabel = new GridBagConstraints();
		gbc_lblNewLabel.anchor = GridBagConstraints.WEST;
		gbc_lblNewLabel.insets = new Insets(0, 0, 5, 5);
		gbc_lblNewLabel.gridx = 1;
		gbc_lblNewLabel.gridy = 0;
		panel.add(lblNewLabel, gbc_lblNewLabel);
		
		textField = new JTextField();
		GridBagConstraints gbc_textField = new GridBagConstraints();
		gbc_textField.anchor = GridBagConstraints.NORTHWEST;
		gbc_textField.insets = new Insets(0, 0, 5, 5);
		gbc_textField.gridx = 2;
		gbc_textField.gridy = 0;
		panel.add(textField, gbc_textField);
		textField.setColumns(10);
		
		JLabel lblNewLabel_1 = new JLabel("이름");
		GridBagConstraints gbc_lblNewLabel_1 = new GridBagConstraints();
		gbc_lblNewLabel_1.anchor = GridBagConstraints.WEST;
		gbc_lblNewLabel_1.insets = new Insets(0, 0, 5, 5);
		gbc_lblNewLabel_1.gridx = 1;
		gbc_lblNewLabel_1.gridy = 1;
		panel.add(lblNewLabel_1, gbc_lblNewLabel_1);
		
		textField_1 = new JTextField();
		GridBagConstraints gbc_textField_1 = new GridBagConstraints();
		gbc_textField_1.anchor = GridBagConstraints.NORTHWEST;
		gbc_textField_1.insets = new Insets(0, 0, 5, 5);
		gbc_textField_1.gridx = 2;
		gbc_textField_1.gridy = 1;
		panel.add(textField_1, gbc_textField_1);
		textField_1.setColumns(10);
		
		JLabel lblNewLabel_2 = new JLabel("성");
		GridBagConstraints gbc_lblNewLabel_2 = new GridBagConstraints();
		gbc_lblNewLabel_2.anchor = GridBagConstraints.WEST;
		gbc_lblNewLabel_2.insets = new Insets(0, 0, 0, 5);
		gbc_lblNewLabel_2.gridx = 1;
		gbc_lblNewLabel_2.gridy = 2;
		panel.add(lblNewLabel_2, gbc_lblNewLabel_2);
		
		textField_2 = new JTextField();
		GridBagConstraints gbc_textField_2 = new GridBagConstraints();
		gbc_textField_2.anchor = GridBagConstraints.SOUTHWEST;
		gbc_textField_2.insets = new Insets(0, 0, 0, 5);
		gbc_textField_2.gridwidth = 3;
		gbc_textField_2.gridx = 2;
		gbc_textField_2.gridy = 2;
		panel.add(textField_2, gbc_textField_2);
		textField_2.setColumns(10);
		
		JPanel panel_1 = new JPanel();
		contentPane.add(panel_1, BorderLayout.SOUTH);
		
		JButton btnNewButton = new JButton("등록");
		btnNewButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				userin();
			}
		});
		panel_1.add(btnNewButton);
		
		JPanel panel_2 = new JPanel();
		contentPane.add(panel_2, BorderLayout.NORTH);
		
		lblNewLabel_3 = new JLabel("결과텍스트");
		panel_2.add(lblNewLabel_3);
	}
}

 

package user;
public class Userinfo {
	private int id;
	private String email;
	private String firstname;
	private String lastname;
	public Userinfo(int id, String email, String firstname, String lastname) {
		super();
		this.id = id;
		this.email = email;
		this.firstname = firstname;
		this.lastname = lastname;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public String getFirstname() {
		return firstname;
	}
	public void setFirstname(String firstname) {
		this.firstname = firstname;
	}
	public String getLastname() {
		return lastname;
	}
	public void setLastname(String lastname) {
		this.lastname = lastname;
	}
	@Override
	public String toString() {
		return "Userinfo [id=" + id + ", email=" + email + ", firstname=" + firstname + ", lastname=" + lastname + "]";
	}
}

 

package user;
public interface UserinfoService {
	int INPUT_NOT_VALID = -1;
	int EMAIL_DUPLICATED = -2;
	
	int userin(String email, String firstname, String lastname);
	int userout(int id);
}

 

package user;
import java.sql.Connection;
import java.sql.SQLException;

import dbutil.ConnectionProvider;
import exceptions.DataIOException;
import exceptions.InputNotValidException;

public class UserinfoServiceImpl implements UserinfoService {
	private UserinfoRepository repo;
	
	public UserinfoServiceImpl(UserinfoRepository repo) {
		super();
		this.repo = repo;
	}

	// 값 유효한지 확인(길이 및 NOT NULL)
	public boolean verifyString(String str, int length) {
		if (str == null || str.isEmpty()) {
			return false;
		}
		if (str.length() > length) {
			return false;
		}
		return true;
	}
	
	@Override
	public int userin(String email, String firstname, String lastname) throws DataIOException {
		if (!verifyString(email, 60) 
				|| !verifyString(firstname, 15)
				|| !verifyString(lastname, 15)) {
			throw new InputNotValidException("입력값 잘못됨.");
		}
		if (repo.countByEmail(email) == 1) {
			return EMAIL_DUPLICATED;
		}
		return repo.insert(email, firstname, lastname);
	}

	@Override
	public int userout(int id) {
		Connection conn = null;
		try {
			conn = ConnectionProvider.makeConnection();
			conn.setAutoCommit(false);
			
			int count = repo.countById(id, conn);
			if (count > 0) {
				int move = repo.move(id, conn);
				int result = repo.delete(id, conn);
				conn.commit();
				
				return result;
			}
		} catch (Exception e) {
			try {
				conn.rollback();
			} catch (SQLException e1) {
				e1.printStackTrace();
			}
		} finally {
			ConnectionProvider.closeConnection(conn);
		}
		return 0;
	}
}

 

package user;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import dbutil.ConnectionProvider;
import exceptions.DataIOException;

public class UserinfoRepositoryImpl implements UserinfoRepository {
	@Override
	public int countByEmail(String email) throws DataIOException {
		String sql = "SELECT count(*) AS CNT FROM userinfo WHERE email = ?";
		try (Connection conn = ConnectionProvider.makeConnection();
				PreparedStatement stmt = conn.prepareStatement(sql)) {
			stmt.setString(1, email);
			
			try (ResultSet rs = stmt.executeQuery()) {
				if (rs.next()) {
					return rs.getInt("CNT");
				}
			}
		} catch (SQLException e) {
			throw new DataIOException(e);
		}
		return 0;
	}

	@Override
	public Userinfo selectByEmail(String email) {
		String sql = "SELECT id, email, firstname, lastname FROM userinfo WHERE email = ?";
		try (Connection conn = ConnectionProvider.makeConnection();
				PreparedStatement stmt = conn.prepareStatement(sql)) {
			stmt.setString(1, email);
			
			try (ResultSet rs = stmt.executeQuery()) {
				if (rs.next()) {
					int id = rs.getInt("id");
					String e = rs.getString("email");
					String firstname = rs.getString("firstname");
					String lastname = rs.getString("lastname");
					
					return new Userinfo(id, e, firstname, lastname);
				}
			}
		} catch (SQLException e) {
			throw new DataIOException(e);
		}
		return null;
	}

	@Override
	public int insert(String email, String firstname, String lastname) {
		String insert = "INSERT INTO userinfo (email, firstname, lastname) VALUES (?, ?, ?)";
//		String lastId = "SELECT LAST_INSERT_ID()";
		try (Connection conn = ConnectionProvider.makeConnection();
				PreparedStatement stmt
					= conn.prepareStatement(insert, Statement.RETURN_GENERATED_KEYS);
				// PreparedStatement stmtSelect = conn.prepareStatement(lastId)
						) {
			stmt.setString(1, email);
			stmt.setString(2, firstname);
			stmt.setString(3, lastname);
			
			stmt.executeUpdate();
			
			try (ResultSet rs = stmt.getGeneratedKeys()) {
				if(rs.next()) {
					return rs.getInt(1);
				}
			}
		} catch (SQLException e) {
			throw new DataIOException(e);
		}
		return 0;
	}

	@Override
	public int countById(int id, Connection conn) {
		String sql = "SELECT count(*) FROM userinfo WHERE id = ?";
		try (PreparedStatement stmt = conn.prepareStatement(sql)) {
			stmt.setInt(1, id);
			
			try (ResultSet rs = stmt.executeQuery()) {
				if (rs.next()) {
					return rs.getInt(1);
				}
			}
		} catch (SQLException e) {
			throw new DataIOException(e);
		}
		return 0;
	}

	@Override
	public int move(int id, Connection conn) {
		String sql = "INSERT INTO userinfo_inactive (id, email, firstname, lastname)"
				+ " SELECT id, email, firstname, lastname FROM userinfo WHERE id = ?";
		try (PreparedStatement stmt = conn.prepareStatement(sql)) {
			stmt.setInt(1, id);
			
			int result = stmt.executeUpdate();
			
			return result;
		} catch (SQLException e) {
			throw new DataIOException(e);
		}
	}

	@Override
	public int delete(int id, Connection conn) {
		String sql = "DELETE FROM userinfo WHERE id = ?";
		try (PreparedStatement stmt = conn.prepareStatement(sql)) {
			stmt.setInt(1, id);
			
			return stmt.executeUpdate();
		} catch (SQLException e) {
			throw new DataIOException(e);
		}
	}
}

 

package user;
import java.sql.Connection;

public interface UserinfoRepository {
	int countByEmail(String email);
	Userinfo selectByEmail(String email);
	int insert(String email, String firstname, String lastname); // pk 반환
	
	int countById(int id, Connection conn);
	int move(int id, Connection conn);
	int delete(int id, Connection conn);
}

 

package exceptions;
public class InputNotValidException extends RuntimeException {
	public InputNotValidException(String message) {
		super(message);
	}
}

 

package exceptions;
public class DataIOException extends RuntimeException {
	// SQL예외 객체의 참조 - 네트워크 접속안됐거나.. id 비밀번호 오류... 예외를 포장만한거
	public DataIOException(Throwable cause) {
		super(cause);
	}
}

 

 

 

테이블 행 추가하면서 PK 값 구하기

 

*LAST_INSERT_ID()

public int insert(String email, String firstname, String lastname) {
    String insert = "INSERT INTO userinfo (email, firstname, lastname) VALUES (?, ?, ?)";
    String lastId = "SELECT LAST_INSERT_ID() AS lastID";
    try (Connection conn = ConnectionProvider.makeConnection();
            PreparedStatement pstmt = conn.prepareStatement(insert);
            PreparedStatement pstmt2 = conn.prepareStatement(lastId)) {
        pstmt.setString(1, email);
        pstmt.setString(2, firstname);
        pstmt.setString(3, lastname);

        pstmt.executeUpdate();

        try (ResultSet rs = pstmt2.executeQuery()) {
            if (rs.next()) {
                return rs.getInt("lastID");
            }
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }
    return 0;
}

 

*Statement.RETURN_GENERATED_KEYS

*getGeneratedKeys()

public int insert(String email, String firstname, String lastname) {
    String insert = "INSERT INTO userinfo (email, firstname, lastname) VALUES (?, ?, ?)";
    try (Connection conn = ConnectionProvider.makeConnection();
            PreparedStatement pstmt = conn.prepareStatement(insert, Statement.RETURN_GENERATED_KEYS);) {
        pstmt.setString(1, email);
        pstmt.setString(2, firstname);
        pstmt.setString(3, lastname);

        pstmt.executeUpdate();

        try (ResultSet rs = pstmt.getGeneratedKeys()) {
            if (rs.next()) {
                return rs.getInt(1);
            }
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }
    return 0;
}

 

 

regex(Regular expression)

 

1. Pattern
정규 표현식이 컴파일된 클래스. 정규 표현식에 대상 문자열을 검증하거나, 활용하기 위해 사용되는 클래스이다. 

 

2. Matcher
Pattern클래스를 받아 대상 문자열과 패턴이 일치하는 부분을 찾거나 전체 일치 여부 등을 판별하기 위해 사용된다. 

 

*연습

String line = "Hi. This is a book.";

// 정규표현식 : regex(Regular expression)
// Pattern 객체
Pattern p = Pattern.compile("is");
// Matcher 객체
Matcher m = p.matcher(line);

while (m.find()) {
    System.out.println(m.start());
    System.out.println(m.end());
}
6
8
9
11
String inputABC = "abcdef";
String input123 = "123456";

Pattern p = Pattern.compile("abcdef");
Matcher m = p.matcher(inputABC);
System.out.println(m.matches()); // true

Pattern p1 = Pattern.compile("[a-z]{6}"); // a부터z까지 길이6
Matcher m1 = p1.matcher(inputABC);
System.out.println(m1.matches()); // true

Pattern p2 = Pattern.compile("[0-9]{6}"); // 0부터9까지 길이6
Matcher m2 = p2.matcher(input123);
System.out.println(m2.matches()); // true

 

\\d → [0-9]
\\w → [a-zA-Z0-9] (알파벳이나 숫자)
\\w+ → 한개 이상으로 이루어진 알파벳이나 숫자 문자열 
[a-f|z] → a~f 또는 z
[a-zA-Zㄱ-힣]{5,} → 영소문자/대문자나 한글로 이루어진 문자열로 길이는 5이상

 

*전화번호 확인

// 전화번호 형식 : 010-####-#### (#은 숫자)
Scanner scan = new Scanner(System.in);
System.out.println("전화번호 입력");
String phone = scan.nextLine();

Pattern p = Pattern.compile("010-[0-9]{4}-\\d{4}");
System.out.println(p.matcher(phone).matches());

 

*아이디, 비밀번호 확인

// 사용자 아이디를 입력받아 유효한지 확인
// 아이디 형식 : 
// 1. 영소문자로 시작하며, 영문자 또는 숫자로 이루어져야 한다.
// 2. 영소/대문자 또는 숫자로 이루어져야 한다.
// 3. 길이값은 최소:3, 최대:15
System.out.println("아이디 입력");
String id = scan.nextLine();

Pattern p2 = Pattern.compile("[a-z]{1}\\w{2,14}");
System.out.println(p2.matcher(id).matches());

// 사용자 비밀번호 입력받아 유효한지 확인
// 비밀번호 형식 : 특수문자를 포함한 최소:8자리, 최대:20자리 문자열
System.out.println("비밀번호 입력");
String pw = scan.nextLine();

Pattern p3 = Pattern.compile("[a-zA-Z0-9!@#$%^&*()]{8,20}");
System.out.println(p3.matcher(pw).matches());

 

*group

String line = "[name:parkmin, age:18],[name:dooli, age:22]";

Pattern p = Pattern.compile("\\[name:(\\w+), age:(\\d+)\\]");
Matcher m = p.matcher(line);

while (m.find()) {
    System.out.println(m.group(1)); 
    System.out.println(m.group(2));
}
parkmin
18
dooli
22