반응형

 

MVC 패턴

 

: 사용자 인터페이스, 데이터 및 논리 제어를 구현하는데 사용되는 소프트웨어 디자인 패턴을 이야기 한다.

Model, View, Controller 의 구성으로 구성되어 있다.

 

MVC 패턴

 

Controller : 화면의 이동

Model : 데이터

View : 출력

 

 

- 진행 방향

controller > service > dao > jdbc DB
controller < service < dao <

 

controller : 화면의 이동

service : 알고리즘 적인 정보 ex) 어떤 데이터를 가져와야 하는지, 정렬이라던지

dao : sql문

jdbc DB : DB에 접근

 

 


 

하단의 테이블을 생성 후 데이터를 삽입하여 진행하였다.

 

테이블 생성

 

데이터 삽입, delyn의 경우 전부 N으로 집어 넣는다.

 

 

예시 프로젝트는 아래와 같다.

JDBCUtil 의 경우 user의 명과 비밀번호를 수정하여 진행해야한다.

최종적인 프로젝트 파일은 바로 하단에 접기로 기입해놓았다.

 

package util;

import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class JDBCUtil {
	/*
	 * JDBC를 좀 더 쉽고 편하게 사용하기 위한 Utility 클래스
	 * 
	 * Map<String, Object> selectOne(String sql)
	 * Map<String, Object> selectOne(String sql, List<Object> param)
	 * List<Map<String, Object>> selectList(String sql)
	 * List<Map<String, Object>> selectList(String sql, List<Object> param)
	 * int update(String sql)
	 * int update(String sql, List<Object> param)
	 * */
	
	// 싱글톤 패턴 : 인스턴스의 생성을 제한하여 하나의 인스턴스만 사용하는 디자인 패턴
	
	// 인스턴스를 보관할 변수
	private static JDBCUtil instance = null;
	// JDBCUtil 객체를 만들 수 없게(인스턴스화 할 수 없게) private으로 제한함
	private JDBCUtil() {} 
	public static JDBCUtil getInstance() {
		if(instance == null) 
			instance = new JDBCUtil();
		return instance;
	}
	
	private String url = "jdbc:oracle:thin:@localhost:1521:xe";
	private String user = ""; // DB user 명
	private String password = ""; // DB 비밀번호
	
	private Connection conn = null;
	private ResultSet rs = null;
	private PreparedStatement ps = null;
	
	public List<Map<String, Object>> selectList(String sql, List<Object> param){
		// sql => "SELECT * FROM MEMBER WHERE MEM_ADD1 LIKE '%'||?||'%'"
		// sql => "SELECT * FROM JAVA_BOARD WHERE WRITER=?"
		// sql => "SELECT * FROM JAVA_BOARD WHERE BOARD_NUM > ?"
		List<Map<String, Object>> result = null;
		try {
			conn = DriverManager.getConnection(url, user, password);
			ps = conn.prepareStatement(sql);
			for(int i = 0; i < param.size(); i++) {
				ps.setObject(i + 1, param.get(i));
			}
			rs = ps.executeQuery();
			ResultSetMetaData rsmd = rs.getMetaData();
			int columnCount = rsmd.getColumnCount();
			while(rs.next()) {
				if(result == null) result = new ArrayList<>();
				Map<String, Object> row = new HashMap<>();
				for(int i = 1; i <= columnCount; i++) {
					String key = rsmd.getColumnLabel(i);
					Object value = rs.getObject(i);
					row.put(key, value);
				}
				result.add(row);
			}
		}catch(SQLException e) {
			e.printStackTrace();
		}finally {
			if(rs != null) try { rs.close(); } catch(Exception e) {}
			if(ps != null) try { ps.close(); } catch(Exception e) {}
			if(conn != null) try { conn.close(); } catch(Exception e) {}
		}
		return result;
	}
	
	public List<Map<String, Object>> selectList(String sql){
		// sql => "SELECT * FROM MEMBER"
		// sql => "SELECT * FROM JAVA_BOARD"
		// sql => "SELECT * FROM JAVA_BOARD WHERE BOARD_NUM > 10"
		List<Map<String, Object>> result = null;
		try {
			conn = DriverManager.getConnection(url, user, password);
			ps = conn.prepareStatement(sql);
			rs = ps.executeQuery();
			ResultSetMetaData rsmd = rs.getMetaData();
			int columnCount = rsmd.getColumnCount();
			while(rs.next()) {
				if(result == null) result = new ArrayList<>();
				Map<String, Object> row = new HashMap<>();
				for(int i = 1; i <= columnCount; i++) {
					String key = rsmd.getColumnLabel(i);
					Object value = rs.getObject(i);
					row.put(key, value);
				}
				result.add(row);
			}
		}catch(SQLException e) {
			e.printStackTrace();
		}finally {
			if(rs != null) try { rs.close(); } catch(Exception e) {}
			if(ps != null) try { ps.close(); } catch(Exception e) {}
			if(conn != null) try { conn.close(); } catch(Exception e) {}
		}
		return result;
	}

	public int update(String sql, List<Object> param) {
		// sql => "DELETE FROM JAVA_BOARD WHERE BOARD_NUMBER=?"
		// sql => "UPDATE JAVA_BOARD SET TITLE='하하' WHERE BOARD_NUMBER=?"
		// sql => "INSERT MY_MEMBER (MEM_ID, MEM_PASS, MEM_NAME) VALUES (?, ?, ?)"
		int result = 0;
		try {
			conn = DriverManager.getConnection(url, user, password);
			ps = conn.prepareStatement(sql);
			for(int i = 0; i < param.size(); i++) {
				ps.setObject(i + 1, param.get(i));
			}
			result = ps.executeUpdate();
		}catch(SQLException e) {
			e.printStackTrace();
		}finally {
			if(rs != null) try {  rs.close();  } catch (Exception e) { }
			if(ps != null) try {  ps.close();  } catch (Exception e) { }
			if(conn != null) try { conn.close(); } catch (Exception e) { }
		}
		return result;
	}
	
	public int update(String sql) {
		// sql => "DELETE FROM JAVA_BOARD"
		// sql => "UPDATE JAVA_BOARD SET TITLE='하하'"
		// sql => "UPDATE JAVA_BOARD SET TITLE='하하' WHERE BOARD_NUMBER=1"
		// sql => "INSERT MY_MEMBER (MEM_ID, MEM_PASS, MEM_NAME) VALUES ('admin', '1234', '홍길동')"
		int result = 0;
		try {
			conn = DriverManager.getConnection(url, user, password);
			ps = conn.prepareStatement(sql);
			result = ps.executeUpdate();
		}catch(SQLException e) {
			e.printStackTrace();
		}finally {
			if(rs != null) try {  rs.close();  } catch (Exception e) { }
			if(ps != null) try {  ps.close();  } catch (Exception e) { }
			if(conn != null) try { conn.close(); } catch (Exception e) { }
		}
		return result;
	}
	
	public <T> List<T> selectList(String sql,  List<Object> param , Class<T> type) {
		List<Map<String, Object>> list = selectList(sql, param);
		return ConvertUtils.convertToList(list, type);
	}
	
	public <T> List<T> selectList(String sql, Class<T> type) {
		List<Map<String, Object>> list = selectList(sql);
		return ConvertUtils.convertToList(list, type);
	}
	
	public <T> T selectOne(String sql, Class<T> type) {
		Map<String, Object> map = selectOne(sql);
		return ConvertUtils.convertToVo(map, type);
	}
	
	public <T> T selectOne(String sql, List<Object> param , Class<T> type) {
		Map<String, Object> map = selectOne(sql, param);
		return ConvertUtils.convertToVo(map, type);
	}
//	
	public Map<String, Object> selectOne(String sql, List<Object> param){
		// sql => "SELECT * FROM JAVA_BOARD WHERE BOARD_NUMBER=?"
		// param => [1]
		//
		// sql => "SELECT * FROM JAVA_BOARD WHERE WRITER=? AND TITLE=?"
		// param => ["홍길동", "안녕"]
		Map<String, Object> row = null;
		
		try {
			conn = DriverManager.getConnection(url, user, password);
			ps = conn.prepareStatement(sql);
			for(int i = 0; i < param.size(); i++) {
				ps.setObject(i + 1, param.get(i));
			}
			rs = ps.executeQuery();
			ResultSetMetaData rsmd = rs.getMetaData();
			int columnCount = rsmd.getColumnCount();
			while(rs.next()) {
				row = new HashMap<>();
				for(int i = 1; i <= columnCount; i++) {
					String key = rsmd.getColumnLabel(i);
					Object value = rs.getObject(i);
					row.put(key,value);
				}
				// {DATETIME=2022-08-05 16:35:08.0, WRITER=홍길동, TITLE=안녕하세요, CONTENT=안녕안녕, BOARD_NUMBER=1}
			}
		}catch(SQLException e) {
			e.printStackTrace();
		}finally {
			if(rs != null) try {  rs.close();  } catch (Exception e) { }
			if(ps != null) try {  ps.close();  } catch (Exception e) { }
			if(conn != null) try { conn.close(); } catch (Exception e) { }
		}
		return row;
	}
	
	public Map<String, Object> selectOne(String sql){
		// sql => "SELECT * FROM JAVA_BOARD 
		//			WHERE BOARD_NUMBER=(SELECT MAX(BOARD_NUMBER) FROM JAVA_BOARD)"
		// sql => "SELECT * FROM MEMBER MEM_ID='a001' AND MEM_PASS='123'"
		Map<String, Object> row = null;
		
		try {
			conn = DriverManager.getConnection(url, user, password);
			ps = conn.prepareStatement(sql);
			rs = ps.executeQuery();
			ResultSetMetaData rsmd = rs.getMetaData();
			int columnCount = rsmd.getColumnCount();
			while(rs.next()) {
				row = new HashMap<>();
				for(int i = 1; i <= columnCount; i++) {
					String key = rsmd.getColumnLabel(i);
					// getColumnName vs getColumnLabel
					// getColumnName : 원본 컬럼명을 가져옴
					// getColumnLabel : as로 선언된 별명을 가져옴, 없으면 원본 컬럼명
					Object value = rs.getObject(i);
					row.put(key,value);
				}
			}
		}catch(SQLException e) {
			e.printStackTrace();
		}finally {
			if(rs != null) try {  rs.close();  } catch (Exception e) { }
			if(ps != null) try {  ps.close();  } catch (Exception e) { }
			if(conn != null) try { conn.close(); } catch (Exception e) { }
		}
		return row;
	}
	
}

 

