MVC 패턴
: 사용자 인터페이스, 데이터 및 논리 제어를 구현하는데 사용되는 소프트웨어 디자인 패턴을 이야기 한다.
Model, View, Controller 의 구성으로 구성되어 있다.
Controller : 화면의 이동
Model : 데이터
View : 출력
- 진행 방향
controller > service > dao > | jdbc DB |
controller < service < dao < |
controller : 화면의 이동
service : 알고리즘 적인 정보 ex) 어떤 데이터를 가져와야 하는지, 정렬이라던지
dao : sql문
jdbc DB : DB에 접근
하단의 테이블을 생성 후 데이터를 삽입하여 진행하였다.
예시 프로젝트는 아래와 같다.
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) 로그인, 보안이 필요한 작업
'자바' 카테고리의 다른 글
[Java 초급] 25장 MVC 패턴3 : 커피 주문 시스템 (0) | 2024.01.08 |
---|---|
[Java 초급] 24장 MVC 패턴2 : 게시판 만들기1 (0) | 2024.01.04 |
[Java 초급] 22.5장 테스트 (0) | 2024.01.02 |
[Java 초급] 22장 JDBC Utility 클래스 (0) | 2024.01.02 |
[Java 초급] 21.5장 테스트 (0) | 2023.12.30 |