반응형
도서 대여 시스템 프로젝트 진행
아래의 메뉴로 구성된 프로젝트를 구현한다.
관리자는 구현하지 않았으며 도서 대여의 종류만 검색 가능하게 하여 진행했다.
더보기
---------------- 도서 관리 프로젝트 ----------------
1. 일반 회원
2. 관리자
---------------- 일반 회원 ----------------
1. 전체 도서 조회
2. 도서 대여
3. 도서 대여 내역 조회
---------------- 일반회원 도서 대여 ----------------
# 도서 전체 내역 출력
1. 제목 검색
2. 종류 검색
3. 내용 검색
---------------- 도서 대여 내역 조회 ----------------
#전체 내역 출력
1. 대여 중인 도서
---------------- 관리자 ----------------
1. 전체 도서 조회
2. 신규 도서 등록
3. 도서 수량 변경
---------------- 신규 도서 등록 ----------------
---------------- 도서 수량 변경 ----------------
#전체 도서 내역 출력
아래의 SQL을 이용해 DB 테이블과 데이터를 생성해놓는다.
--------------------------------------------------------
-- 파일이 생성됨
--------------------------------------------------------
--------------------------------------------------------
-- DDL for Table JAVA_BOOK
--------------------------------------------------------
CREATE TABLE "JAVA_BOOK"
( "BOOK_NO" NUMBER,
"NAME" VARCHAR2(100 BYTE),
"KIND" VARCHAR2(30 BYTE),
"CONTENT" VARCHAR2(2000 BYTE)
) ;
--------------------------------------------------------
-- DDL for Table JAVA_BOOK_HOLD
--------------------------------------------------------
CREATE TABLE "JAVA_BOOK_HOLD"
( "HOLD_NO" NUMBER,
"BOOK_NO" NUMBER
) ;
--------------------------------------------------------
-- DDL for Table JAVA_BOOK_RENT
--------------------------------------------------------
CREATE TABLE "JAVA_BOOK_RENT"
( "HOLD_NO" NUMBER,
"MEM_NO" NUMBER,
"RENT" VARCHAR2(20 BYTE)
) ;
REM INSERTING into JAVA_BOOK
SET DEFINE OFF;
Insert into JAVA_BOOK (BOOK_NO,NAME,KIND,CONTENT) values (1,'올웨더 투자법','경제','꼭지에 사고 바닥일 때 털고 나오는, 언제나 돈과 어긋나는 사람들을 위한 투자 교과서. 투자의 성패는 예측에 좌우되는 것이 아니다. 시장에 따라 돈이 되는 종목은 따로 있다. 우산 장수와 나막신 장수 두 아들을 둔 어머니처럼 비가 오는 날엔 우산을 팔고 맑은 날에는 나막신을 팔면, 언제나 웃을 수 있다. 투자도 마찬가지. 시장 변화에 종목을 바꿔 대응하면 언제든 ‘수익’을 낼 수 있다!');
Insert into JAVA_BOOK (BOOK_NO,NAME,KIND,CONTENT) values (2,'돈의 속성 ','경제','돈의 속성』은 3년 전 어느 극장 하나를 빌려 대중에게 강의했던 내용을 기반으로 집필됐다. 강연은 방송을 통해 전파되며 유튜브와 셀럽들에 의해 공유와 전파를 거듭했다. 그리고 이내 1,100만 명에게 전달되기에 이르렀다. 하지만 여러 사람을 통해 생산 및 재생산되는 과정에서 어떤 의미는 그 뜻이 정확히 전달되지 않았거나 의미가 왜곡되는 일이 있었다');
Insert into JAVA_BOOK (BOOK_NO,NAME,KIND,CONTENT) values (3,'클래식 음악 수업','예술','클래식 음악에 한결 더 가까이
알고 들으면 더 감동적인 클래식 음악의 세계
음악은 언어와도 같습니다. 클래식 음악은 낯선 외국어입니다. ');
Insert into JAVA_BOOK (BOOK_NO,NAME,KIND,CONTENT) values (4,'모든 순간의 클래식','예술','두려움과 불안, 반복되는 일상에서 느끼는 무기력, 누군가를 향한 그리움, 실패 후 느끼는 좌절…… 인생은 똑같이 흘러가는 듯 보이지만 실상 우리는 매일 완전히, 혹은 미묘하게 다른 감정의 순간들을 마주하며 살아간다. 그 순간 우리는 마치 무언가에 홀린 듯 어떤 선율을 떠올리거나 읊조린다. 선율은 추억이 담긴 음악일 수도, 젊었던 나를 위로한 멜로디일 수도, 그저 별 이유 없이 떠오른 음악일 수도 있다. 분명한 사실은 그 선율이 과거의 어느 날 당신을 위로했고, 여전히 당신의 마음을 어루만지고 있으며, 앞으로도 당신을 헤아리고 보듬어줄 거라는 것이다.');
REM INSERTING into JAVA_BOOK_HOLD
SET DEFINE OFF;
Insert into JAVA_BOOK_HOLD (HOLD_NO,BOOK_NO) values (1,1);
Insert into JAVA_BOOK_HOLD (HOLD_NO,BOOK_NO) values (2,1);
Insert into JAVA_BOOK_HOLD (HOLD_NO,BOOK_NO) values (3,2);
Insert into JAVA_BOOK_HOLD (HOLD_NO,BOOK_NO) values (4,2);
Insert into JAVA_BOOK_HOLD (HOLD_NO,BOOK_NO) values (5,3);
Insert into JAVA_BOOK_HOLD (HOLD_NO,BOOK_NO) values (6,3);
Insert into JAVA_BOOK_HOLD (HOLD_NO,BOOK_NO) values (7,4);
REM INSERTING into JAVA_BOOK_RENT
SET DEFINE OFF;
Insert into JAVA_BOOK_RENT (HOLD_NO,MEM_NO,RENT) values (1,1,'Y');
Insert into JAVA_BOOK_RENT (HOLD_NO,MEM_NO,RENT) values (2,1,'N');
Insert into JAVA_BOOK_RENT (HOLD_NO,MEM_NO,RENT) values (2,2,'Y');
Insert into JAVA_BOOK_RENT (HOLD_NO,MEM_NO,RENT) values (3,1,'N');
--------------------------------------------------------
-- DDL for Index JAVA_BOOK_PK
--------------------------------------------------------
CREATE UNIQUE INDEX "JAVA_BOOK_PK" ON "JAVA_BOOK" ("BOOK_NO")
;
--------------------------------------------------------
-- DDL for Index JAVA_BOOK_HOLD_PK
--------------------------------------------------------
CREATE UNIQUE INDEX "JAVA_BOOK_HOLD_PK" ON "JAVA_BOOK_HOLD" ("HOLD_NO")
;
--------------------------------------------------------
-- Constraints for Table JAVA_BOOK
--------------------------------------------------------
ALTER TABLE "JAVA_BOOK" ADD CONSTRAINT "JAVA_BOOK_PK" PRIMARY KEY ("BOOK_NO") ENABLE;
ALTER TABLE "JAVA_BOOK" MODIFY ("BOOK_NO" NOT NULL ENABLE);
--------------------------------------------------------
-- Constraints for Table JAVA_BOOK_HOLD
--------------------------------------------------------
ALTER TABLE "JAVA_BOOK_HOLD" MODIFY ("BOOK_NO" NOT NULL ENABLE);
ALTER TABLE "JAVA_BOOK_HOLD" ADD CONSTRAINT "JAVA_BOOK_HOLD_PK" PRIMARY KEY ("HOLD_NO") ENABLE;
ALTER TABLE "JAVA_BOOK_HOLD" MODIFY ("HOLD_NO" NOT NULL ENABLE);
--------------------------------------------------------
-- Constraints for Table JAVA_BOOK_RENT
--------------------------------------------------------
ALTER TABLE "JAVA_BOOK_RENT" MODIFY ("HOLD_NO" NOT NULL ENABLE);
최종적인 프로젝트 파일은 바로 하단에 접기로 기입해놓았다.
package controller;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import service.BookService;
import util.ScanUtil;
import util.View;
import view.Print;
import vo.BookVo;
public class MainController extends Print{
// sessionStorage은 하나 밖에 존재하지 않음
static public Map<String, Object> sessionStorage = new HashMap<>();
BookService bookService = BookService.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 MEMBER:
view = member();
break;
case ADMIN:
view = admin();
break;
case MEM_BOOK_LIST:
view = bookList();
break;
case BOOK_RENT:
view = bookRent();
break;
case BOOK_RENT_LIST:
view = bookRentList();
break;
case ADMIN_BOOK_LIST:
view = adminBookList();
break;
case BOOK_ADD:
view = bookAdd();
break;
case BOOK_HOLD_ADD:
view = bookHoldAdd();
break;
default:
break;
}
}
}
// 도서 수량 변경
private View bookHoldAdd() {
System.out.println("도서 수량 변경");
System.out.println("#전체 도서 내역 출력");
return null;
}
// 신규 도서 등록
private View bookAdd() {
System.out.println("신규 도서 등록");
return View.MAIN;
}
// 전체 도서 조회(관리자)
private View adminBookList() {
System.out.println("전체 도서 조회");
return View.MAIN;
}
// 관리자
private View admin() {
printAdmin();
int sel = ScanUtil.menu();
switch (sel) {
case 1:
return View.ADMIN_BOOK_LIST;
case 2:
return View.BOOK_ADD;
case 3:
return View.BOOK_HOLD_ADD;
default:
return View.MAIN;
}
}
// 도서 대여 내역 조회
private View bookRentList() {
// 전체 대여 내역 출력
int mem_no = (int)sessionStorage.get("mem_no");
List<Map<String, Object>> rentList = bookService.bookRentList(mem_no);
// 출력
System.out.println("책 이름\t내용\t종류\t대여여부");
for (Map<String, Object> map : rentList) {
String name = (String)map.get("NAME");
String content = (String)map.get("CONTENT");
String kind = (String)map.get("KIND");
String rent = (String)map.get("RENT");
System.out.println(name + "\t" + content + "\t" + kind + "\t" + rent);
}
printMemberRentalList();
int sel = ScanUtil.menu();
if(sel == 1) {
// 대여 중인 도서 출력
List<Map<String, Object>> rentListY = bookService.bookRentListY(mem_no);
for (Map<String, Object> map : rentListY) {
String name = (String)map.get("NAME");
String content = (String)map.get("CONTENT");
String kind = (String)map.get("KIND");
String rent = (String)map.get("RENT");
System.out.println(name + "\t" + content + "\t" + kind + "\t" + rent);
}
}
return View.MEMBER;
}
// 도서 대여
private View bookRent() {
List<Map<String, Object>> list = bookService.bookRentPossible();
for (Map<String, Object> map : list) {
BigDecimal hold_no = (BigDecimal)map.get("HOLD_NO");
String name = (String)map.get("NAME");
String kind = (String)map.get("KIND");
String content = (String)map.get("CONTENT");
System.out.println(hold_no.intValue() + "\t" + name + "\t" + kind + "\t" + content);
}
printMemberRental();
int sel = ScanUtil.menu();
if(sel == 2) {
String kind = ScanUtil.nextLine("종류 >> ");
List<Map<String, Object>> kindList
= bookService.bookRentPossibleList(kind, sel);
for (Map<String, Object> map : kindList) {
BigDecimal hold_no = (BigDecimal)map.get("HOLD_NO");
String name = (String)map.get("NAME");
String kind2 = (String)map.get("KIND");
String content = (String)map.get("CONTENT");
System.out.println(hold_no.intValue() + "\t" + name + "\t" + kind2 + "\t" + content);
}
}
if(sel == 3) {
String content = ScanUtil.nextLine("내용 >> ");
}
return View.MAIN;
}
// 전체 도서 조회
private View bookList() {
List<BookVo> bookList = bookService.bookList();
for (BookVo bookVo : bookList) {
System.out.println(bookVo);
}
return View.MEMBER;
}
// 일반 회원
private View member() {
printMember();
int sel = ScanUtil.menu();
switch (sel) {
case 1:
return View.MEM_BOOK_LIST;
case 2:
return View.BOOK_RENT;
case 3:
return View.BOOK_RENT_LIST;
default:
return View.MAIN;
}
}
// 홈
private View home() {
sessionStorage.put("mem_no", 1); // 로그인 생략
printHome();
int sel = ScanUtil.menu();
switch (sel) {
case 1:
return View.MEMBER;
case 2:
return View.ADMIN;
default:
return View.MAIN;
}
}
}
package dao;
import java.util.List;
import java.util.Map;
import util.JDBCUtil;
import vo.BookVo;
public class BookDao {
private static BookDao instance = null;
private BookDao() {
}
public static BookDao getInstance() {
if (instance == null) {
instance = new BookDao();
}
return instance;
}
JDBCUtil jdbc = JDBCUtil.getInstance();
public List<BookVo> bookList() {
String sql = "select book_no, name, kind, "
+"substr(content, 0, 10) content\r\n" +
"from java_book";
return jdbc.selectList(sql, BookVo.class);
}
public List<Map<String, Object>> bookRentList(int mem_no) {
String sql = "select b.name, b.kind,\r\n" +
"substr(b.content, 0, 10) content, br.rent\r\n" +
"from java_book_rent br, java_book b, java_book_hold bh\r\n" +
"where bh.hold_no = br.hold_no\r\n" +
"and bh.book_no = b.book_no\r\n" +
"and mem_no = " + mem_no;
return jdbc.selectList(sql);
}
public List<Map<String,Object>> bookRentListY(int mem_no) {
String sql = "select b.name, b.kind,\r\n" +
"substr(b.content, 0, 10) content, br.rent\r\n" +
"from java_book_rent br, java_book b, java_book_hold bh\r\n" +
"where bh.hold_no = br.hold_no\r\n" +
"and bh.book_no = b.book_no\r\n" +
"and mem_no = " + mem_no +
"and br.rent = 'Y'";
return jdbc.selectList(sql);
}
public List<Map<String, Object>> bookRentPossible() {
String sql = "with data as(\r\n" +
"select *\r\n" +
"from java_book_hold h\r\n" +
"where not h.hold_no in (select hold_no \r\n" +
" from java_book_rent\r\n" +
" where rent = 'Y')\r\n" +
")\r\n" +
"select d.hold_no, b.name, b.kind,\r\n" +
"substr(b.content, 0, 10) content\r\n" +
"from data d, java_book b\r\n" +
"where d.book_no = b.book_no\r\n" +
"order by b.book_no";
return jdbc.selectList(sql);
}
public List<Map<String, Object>> bookRentPossibleList(String kind, int sel) {
String sql = "with data as(\r\n" +
"select *\r\n" +
"from java_book_hold h\r\n" +
"where not h.hold_no in (select hold_no \r\n" +
" from java_book_rent\r\n" +
" where rent = 'Y')\r\n" +
")\r\n" +
"select d.hold_no, b.name, b.kind,\r\n" +
"substr(b.content, 0, 10) content\r\n" +
"from data d, java_book b\r\n" +
"where d.book_no = b.book_no\r\n" +
// "and kind like '%'||?||'%'\r\n" +
"and kind like '%" + kind + "%'\r\n" +
"order by b.book_no";
return jdbc.selectList(sql);
}
}
package service;
import java.util.List;
import java.util.Map;
import dao.BookDao;
import vo.BookVo;
public class BookService {
private static BookService instance = null;
private BookService() {
}
public static BookService getInstance() {
if (instance == null) {
instance = new BookService();
}
return instance;
}
BookDao dao = BookDao.getInstance();
public List<BookVo> bookList() {
return dao.bookList();
}
public List<Map<String, Object>> bookRentList(int mem_no) {
return dao.bookRentList(mem_no);
}
public List<Map<String,Object>> bookRentListY(int mem_no) {
return dao.bookRentListY(mem_no);
}
public List<Map<String, Object>> bookRentPossible() {
return dao.bookRentPossible();
}
public List<Map<String, Object>> bookRentPossibleList(String kind, int sel) {
return dao.bookRentPossibleList(kind, sel);
}
}
package vo;
public class BookVo {
private int book_no;
private String name;
private String kind;
private String content;
public int getBook_no() {
return book_no;
}
public void setBook_no(int book_no) {
this.book_no = book_no;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getKind() {
return kind;
}
public void setKind(String kind) {
this.kind = kind;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
@Override
public String toString() {
return "BookVo [book_no=" + book_no + ", name=" + name + ", kind=" + kind + ", content=" + content + "]";
}
}
package view;
public class Print {
public void printVar() {
System.out.println("============================");
}
public void printLn(int num) {
for(int i=0; i<num; i++) System.out.println();
}
public void printHome() {
printVar();
System.out.println("----------- 도서 관리 프로젝트 -----------");
System.out.println("1. 일반 회원");
System.out.println("2. 관리자");
printLn(4);
printVar();
}
public void printMember() {
printVar();
System.out.println("----------- 일반 회원 -----------");
System.out.println("1. 전체 도서 조회");
System.out.println("2. 도서 대여");
System.out.println("3. 도서 대여 내역 조회");
printLn(3);
printVar();
}
public void printMemberRental() {
printVar();
System.out.println("------ 일반회원 도서 대여 ------");
System.out.println("1. 제목 검색");
System.out.println("2. 종류 검색");
System.out.println("3. 내용 검색");
printLn(3);
printVar();
}
public void printMemberRentalList() {
printVar();
System.out.println("------ 도서 대여 내역 조회 ------");
System.out.println("1. 대여 중인 도서");
System.out.println("2. 홈");
printLn(3);
printVar();
}
public void printAdmin() {
printVar();
System.out.println("------ 관리자 ------");
System.out.println("1. 전체 도서 조회");
System.out.println("2. 신규 도서 등록");
System.out.println("3. 도서 수량 변경");
printLn(3);
printVar();
}
}
package util;
public enum View {
MAIN, // 기본화면
ADMIN, // 관리자
MEMBER, // 일반 회원
MEM_BOOK_LIST, // 일반회원 전체 조회
BOOK_RENT, // 도서 대여
BOOK_RENT_LIST, // 도서 대여 내역
ADMIN_BOOK_LIST, // 관리자 전체 도서 조회
BOOK_ADD, // 신규 도서 등록
BOOK_HOLD_ADD // 도서 수량 변경
}
package util;
import java.util.Scanner;
public class ScanUtil {
// 스캐너를 손쉽게 사용할 수 있는 static 메서드를 가지고있음
static Scanner sc = new Scanner(System.in);
public static int menu() {
return nextInt("메뉴 선택 : ");
}
public static String nextLine(String print) {
System.out.print(print);
return nextLine();
}
private static String nextLine() {
return sc.nextLine();
}
public static int nextInt(String print) {
System.out.print(print);
return nextInt();
}
private static int nextInt() {
while(true) {
try {
int result = Integer.parseInt(sc.nextLine());
return result;
}catch (NumberFormatException e) {
System.out.println("잘못 입력!!");
}
}
}
}
TIP (Database)
- whith as 문
: 복잡한 부분의 쿼리를 분리해서 사용할 수 있는 문. 서브 쿼리를 옮겨 괄호 안에 넣어두면 된다.
with 테이블이름 as (
서브쿼리;
)
-- with as문 : 복잡한 부분의 쿼리를 분리해서 사용할 수 있는 문. 서브 쿼리를 옮겨 괄호 안에 넣어두면 된다.
with data as(
select *
from java_book_hold h
where not h.hold_no in (select hold_no
from java_book_rent
where rent = 'Y')
)
select d.hold_no, b.name, b.kind, substr(b.content, 0, 10) content
from data d, java_book b
where d.book_no = b.book_no
and kind like '%'||'경제'||'%'
order by b.book_no;
- VO 생성
SQL Developer 에 하단의 코드를 작성하여 복붙하면 좀 더 쉽게 vo를 생성할 수 있다.
SELECT
' private '||
DECODE( DATA_TYPE , 'NUMBER', 'int ', 'String ' )||
LOWER(COLUMN_NAME)||';'
FROM COLS
WHERE TABLE_NAME = '테이블이름' -- 대문자로 입력하지 않을시 오류뜸
ORDER BY COLUMN_ID;
반응형
'자바' 카테고리의 다른 글
[Java 초급] 28장 MVC 패턴6 : 영화 예매 (0) | 2024.01.10 |
---|---|
[Java 초급] 27장 MVC 패턴5 : 게시판2 (0) | 2024.01.09 |
[Java 초급] 25장 MVC 패턴3 : 커피 주문 시스템 (0) | 2024.01.08 |
[Java 초급] 24장 MVC 패턴2 : 게시판 만들기1 (0) | 2024.01.04 |
[Java 초급] 23장 MVC 패턴1, 회원가입 (2) | 2024.01.03 |