package controller;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import service.UserService;
import util.Print;
import util.ScanUtil;
import util.View;

public class MainController extends Print {
	// sessionStorage은 하나 밖에 존재하지 않음
	static public Map<String, Object> sessionStorage = new HashMap<>();
	
	UserService userService = UserService.getInstance();
	
	public static void main(String[] args) {
		new MainController().start();
	}
	
	private void start() {
		View view = View.MAIN;
		while (true) {
			switch (view) {
			case MAIN:
				view = home();
				break;
			case USER_JOIN:
				view = userJoin();
				break;
			case USER_LIST:
				view = userList();
				break;
			case USER_LOGIN:
				view = userLogin();
				break;
			case USER_DEL:
				view = userDel();
				break;
			case USER_UPDATE:
				view = userUpdate();
				break;
			default:
				break;
			}
		}
	}
	
	private View userUpdate() {
		System.out.println("회원 수정 페이지");
		String pass = ScanUtil.nextLine("pass >> ");
		String name = ScanUtil.nextLine("name >> ");
		Map<String, Object> user = (Map<String, Object>) sessionStorage.get("user"); 
		String id = (String) user.get("ID");
		
		List<Object> param = new ArrayList();
		param.add(pass);
		param.add(name);
		param.add(id);
		
		userService.userUpdate(param);
		
		return View.MAIN;
	}
	
