내가 보려고 정리하는/JAVA

MVC패턴!

보동이용용 2023. 1. 13. 20:25
반응형

초급 프로젝트때 살짝 맛보기 했던 mvc패턴이 다시 나타났다!!

 

mvc.... model / view / controller 패턴이다

model  => 데이터와 데이터를 구성하기 위한 로직을 말한다.

view => 데이터를 사용자에게 보여주는 역할

controller => 사용자의 요청을 받아서 model에 일을 시키고 그 결과를 받아서 view에 전달.

 

 

 

패키지를 4개 만든다.

vo / dao / service / controller

 

 

1. vo 

package kr.or.ddit.mvc.vo;

/*
	- DB 테이블에 있는 컬럼을 기준으로 데이터를 객체화한 클래스
	
	- DB 테이블의 '컬럼명'이 클래스의 '멤버변수명'이 된다.
	- DB 테이블의 컬럼과 클래스의 멤버변수를 매핑하는 역할을 한다.
*/
public class MemberVO {
	private String mem_id;
	private String mem_pass;
	private String mem_name;
	private String mem_tel;
	private String mem_addr;
	
	public String getMem_id() {
		return mem_id;
	}
	public void setMem_id(String mem_id) {
		this.mem_id = mem_id;
	}
	public String getMem_pass() {
		return mem_pass;
	}
	public void setMem_pass(String mem_pass) {
		this.mem_pass = mem_pass;
	}
	public String getMem_name() {
		return mem_name;
	}
	public void setMem_name(String mem_name) {
		this.mem_name = mem_name;
	}
	public String getMem_tel() {
		return mem_tel;
	}
	public void setMem_tel(String mem_tel) {
		this.mem_tel = mem_tel;
	}
	public String getMem_addr() {
		return mem_addr;
	}
	public void setMem_addr(String mem_addr) {
		this.mem_addr = mem_addr;
	}
	
	
	
}

필요한 DB의 컬럼을 변수로 저장하고 객체화한다.

getter와 setter를 생성하여 사용할 수 있도록 한다.

 


2. dao 

package kr.or.ddit.mvc.dao;

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

import kr.or.ddit.mvc.vo.MemberVO;

/**
 * 실제 DB와 연결해서 SQL문을 실행하여 결과를 작성해서 Service에게 전달하는 DAO의 interface
 * 
 * 메서드 하나가 DB와 관련된 작업 1개를 수행하도록 작성한다.
 * 
 * @author ueryoung
 *
 */
public interface IMemberDao {
	/**
	 * MemberVO에 담겨진 데이터를 DB에 insert하는 메서드
	 * 
	 * @param memVo DB에 insert할 자료가 저장된 MemberVO객체
	 * @return 작업 성공 : 1, 작업 실패 : 0
	 */
	public int insertMember(MemberVO memVo);
	
	/**
	 * 회원ID를 인수값으로 받아서 해당 회원 정보를 삭제하는 메서드
	 * 
	 * @param memId 삭제할 회원ID
	 * @return 작업 성공 : 1, 작업 실패 : 0
	 */
	public int deleteMember(String memId);
	
	/**
	 * MemberVO의 자료를 이용하여 DB의 자료를 update하는 메서드
	 * 
	 * @param memVo update할 회원 정보가 저장된 MemberVO객체
	 * @return 작업 성공 : 1, 작업 실패 : 0
	 */
	public int updateMember(MemberVO memVo);
	
	/**
	 * DB의 전체 회원 정보를 가져와 List에 담아서 반환하는 메서드
	 * 
	 * @return MemberVO객체가 저장된 List객체
	 */
	public List<MemberVO> getAllMember();

	/**
	 * 회원ID를 인수값으로 받아서 해당 회원ID의 개수를 반환하는 메서드
	 * 
	 * @param memId 검색할 회원ID
	 * @return 검색된 회원ID의 갯수
	 */
	public int getMemberCount(String memId);
	
	/**
	 * Map의 정보를 이용하여 회원 정보 중 원하는 컬럼을 수정하는 메서드
	 * 		key값 ==> 회원ID(id),  수정할컬럼명(field),  수정할데이터(data)
	 * 
	 * @param paramMap 회원ID, 수정할 컬럼명, 수정할데이터가 저장된 Map객체
	 * @return 작업 성공 : 1, 작업 실패 : 0
	 */
	public int updateMember2(Map<String, String> paramMap);
}

2-1.

dao 인터페이스를 생성하여 메서드 이름으로 사용할 쿼리문을 구분한다.

쿼리문에 사용할 파라미터, 반환값 등을 정할 수 있고 설명을 쓴다.

 