	private View userDel() {
		System.out.println("회원 탈퇴 페이지");
		Map<String, Object> user = (Map<String, Object>) sessionStorage.get("user"); 
		String id = (String) user.get("ID");
		userService.userDelete(id);
		return View.MAIN;
	}
	
	private View userLogin() {
		System.out.println("로그인 페이지");
		String id = ScanUtil.nextLine("ID >> ");
		String pass = ScanUtil.nextLine("pass >> ");
		
		List<Object> param = new ArrayList();
		param.add(id);
		param.add(pass);
		
		// DB 에서 로그인 여부 확인
		boolean login = userService.userLogin(param);
		if(!login) {
			System.out.println("로그인에 실패하였습니다.");
			return View.USER_LOGIN;
		}
		Map<String,Object> user = (Map<String,Object>) sessionStorage.get("user");
		System.out.println(user.get("NAME") + "님 환영합니다.");
		
		
		System.out.println("1. 회원 탈퇴");
		System.out.println("2. 정보 수정");
		System.out.println("3. 로그아웃");
		
		int sel = ScanUtil.nextInt("메뉴 선택 : ");
		switch (sel) {
		case 1:
			return View.USER_DEL;
		case 2:
			return View.USER_UPDATE;
		case 3:
			return View.MAIN;
		default:
			return View.MAIN;
		}
	}
	
	private View userList() {
		System.out.println("유저 리스트");
		/*
		 * 디비에서 유저 리스트 값 출력
		 */
		List<Map<String, Object>> userList = userService.userList();
		System.out.println("ID\tNAME");
		System.out.println("===================");
		for(Map<String, Object> map : userList) {
			String id = (String) map.get("ID");
//			String pass = (String) map.get("PASS");
			String name = (String) map.get("NAME");
			System.out.println(id + "\t" + name);
		}
		return View.MAIN;
	}
	
	private View userJoin() {
		System.out.println("회원가입 페이지");
		// id
		String id = ScanUtil.nextLine("ID >> ");
		// pass
		String pass = ScanUtil.nextLine("pass >> ");
		// name
		String name = ScanUtil.nextLine("name >> ");
		
		List<Object> param = new ArrayList();
		param.add(id);
		param.add(pass);
		param.add(name);
		
		userService.userJoin(param);
		
		return View.MAIN;
	}
	

	private View home() {
		System.out.println("1. 회원가입");
		System.out.println("2. 회원조회");
		System.out.println("3. 로그인");
		
		int sel = ScanUtil.nextInt("메뉴 선택 : ");
		switch (sel) {
		case 1:
			return View.USER_JOIN;
		case 2:
			return View.USER_LIST;
		case 3:
			return View.USER_LOGIN;
		default:
			return View.MAIN;
		}
	}
}

 

package util;

public enum View {
	MAIN,					// 기본화면
	USER_JOIN,				// 회원가입
	USER_LOGIN,				// 로그인
	USER_LIST,				// 정보 수정
	USER_UPDATE,			// 회원조회
	USER_DEL				// 회원 탈퇴
}

 

package service;

import java.util.List;
import java.util.Map;

import controller.MainController;
import dao.UserDao;

public class UserService {
	private static UserService instance = null;

	private UserService() {
	}

	public static UserService getInstance() {
		if (instance == null) {
			instance = new UserService();
		}
		return instance;
	}
	
	UserDao dao = UserDao.getInstance();
	
	public List<Map<String, Object>> userList() {
		return dao.userList();
	}
	