package kr.or.ddit.mvc.dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import kr.or.ddit.mvc.vo.MemberVO;
import kr.or.ddit.util.DBUtil3;

public class MemberDaoImpl implements IMemberDao {
	// 1번
	private static MemberDaoImpl dao;
	
	// 2번
	private MemberDaoImpl() {  }
	
	// 3번
	public static MemberDaoImpl getInstance() {
		if(dao==null) dao = new MemberDaoImpl();
		return dao;
	}

	@Override
	public int insertMember(MemberVO memVo) {
		Connection conn = null;
		PreparedStatement pstmt = null;
		int cnt = 0;		// 반환값이 저장될 변수
		
		try {
			
			conn = DBUtil3.getConnection();
			String sql = "insert into mymember "
					+ "(mem_id, mem_pass, mem_name, mem_tel, mem_addr)"
					+ " values(?, ?, ?, ?, ?) ";
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, memVo.getMem_id());
			pstmt.setString(2, memVo.getMem_pass());
			pstmt.setString(3, memVo.getMem_name());
			pstmt.setString(4, memVo.getMem_tel());
			pstmt.setString(5, memVo.getMem_addr());
			
			cnt = pstmt.executeUpdate();
			
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			if(pstmt!=null) try{ pstmt.close(); }catch(SQLException e) {}
			if(conn!=null) try{ conn.close(); }catch(SQLException e) {}
		}
		
		return cnt;
	}

	@Override
	public int deleteMember(String memId) {
		Connection conn = null;
		PreparedStatement pstmt = null;
		int cnt = 0;
		
		try {
			
			conn = DBUtil3.getConnection();
			String sql = "delete from mymember where mem_id = ? " ;
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, memId);
			
			cnt = pstmt.executeUpdate();
					
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			if(pstmt!=null) try { pstmt.close(); } catch(SQLException e) {}
			if(conn!=null) try { conn.close(); } catch(SQLException e) {}
		}
		return cnt;
	}

	@Override
	public int updateMember(MemberVO memVo) {
		Connection conn = null;
		PreparedStatement pstmt = null;
		int cnt = 0;
		
		try {
			
			conn = DBUtil3.getConnection();
			String sql = "update mymember set "
					+ " mem_pass=?, mem_name=?, mem_tel=?, mem_addr=? "
					+ " where mem_id=? ";
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, memVo.getMem_pass());
			pstmt.setString(2, memVo.getMem_name());
			pstmt.setString(3, memVo.getMem_tel());
			pstmt.setString(4, memVo.getMem_addr());
			pstmt.setString(5, memVo.getMem_id());
			
			cnt = pstmt.executeUpdate();
			
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			if(pstmt != null) try { pstmt.close(); } catch(SQLException e) {}
			if(conn != null) try { conn.close(); } catch(SQLException e) {}
		}
		
		return cnt;
	}

	@Override
	public List<MemberVO> getAllMember() {
		Connection conn = null; 
		Statement stmt = null;
		ResultSet rs = null;
		
		List<MemberVO> memList = null;	// 반환값이 저장될 변수
		
		try {
			conn = DBUtil3.getConnection();
			String sql = "select * from mymember";
			stmt = conn.createStatement();
			
			rs = stmt.executeQuery(sql);
			memList = new ArrayList<MemberVO>();		///memList 초기화
			
			while(rs.next()) {
				// 1개의 레코드 결과를 VO객체에 담는다.
				MemberVO memVo = new MemberVO();
				memVo.setMem_id(rs.getString("mem_id"));
				memVo.setMem_pass(rs.getString("mem_pass"));
				memVo.setMem_name(rs.getString("mem_name"));
				memVo.setMem_tel(rs.getString("mem_tel"));
				memVo.setMem_addr(rs.getString("mem_addr"));
				
				memList.add(memVo);	// VO객체를 List에 추가
			}
					
		} catch (SQLException e) {
			memList = null;
			e.printStackTrace();
		} finally {
			if(rs!=null) try { rs.close(); } catch(SQLException e) {}
			if(stmt!=null) try { stmt.close(); } catch(SQLException e) {}
			if(conn!=null) try { conn.close(); } catch(SQLException e) {}
		}
		
		return memList;
	}

	@Override
	public int getMemberCount(String memId) {
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		int count = 0;
		
		try {
			conn = DBUtil3.getConnection();
			
			String sql = "select count(*) cnt from mymember where mem_id = ? ";
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, memId);
			
			rs = pstmt.executeQuery();
			
			if(rs.next()) {
				count = rs.getInt("cnt");
			}
			
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			if( rs != null) try { rs.close(); } catch(SQLException e) {}
			if( pstmt != null) try { pstmt.close(); } catch(SQLException e) {}
			if( conn != null) try { conn.close(); } catch(SQLException e) {}
		}
		return count;
	}

	
	@Override
	public int updateMember2(Map<String, String> paramMap) {
		Connection conn = null;
		PreparedStatement pstmt = null;
		int cnt = 0;		// 반환값이 저장될 변수
		
		try {
			conn = DBUtil3.getConnection();
			String sql = "update mymember set " 
					+ paramMap.get("field") + " = ? where mem_id = ? ";
			pstmt = conn.prepareStatement(sql);
			pstmt.setString(1, paramMap.get("data"));
			pstmt.setString(2, paramMap.get("id"));
			
			cnt = pstmt.executeUpdate();
			
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			if( pstmt != null) try { pstmt.close(); } catch(SQLException e) {}
			if( conn != null) try { conn.close(); } catch(SQLException e) {}
		}
		return cnt;
	}

}