	public void userJoin(List<Object> param) {
		dao.userJoin(param);
	}
	
	public boolean userLogin(List<Object> param) {
		Map<String, Object> map = dao.userLogin(param);
		if(map == null || map.isEmpty()) {
			return false;
		} else {
			MainController.sessionStorage.put("user", map);
			return true;
		}
	}
	
	public void userDelete(String id) {
		dao.userDelete(id);
	}
	
	public void userUpdate(List<Object> param) {
		dao.userUpdate(param);
	}
}

 

package dao;

import java.util.List;
import java.util.Map;

import util.JDBCUtil;

public class UserDao {
	private static UserDao instance = null;

	private UserDao() {
	}

	public static UserDao getInstance() {
		if (instance == null) {
			instance = new UserDao();
		}
		return instance;
	}

	JDBCUtil jdbc = JDBCUtil.getInstance();
	
	public List<Map<String, Object>> userList() {
		String sql = "select *\r\n" + 
					 "from java_user\r\n" + 
					 "where delyn = 'N'";
		
		return jdbc.selectList(sql);
	}
	
	public void userJoin(List<Object> param) {
		String sql = "insert into java_user "
				   + "values (?, ?, ?, 'N')"; // param의 데이터가 순서대로 ?에 들어감
		
		jdbc.update(sql, param);
	}
	
	public Map<String, Object> userLogin(List<Object> param) {
		String sql = "select *\r\n" + 
				"from java_user\r\n" + 
				"where id=?\r\n" + 
				"and pass=?\r\n" +
				"and delyn='N'";
		
		return jdbc.selectOne(sql, param);
	}
	
	public void userDelete(String id) {
		String sql = "update java_user\r\n" + 
				"set delyn = 'Y'\r\n" + 
				"where id = '" + id + "'";
		
		jdbc.update(sql);
	}
	
	public void userUpdate(List<Object> param) {
		String sql = "update java_user\r\n" + 
				"set pass = ?\r\n" +
				", name = ?\r\n" +
				"where id = ?";
		
		jdbc.update(sql, param);
	}
	
}

 

 

 

회원가입 결과화면

 

회원조회 결과화면

 

로그인 결과 화면

 

정보 수정 및 조회 결과 화면

 

로그인, 로그아웃 결과 화면

 

회원 탈퇴 후 결과 화면

 

 

 

CRUD

 

: 컴퓨터 소프트웨어가 가지는 기본적인 데이터 처리 기능을 이야기 한다.

Create(생성), Read(읽기), Update(갱신), Delete(삭제) 를 줄여서 부른다.

사용자 인터페이스가 갖춰야 할 기능을 가리키는 용어로서도 사용된다.

 

 

 

TIP

 

- 쿠키와 세션 차이

 

  • 쿠키

: 클라이언트(브라우저) 로컬에 저장되는 키와 값이 들어있는 작은 데이터 파일을 이야기한다.

사용자 인증이 유효한 시간을 명시할 수 있으며, 브라우저가 종료되어도 인증이 유지된다.

사용자가 따로 요청하지 않아도 브라우저가 자동으로 서버에 전송한다.

=> 사용자 정보 파일을 브라우저에 저장함

 

ex) 사이트에 로그인 시, 아이디와 비밀번호를 저장하시겠습니까? 묻는 여부

      쇼핑몰의 장바구니

      자동로그인, 팝업에서 하루 동안 창 보지 않기 체크

 

  • 세션

: 쿠키를 기반으로 하지만 사용자 정보 파일을 서버 측에서 관리한다.

세션 ID를 부여하며 웹 브라우저가 서버에 접속해서 브라우저를 종료할 때 까지만 인증상태를 유지한다.

쿠키보다 보안이 좋지만, 사용자가 많을 수록 서버 메모리를 많이 차지한다.

 

ex) 로그인, 보안이 필요한 작업

 

 

반응형