2-2.

daoImpl에는 dao의 메서드를 구현한다.

필요한 CRUD를 try, catch문 안에 작성한다.

           


3. service

service는 dao와 비슷하다.

 

package kr.or.ddit.mvc.service;

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

import kr.or.ddit.mvc.vo.MemberVO;

/**
 * Service객체는 DAO에 설정된 메서드를 원하는 작업에 맞게 호출하여 그 결과를 받아오고,
 * 받아온 결과를 Controller에게 보내주는 역할을 한다.
 * 
 * 보통은 DAO의 메서드 구조와 같게 만든다. (자바 고급 시간에 한해서...)
 * @author ueryoung
 *
 */
public interface IMemberService {
	/**
	 * MemberVO에 담겨진 데이터를 DB에 insert하는 메서드
	 * 
	 * @param memVo DB에 insert할 자료가 저장된 MemberVO객체
	 * @return 작업 성공 : 1, 작업 실패 : 0
	 */
	public int insertMember(MemberVO memVo);
	
	/**
	 * 회원ID를 인수값으로 받아서 해당 회원 정보를 삭제하는 메서드
	 * 
	 * @param memId 삭제할 회원ID
	 * @return 작업 성공 : 1, 작업 실패 : 0
	 */
	public int deleteMember(String memId);
	
	/**
	 * MemberVO의 자료를 이용하여 DB의 자료를 update하는 메서드
	 * 
	 * @param memVo update할 회원 정보가 저장된 MemberVO객체
	 * @return 작업 성공 : 1, 작업 실패 : 0
	 */
	public int updateMember(MemberVO memVo);
	
	/**
	 * DB의 전체 회원 정보를 가져와 List에 담아서 반환하는 메서드
	 * 
	 * @return MemberVO객체가 저장된 List객체
	 */
	public List<MemberVO> getAllMember();

	/**
	 * 회원ID를 인수값으로 받아서 해당 회원ID의 개수를 반환하는 메서드
	 * 
	 * @param memId 검색할 회원ID
	 * @return 검색된 회원ID의 갯수
	 */
	public int getMemberCount(String memId);	
	
	/**
	 * Map의 정보를 이용하여 회원 정보 중 원하는 컬럼을 수정하는 메서드
	 * 		key값 ==> 회원ID(id),  수정할컬럼명(field),  수정할데이터(data)
	 * 
	 * @param paramMap 회원ID, 수정할 컬럼명, 수정할데이터가 저장된 Map객체
	 * @return 작업 성공 : 1, 작업 실패 : 0
	 */
	public int updateMember2(Map<String, String> paramMap);
}

3-1.

service도 interface로 생성하고 dao의 자료를 받을 수 있도록 준비한다.

 

 

package kr.or.ddit.mvc.service;

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

import kr.or.ddit.mvc.dao.IMemberDao;
import kr.or.ddit.mvc.dao.MemberDaoImpl;
import kr.or.ddit.mvc.vo.MemberVO;

public class MemberServiceImpl implements IMemberService {
	private IMemberDao dao;		// DAO객체가 저장될 변수 선언
	
	// 1번
	private static MemberServiceImpl service;
	
	// 생성자 // 2번
//	public MemberServiceImpl() {
	private MemberServiceImpl() {
//		dao = new MemberDaoImpl();	// DAO객체를 생성해서 dao객체변수를 초기화한다.
		dao = MemberDaoImpl.getInstance();	///싱글톤
	}
	
	// 3번
	public static MemberServiceImpl getInstance() {
		if(service==null) service= new MemberServiceImpl();
		return service;
	}
	
	
	
	@Override
	public int insertMember(MemberVO memVo) {
		return dao.insertMember(memVo);
	}

	@Override
	public int deleteMember(String memId) {
		return dao.deleteMember(memId);
	}

	@Override
	public int updateMember(MemberVO memVo) {
		return dao.updateMember(memVo);
	}

	@Override
	public List<MemberVO> getAllMember() {
		return dao.getAllMember();
	}

	@Override
	public int getMemberCount(String memId) {
		return dao.getMemberCount(memId);
	}

	@Override
	public int updateMember2(Map<String, String> paramMap) {
		return dao.updateMember2(paramMap);
	}

}

3-2.

service의 메서드를 serviceImpl 에서 구현한다.


4.Controller

package kr.or.ddit.mvc.controller;

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

import kr.or.ddit.mvc.service.IMemberService;
import kr.or.ddit.mvc.service.MemberServiceImpl;
import kr.or.ddit.mvc.vo.MemberVO;

public class MemberController {
	private Scanner scan;
	private IMemberService service; 	// Service객체가 저장될 변수 선언
	
	// 생성자
	public MemberController() {
		scan = new Scanner(System.in);
//		service = new MemberServiceImpl();
		service = MemberServiceImpl.getInstance();
	}
	
	public static void main(String[] args) {
		new MemberController().startMember();

	}
	
	private void startMember() {	
		
		while(true) {
			System.out.println("--------------------");
			System.out.println("회원관리프로그램");
			int choice = displayMenu();
			
			switch(choice) {
			case 1: 
				insertMember();	break;
			case 2: 
				deleteMember();	break;
			case 3: 
				updateMember(); break;
			case 4: 
				displayAllMember(); break;
			case 5: 
				updateMember2(); break;	
			case 0: 
				System.out.println("작업을 마칩니다.");  
				return;
			default: 
				System.out.println("작업 번호를 잘못 입력했습니다."); 
			}
		}
		
	}
	
	// 회원 정보 수정2 ==> 원하는 컬럼만 수정하기
	private void updateMember2() {
		System.out.println();
		System.out.println("수정할 회원 정보를 입력하세요...");
		
		System.out.println("회원ID >> ");
		String id = scan.next();
		
		int count = service.getMemberCount(id);
		
		if(count==0) {	// 없는 회원이면... 
			System.out.println(id + "은(는) 등록되지 않은 회원ID 입니다.");
			System.out.println("수정 작업을 마칩니다...");
			return;
		}
		
		String updateField = null;		// 수정할 컬럼며이 저장될 변수
		int num; 						// 수정할 컬럼명을 선택할 때 저장될 변수
		String updateTitle = null;		// 수정할 값을 입력 받을 때 나타낼 제목이 저장될 변수
		
		do {
			System.out.println();
			System.out.println("수정할 항목을 선택하세요... ");
			System.out.println("------------------------------------");
			System.out.println("1.비밀번호   2.회원이름    3.전화번호     4.회원주소");
			System.out.println("------------------------------------");
			System.out.println(" 수정할 항목 선택 >> ");
			num = scan.nextInt();
			
			switch(num) {
			case 1 : updateField = "mem_pass"; updateTitle = "비밀번호"; break;
			case 2 : updateField = "mem_name"; updateTitle = "회원이름"; break;
			case 3 : updateField = "mem_tel";  updateTitle = "전화번호"; break;
			case 4 : updateField = "mem_addr"; updateTitle = "회원주소"; break;
			default : System.out.println("수정할 항목을 잘못 선택했습니다. 다시 선택하세요.");
			}
			
		}while(num<1 || num>4);
		
		scan.nextLine();	// 입력 버퍼 비우기
		System.out.println();
		System.out.println("수정할 내용을 입력하세요...");
		System.out.println("새로운" + updateTitle + " >> ");
		String updateData = scan.nextLine();
		
		// 수정 작업에 필요한 정보들을 Map객체에 추가한다.
		// key값 ==> 회원ID(id),  수정할컬럼명(field),  수정할데이터(data)
		Map<String, String> paramMap = new HashMap<String, String>();
		paramMap.put("id", id);
		paramMap.put("field", updateField);
		paramMap.put("data", updateData);
		
		int cnt = service.updateMember2(paramMap);
		
		if(cnt>0) {
			System.out.println("수정 작업 성공!!!");
		}else {
			System.out.println("수정 작업 실패~~~");
		}
		
		
	}

	// 전체 회원 정보 출력
	private void displayAllMember() {
		System.out.println();
		System.out.println("-----------------------------------------------------");
		System.out.println("회원ID   비밀번호    회원이름     전화번호                        회원주소");
		System.out.println("-----------------------------------------------------");
		
		List<MemberVO> memList = service.getAllMember();
		if(memList==null || memList.size()==0) {
			System.out.println(" 출력할 회원 정보가 하나도 없습니다...");
		}else {
			for(MemberVO memVo : memList) {
				System.out.println(memVo.getMem_id() + "\t" 
						+ memVo.getMem_pass() + "\t" 
						+ memVo.getMem_name() + "\t" 
						+ memVo.getMem_tel() + "\t" 
						+ memVo.getMem_addr());
			}
			System.out.println("-----------------------------------------------------");
		}
		
		
		
	}

	// update메서드
	private void updateMember() {
		System.out.println();
		System.out.println("수정할 회원 정보를 입력하세요...");
		
		System.out.println("회원ID >> ");
		String id = scan.next();
		
		int count = service.getMemberCount(id);
		
		if(count==0) {	// 없는 회원이면... 
			System.out.println(id + "은(는) 등록되지 않은 회원ID 입니다.");
			System.out.println("수정 작업을 마칩니다...");
			return;
		}
		
		System.out.println("수정할 내용을 입력하세요...");
		System.out.println("새로운 비밀번호 >> ");
		String newPass = scan.next();
		
		System.out.println("새로운 회원이름 >> ");
		String newName = scan.next();
		
		System.out.println("새로운 전화번호 >> ");
		String newTel = scan.next();
		
		scan.nextLine();
		System.out.println("새로운 회원주소 >> ");
		String newAddr = scan.nextLine();
		
		// 입력 받은 수정할 데이터를 VO객체에 저장한다.
		MemberVO memVo = new MemberVO();
		memVo.setMem_id(id);
		memVo.setMem_pass(newPass);
		memVo.setMem_name(newName);
		memVo.setMem_tel(newTel);
		memVo.setMem_addr(newAddr);
		
		int cnt = service.updateMember(memVo);
		
		if(cnt > 0) {
			System.out.println("수정 작업 성공!!");
		}else {
			System.out.println("수정 작업 실패~~");
		}
	}

	// delete메서드
	private void deleteMember() {
		System.out.println();
		System.out.println("삭제할 회원 정보를 입력하세요...");
		System.out.println("회원ID >> ");
		String id = scan.next();
		
		int count = service.getMemberCount(id);
		
		int cnt = service.deleteMember(id);
		
		if(cnt>0) {
			System.out.println("회원ID가 " + id + "인 회원 정보 삭제 성공!!");
		}else {
			System.out.println("회원ID가 " + id + "인 회원 정보 삭제에 실패했습니다...");
		}
	}

	// insert메서드
	private void insertMember() {
		System.out.println();
		System.out.println("추가할 회원 정보를 입력하세요...");
		int count = 0;		// 회원ID의 개수가 저장될 변수
		String id = null;
		
		do {
			System.out.println("회원ID>> ");
			id = scan.next();
			count = service.getMemberCount(id);
			if(count>0) {
				System.out.println("입력한 " + id + "은(는) 이미 등록된 회원ID입니다.");
				System.out.println("다른 회원ID를 입력하세요...");
				System.out.println();
				
			}
		}while(count>0);
		
		System.out.println("비밀번호 >> ");
		String pass = scan.next();
		
		System.out.println("회원이름 >> ");
		String name = scan.next();
		
		System.out.println("전화번호 >> ");
		String tel = scan.next();
		
		scan.nextLine();	// 입력 버퍼 비우기...
		System.out.println("회원주소 >> ");
		String addr = scan.nextLine();
		
		// 입력한 데이터들을 VO객체에 담는다.
		MemberVO memVo = new MemberVO();
		memVo.setMem_id(id);
		memVo.setMem_pass(pass);
		memVo.setMem_name(name);
		memVo.setMem_tel(tel);
		memVo.setMem_addr(addr);
		
		int cnt = service.insertMember(memVo);
		
		if(cnt > 0) {
			System.out.println("등록 작업 성공!!!");
		}else {
			System.out.println("등록 작업 실패~~~");
		}
		
	}
	
	private int displayMenu() {
		System.out.println("--------------------");
		System.out.println("1. 자료 추가");
		System.out.println("2. 자료 삭제");
		System.out.println("3. 자료 수정");
		System.out.println("4. 전체 자료 출력");
		System.out.println("5. 자료 수정2");
		System.out.println("0. 프로그램 종료.");
		System.out.println("--------------------");
		System.out.println("메뉴 선택 >>");
		return scan.nextInt();
	}

}

실제로 화면에 보이는 것들을 구성하고

service로 자료를 보내고 받아와서  출력한다.

 

mvc패턴을 사용하는 기본 형은 이런식이다

 

 

 

반응형