본문 바로가기

2. MySQL | MongoDB

3/21(화) IT K-DT(14일차) / 4.사용자,뷰,트랜젝션,인덱스~5.DAO,DTO,VO


4-1. 사용자

    4-1-1. 사용자 계정 추가하기

    4-1-2. 사용자 계정 삭제하기

    4-1-3. 사용자 목록 조회하기

    4-1-4. 사용자 권한 조회하기

    4-1-5. 사용자 권한 제거하기

 

4-2. 뷰(view)

    4-2-1. 뷰(view)의 정의

    4-2-2. 뷰(view)의 목적

    4-2-3. 뷰(view)의 생성

    4-2-4. 뷰(view)의 수정

    4-2-5. 뷰(view)의 대체

    4-2-6. 뷰(view)의 삭제

    4-2-7. 뷰(view)의 내부 데이터 변경

 

4-3. 트랜젝션(Transaction)

    4-3-1. 트랜젝션의 정의

    4-3-2. 트랜젝션의 명령어

    4-3-3. 트랜젝션의 형태

    4-3-4. 트랜젝션의 특징

    4-3-5. 트랜젝션의 예외

 

4-4. 인덱스(index)

    4-4-1. 인덱스, order by절, group by절

    4-4-2. 인덱스 생성

    4-4-3. 인덱스 조회

    4-4-4. 인덱스 삭제

 

5. 소프트웨어 디자인 패턴

    5-1. DAO(Data Access Object)

    5-2. DTO(Data Transfer Object)

    5-3. VO(Value Object)

    5-4. MVC 패턴

 

예제


4-1. 사용자

 

4-1-1. 사용자 계정 추가하기

 

직접 서버에 접속해서 SQL을 다룰 일도 있기 때문에 terminal에도 익숙해져야함.

→ MySQL workbench가 아닌, terminal에서 실행할 예정.

MySQL command line client 실행 → 비밀번호 '1234' 입력 (root 계정으로 로그인을 한 상황)

 


로컬에서 접속 가능한 사용자(user) 추가하기


 CREATE user '사용자명' @ 'localhost' IDENTIFIED BY '사용자 비밀번호' ;

user 'apple' 을 새롭게 생성. 사용자 비밀번호는 1111.


CREATE user 'apple'@'localhost' IDENTIFIED BY '1111';

→ Query OK, 0 rows affected (0.01 sec) 라는 줄이 출력. (정상적인 출력 상황)

 

 

DB의 접근 권한을 부여하는 방법

localhost의 사용자에 모든 권한을 부여하고 싶은 경우.


GRANT all privileges ON  * . *  TO  '사용자' @ 'localhost' ;  

FLUSH PRIVILEGES ;
setting을 적용하겠다.

 

할당 권한의 상세 옵션. (복수로 삽입할 수 있음)
  create, drop, alter: 테이블에 대한 생성, 삭제, 변경의 권한.
  select, insert, update, delete: 테이블의 데이터를 조회, 삽입, 변경, 삭제에 대한 권한.
  all privileges: 모든 권한.
  usage: 권한을 부여하지 않고 계정만 생성함.

 

IP 권한의 상세 옵션.
  %: 모든 IP에서 접근이 가능하도록 함.
  127.0.0.1: localhost에서 접근이 가능하도록 하는 IP번호.


모든 IP에서 접근이 가능하도록 특정 데이터베이스에 select의 권한만 별도로 부여.


 GRANT select ON 데이터베이스명 TO  '사용자' @ '%' ;

특정 IP에서 접근이 가능하도록 특정 데이터베이스에 select의 권한만 별도로 부여.


 GRANT select ON 데이터베이스명 TO '사용자' @ '특정 ip주소' ;

' apple ' 이라는 새로운 데이터베이스를 생성하고 localhost에서 접근이 가능하도록 권한을 부여.

 

Workbench 홈 화면에서 새로운 데이터베이스를 생성하는 화면.

  1. MySQL Connection에서 (+)버튼 클릭.
  2. Connection Name, Username을 작성한 후, Test Connection 클릭. (Hostname과 Fort는 건드리지 않음.)
  3. 지정할 비밀번호를 입력(여기서는 '1111'). 이후 OK 클릭.

  4. 정상적으로 창의 확인이 가능.


create database apple; 

grant all privileges on apple.* to 'apple' @ 'localhost' ;

 

 

4-1-2. 사용자 계정 삭제하기

 


DROP user '사용자명' @ 'localhost' ;

 


 flush privileges
 MySQL 데이터베이스에서 권한 및 권한 캐시를 다시 로드하는 데 사용되는 SQL문. 
 MySQL 데이터베이스는 권한을 관리하기 위해 권한 캐시를 사용. 이 캐시에는 데이터베이스 사용자와 그들의 권한이 저장. 
 때로는 권한을 변경하거나 새로운 사용자를 추가한 후에도 이 캐시가 갱신되지 않는 경우가 있는데,
 이때 'flush privileges'를 입력하여 권한 캐시를 다시 로드할 수 있음.
 현재 실행 중인 모든 사용자 세션에 대해 권한을 다시 로드하기 때문에, 권한 변경을 적용하려는 경우 꼭 입력해야 함.

 

4-1-3. 사용자 목록 조회하기


 현재 MySQL 서버에 등록되어있는 모든 user의 조회를 하고 싶은 경우.


SELECT user, host FROM mysql.user ;

현재 MySQL 서버에 등록되어있는 user 중 'apple'이 있는지의 여부를 조회하고 싶은 경우.


SELECT user, host FROM mysql.user WHERE user = 'apple' ;

user 중 'mysql.' 이 있는 것은 시스템계정이므로 사용하지 않음.

이들을 제외한다면, user는 apple, orange, root이 존재하는 것을 확인할 수 있음.

 

4-1-4. 사용자 권한 조회하기

 


SHOW GRANTS FOR '계정명' @ 'localhost' ;

데이터베이스 'apple'의 권한을 조회하고 싶은 경우.


SHOW GRANTS FOR 'apple'@'localhost'; 

 

 

4-1-5. 사용자 권한 제거하기

 


REVOKE 권한명 PRIVILEGES ON 데이터베이스명.테이블명 FROM '계정명' @ 'localhost' ;

데이터베이스 'apple'의 모든 권한을 제거하고 싶은 경우.


REVOKE all PRIVILEGES ON apple.* FROM 'apple' @ 'localhost' ;

 


4-2. 뷰(view)

 

4-2-1. 뷰(view)의 정의

 

실제 테이블을 참고하여 가상의 테이블을 생성하는 것.
실제 테이블이 존재해야 하며, 실제 테이블처럼 행과 열을 갖고 있지만 데이터를 직접 저장하고 있지는 않음.

 

 

4-2-2. 뷰(view)의 목적

 

SQL코드를 간결하게 하여 사용.

삽입, 삭제, 수정 작업에 제한 사항이 필요한 경우 사용.
내부 데이터를 전체 공개하고 싶지 않은 경우 사용 → 데이터의 보안성, 안정성의 제고 목적.

  (실제 table에 접근할 수 없도록 하고 view만 공개 → view의 select가 가능하도록 함.)

 

 

4-2-3. 뷰(view)의 생성


CREATE VIEW 뷰이름 AS 쿼리 ...

member 테이블의 userid, username, hp, gender의 field값을 view로 생성하고 싶은 경우.


SELECT userid, username, hp, gender FROM member; 

'vw_member'라는 해당 view를 생성.


CREATE view vw_member AS SELECT userid, username, hp, gender FROM member; 

'vw_member'가 정상적으로 생성되었는지 확인.


SELECT * FROM vw_member; 

 

 

4-2-4. 뷰(view)의 수정


ALTER VIEW
 뷰이름 AS 쿼리 ... ;

 

4-2-5. 뷰(view)의 대체

뷰(View)를 생성 또는 교체하는 명령문.

뷰를 생성하는 것과 유사하지만, 이미 동일한 이름을 가진 뷰가 존재하는 경우에는 해당 뷰를 대체함.

이 명령문은 뷰의 정의를 변경하는 것으로, 뷰를 참조하는 다른 쿼리에 영향을 줄 수 있음.

이러한 이유로, 해당 명령문을 실행할 때는 주의해야 함,


CREATE OR REPLACE VIEW 뷰이름 AS 쿼리 ...;

 

 

<예제2>로 생성된 view의 대체.


CREATE OR REPLACE VIEW vw_memberprofile AS

( SELECT m.userid, m.username, m.hp, p.MBTI FROM member as m INNER JOIN profile as p ON m.userid1 = p.userid ; )

 

 

4-2-6. 뷰(view)의 삭제


DROP VIEW 뷰이름 ;

 

4-2-7. 뷰(view)의 내부 데이터 변경

뷰(View)는 가상 테이블이므로 내부 데이터를 직접 수정하는 것은 불가능함.

뷰는 하나 이상의 기본 테이블에서 검색된 결과를 보여주는 것으로,

뷰를 통해 데이터를 수정하려면 해당 뷰의 기본 테이블을 수정해야 함.

 

따라서, 뷰의 내부 데이터를 변경하고 싶은 경우에는 뷰를 만들 때 사용한 기본 테이블을 직접 수정해야 함.

이때 기본 테이블의 데이터를 수정하면, 해당 뷰를 사용하는 모든 쿼리에서 수정된 데이터를 확인할 수 있음.


UPDATE 뷰이름 SET 변경할데이터 WHERE 조건 ; 

userid가 jeong인 hp를 9999로 변경하고 싶은 경우.


UPDATE vw_member SET hp='9999' WHERE userid='jeong';

insert into vw_member values ('cha', '차', '7777', 'INFJ'); 
table이 not null 제약조건이기 때문에 data의 insert가 불가능함. → 오류발생.

→ view를 통해 insert를 하고싶은 경우, data를 모두 null처리 해주어야 함.

   (Error Code: 1423. Field of view 'kdt.vw_member' underlying table doesn't have a default value.)


4-3. 트랜젝션(Transaction)

 

4-3-1. 트랜젝션의 정의

분할이 불가능한 업무처리의 단위. 한꺼번에 수행되어야 할 연산의 모음.
데이터베이스의 상태를 변경하는 하나의 논리적인 작업 단위를 말함. 

이 작업은 한 번에 모두 수행되거나, 전혀 수행되지 않아야 함. 

즉, 트랜잭션은 데이터베이스의 일관성을 보장하기 위해 필요한 개념임.

 

4-3-2. 트랜젝션의 명령어

commit: 모든 작업을 정상 처리하겠다고 확정. 모든 작업이 정상적으로 완료되었다는 것을 의미. 

              해당 처리 과정이 데이터베이스에 영구적으로 저장.
rollback: 작업 중 문제가 발생되어 트랜젝션의 처리 과정에서 발생한 변경사항을 모두 취소. 

              데이터베이스를 이전상태로 되돌림. 

 

4-3-3. 트랜젝션의 형태


 start transaction
     ...
     성공 or 실패 둘 중 하나의 결과.
     문제가 발생하면 rollback;
 정상적인 처리가 완료되면 commit;

블록안의 명령어들은 하나의 명령어처럼 처리됨

 

 

4-3-4. 트랜젝션의 특징

원자성: 데이터베이스에 모두 반영되거나, 전혀 반영되지 않아야 함.
             작업이 중간에 실패하면 이전 상태로 되돌리고, 성공적으로 완료되면 모든 작업이 반영되어야 함.
일관성: 수행 전과 수행 후의 작업 처리 결과가 항상 일관성이 있어야 함.
독립성: 어떤 트랜젝션이 다른 트랜젝션의 연산에 끼어들 수 없음.
             트랜잭션을 실행하는 동안 다른 트랜잭션이 해당 데이터를 변경할 수 없도록 보장해야 함.
영구성: 모든 작업이 성공적으로 완료되면, 이전 상태로 돌아갈 수 없도록 결과는 영구적으로 반영되어야 함.


autocommit 모드
데이터베이스 연결 시 자동으로 실행되는 트랜젝션 모드. 모든 변경사항이 즉시 데이터베이스에 반영됨.
일반적으로 개발 및 테스트 단계에서 사용되며, 간단한 쿼리나 데이터베이스에서 읽기만 하는 작업에 적합.

그러나 큰 규모의 트랜잭션을 처리하거나 복잡한 데이터베이스 연산을 수행하는 경우 적합하지 않을 수 있음.
autocommit 모드를 해제하면 여러 개의 SQL 문을 하나의 트랜잭션으로 묶어서 처리할 수 있으며,

이를 통해 데이터베이스의 일관성과 무결성을 보장할 수 있음.
이를 위해서는 각 트랜잭션의 시작과 끝을 명시적으로 지정해주어야 함.

대부분의 데이터베이스 관리 시스템은 autocommit 모드를 해제하기 위한 설정 옵션을 제공하며 이를 이용할 수 있음.

show variables like ' % commit % ' ;
set autocommit = 1; # ON으로 변경.
set autocommit = 0; # OFF로 변경.

 

commit을 이용하여 product의 table에 data를 추가하는 경우.


select * from product;
start transaction; # 트랜젝션의 시작. commit 또는 rollback으로 마무리 해야 함.
insert into product values ('100005', '고철', '팔아요', 100, now()); # product의 table에 data 추가.
commit; # 트랜젝션을 데이터베이스에 적용 (autocommit가 ON이라면 굳이 작성할 필요 없음.)

rollback을 이용하여 product의 table에 data를 추가하는 경우.


select * from product;
start transaction; # 트랜젝션의 시작. commit 또는 rollback으로 마무리 해야 함.
insert into product values ('100006', '공병', '팔아요', 50, now()); # product의 table에 data 추가.
rollback# 트랜젝션을 취소하고 start transaction 상태로 롤백함.

 

4-3-5. 트랜젝션의 예외

DDL문(Data Definition Language. create, drop, alter, rename, truncate)은 트랜젝션의 예외

  → 트랜젝션의 영향을 받지 않아 rollback 적용 대상이 아님.
       truncate: 개별적으로 행을 삭제할 수 없으며, 테이블 전체를 한번에 삭제.
                      트랜젝션 로그에 한 번만 기록하므로 delete 구문보다 성능면에서 빠름.
                      truncate table 테이블명 = delete from 테이블명


delete구문 사용 시에는 트랜젝션(rollback)의 사용이 가능.


select * from product_new; 
start transaction;
delete from product_new;
select * from product_new;
rollback;

truncate구문 사용 시 트랜젝션(rollback) 사용이 불가능.


start transaction;
truncate table from product_new;
select * from product_new;
rollback;
select * from product_new;

 


4-4. 인덱스(index)

 

데이터베이스 테이블에 있는 데이터의 검색 속도를 높이기 위해 사용되는 데이터 구조.
데이터의 위치를 찾아주는 역할. 테이블에서의 인덱스 정보는 MYI(MySQL Index)파일(.myi)에 저장.
인덱스를 설정하지 않으면 Table Full Scan이 일어나 성능이 저하되거나 장애가 발생할 수 있음.

 


 Table Full Scan
 데이터베이스에서 전체 테이블을 순차적으로 조회하는 것.

 테이블에 대한 쿼리에서 where조건이나 join조건이 없는 경우 발생할 수 있음.
 대규모 테이블에서는 매우 느리고 성능에 부담을 주는 작업.

조회속도는 빨라지나 update, insert, delete의 속도는 저하될 수 있기 때문에, 적절한 Index의 설정이 중요함.
MySQL에서는 primary key, unique 제약조건을 사용하면 해당 컬럼에 index가 적용됨.
하나 또는 여러개의 컬럼에 설정할 수 있음.
where절을 사용하여 index가 걸린 컬럼을 조회해야 효과가 있음.


만약 where절을 사용하지 않고 index가 걸린 컬럼을 조회하는 경우,

모든 데이터를 가져오기 때문에 index가 사용되지 않고 전체 테이블 스캔을 수행하게 됨

→ index를 사용하지 않은 것과 마찬가지로 모든 데이터를 읽어와야 하기 때문에 성능상 이점이 없어짐.

    가급적 update가 안되는 값을 index로 설정하는 것을 추천.

 

 

4-4-1. 인덱스, order by절, group by절

데이터베이스에서 order by절이나 group by절을 사용 시, 

결과 데이터를 정렬하거나 그룹화하기 위해 전체 테이블을 스캔해야 함. 

이때 index를 사용하면 데이터베이스가 빠르게 결과를 반환할 수 있음.
(order by나 group by절을 사용할 경우 해당 컬럼에 index를 생성 → 성능 향상)


 
# 복수의 키에 대해 order by를 실행한 경우.
 ORDER BY 인덱스컬럼, 일반컬럼

 # 연속하지 않은 컬럼에 대해 order by를 실행한 경우에는 효과가 없음.

 WHERE 일반컬럼='값' ORDER BY 인덱스컬럼 

 # desc와 asc를 혼합하여 사용한 경우.

ORDER BY 인덱스컬럼1 DESC, 인덱스컬럼2 ASC

 # group by와 order by의 컬럼이 다른 경우.

 GROUP BY 일반컬럼1 ORDER BY 인덱스컬럼 

 # order by절에 컬럼이 아닌 다른 표현을 사용한 경우.

ORDER BY 함수(인덱스컬럼) 



4-4-2. 인덱스 생성


CREATE INDEX 인덱스명 ON 테이블명(필드명1, 필드명2 ...)

예) member테이블의 idx_hp인덱스 생성.


create index idx_hp on member(hp);

 

4-4-3. 인덱스 조회


SHOW INDEX FROM 테이블명;

예) member테이블의 index 조회.


show index from member;

 

4-4-4. 인덱스 삭제


ALTER table 테이블명 DROP index 인덱스명;

예) member테이블의 idx_hp인덱스 삭제.


alter table member drop index idx_hp;

 

 


5. 소프트웨어 디자인 패턴

 

5-1. DAO(Data Access Object)

데이터베이스의 data에 접근하기 위한 객체 (데이터 접근 객체).
직접 데이터베이스와 연동하여 데이터를 삽입, 조회, 변경, 삭제 등을 담당하는 객체.
일반적으로 데이터베이스에 접근하여 데이터를 가져오는 low-level 작업을 수행.
데이터베이스 접근 목적 로직과 비즈니스 로직의 분리, 유지보수성과 확장성의 제고가 목적.


비즈니스 로직
업무에 필요한 데이터처리를 수행하는 응용프로그램의 일부.
 애플리케이션에서 실제로 수행되는 업무처리 규칙과 로직. 

 데이터의 입력, 수정, 조회, 삭제 및 처리등을 수행하는 각종 처리를 의미.
 유저의 눈에는 보이지 않지만, 유저가 원하는 행위를 잘 전달하기 위해 짜여진 코드 로직.
 애플리케이션의 핵심. 효율적인 처리를 위해 성능의 최적화, 로직의 일관성과 유효성이 중요.

 

5-2. DTO(Data Transfer Object)

계층간 데이터 교환을 위해 사용되는 객체 (데이터 전송 객체).
데이터베이스, 웹서비스에서 사용되는 데이터 → 자바 객체로 변환.

데이터를 애플리케이션에서 사용하기 적합한 형태로 변경.
로직을 가지지 않는 순수한 데이터 객체.
데이터를 저장하는 필드와 getter/setter 메서드를 가짐.

layer간의 통신 용도로 사용하는 객체.


getter 메서드 : class의 필드값을 조회하기 위한 메서드. 보통 필드의 값을 반환함.
setter 메서드 : class의 필드값을 설정하기 위한 메서드. 매개변수로 전달받은 값을 필드에 저장함.


getter / setter 메서드는 필드 값을 외부에서 직접 조작하지 않고, 

메서드를 통해 간접적으로 조작함으로써 캡슐화를 구현하는 데에 중요한 역할을 함. 

즉, class의 필드값이 외부에서 마음대로 변경되는 것을 막아 class 내부의 일관성을 유지하고, 

필드 값의 유효성 검사 등의 로직을 추가할 수 있음. 

또한, 필드 값의 유효성을 검사하거나, 필드 값을 반환할 때 특정 로직을 추가하여 보안성을 높이는 것도 가능.
여러 개의 필드를 하나의 객체로 묶어 사용하며, 불필요한 데이터를 제외해 필요한 데이터만을 저장함.
더블클릭 또는 Enter 키를 눌러 수정이 가능.

 

 

5-3. VO(Value Object)

Read-Only 속성을 가진 오브젝트로, 특정 비즈니스 로직의 값을 담는 객체 (값 객체).
데이터를 담는 객체로 DTO와 유사한 개념이나, VO는 setter를 가지고 있지 않아 값을 변경할 수 없음.

 

DTO가 Instance 개념이라면, VO는 literal 개념.

instance : 객체를 생성하기 위해 class를 정의하고, 메모리에 할당하는 과정을 거치며,

                생성된 객체는 각각 독립적인 메모리공간을 갖고 있음.

                생성된 객체를 변수에 할당하거나, 메소드의 매개변수로 전달할 수 있음.
literal : 상수값을 사용하는 고정된 표기법. 메소드의 매개변수로 전달되지 않음.

 

5-4. MVC 패턴

디자인 패턴 중 하나로, Model-View-Controller의 약자.

 
 디자인 패턴
 프로그램이나 어떤 특정한 것을 개발하는 중에 발생했던 문제점들을 정리해서

 상황에 따라 간편하게 적용하여 쓸 수 있는 것을 정리한 '규약'을 통해 형태로 만든 것.

사용자가 view를 통해 controller를 조작하면 controller는 model을 통해 데이터를 가져오고,
그 정보를 통해 시각적인 담당을 하는 view를 다시 제어해서 사용자에게 전달됨.
소프트웨어의 세가지 주요 구성요소를 분리하여 애플리케이션을 개발하는 방식.

 

소프트웨어를 보다 모듈화하고 유지보수하기 쉽게 만들어줌.

각 구성 요소는 독립적으로 개발, 테스트, 유지보수할 수 있으며,

하나의 구성 요소를 수정해도 다른 구성 요소에 영향을 끼치지 않음.

이로써 개발자는 애플리케이션의 특정 부분을 수정하거나 개선하는 작업을 보다 효율적으로 수행할 수 있음.


DTO가 model의 포지션

DAO와 Service가 controller의 포지션

view는 그대로 view의 포지션.

 


Model
애플리케이션의 정보, 데이터를 나타냄.
사용자가 편집하기를 원하는 모든 데이터를 갖고 있음.
view나 controller에 대해 어떠한 정보도 알지 말아야 함.
변경이 일어나면 변경 통지에 대한 처리방법을 구현해야 함.


View
텍스트, 체크박스 등과 같은 사용자 인터페이스 요소를 나타냄.
model이 갖고 있는 정보를 따로 저장해서는 안됨.
model이나 controller와 같이 다른 구성요소들을 몰라야 함.


Controller

데이터와 사용자 인터페이스 요소들을 연결하는 다리 역할.
model과 view에 대해 알고 있어야 함.
model이나 view의 변경을 모니터링하거나 통신을 관리해야 함.
애플리케이션의 메인 로직은 controller가 담당함.

 


예제

 

문제1

apple 데이터베이스에 kdt.member 테이블을 복사하고, 

해당 테이블의 select 권한만 가능한 orange 계정을 만들어보자.


# 데이터베이스 'apple' 사용.

use apple; 

#SubQuery를 사용하여 kdt 데이터베이스의 member 테이블을 apple 데이터베이스로 복사.
create table apple.member (select * from kdt.member);

# user 'orange'를 생성. (사용자 비밀번호 : 1111)
create user 'orange'@'localhost' identified by '1111';

# user 'orange'에게 데이터베이스 apple의 member 테이블의 select 권한을 부여.

grant select on apple.member to 'orange'@'localhost';


# 변경된 내용에 대한 로드
flush privileges;

이후, workbench의 Home에서 orange의 계정을 새로 생성 → 정상적으로 입력이 되었는지 확인 가능.
update member set point = 500 where userid='cho'; 와 같이 update를 이용하려 하는 경우

→ 접근거부의 오류가 발생.

(Error Code: 1142. UPDATE command denied to user 'orange'@'localhost' for table 'member')

 

 

문제2

member의 userid, username, hp와 profile의 mbti를 출력하는

view + select만 할 수 있는 'melon'계정의 생성.


use kdt;
select * from member;
select * from profile;

# inner join을 이용하여 view 생성.
CREATE VIEW vw_memberprofile AS SELECT m.userid, m.username, m.hp, p.MBTI FROM member AS m

INNER JOIN profile AS p ON m.userid=p.userid;

# vw_memberprofile이 정상적으로 생성되었는지를 확인. 
select * from vw_memberprofile;

# user 'melon'의 생성. (사용자 비밀번호: 2222)
create user 'melon'@'localhost' identified by '2222';

# user 'melon'에 vw_memberprofile에 대한 select 권한을 부여.
grant select on kdt.vw_memberprofile to 'melon'@'localhost';

# 변경된 내용에 대한 로드

flush privileges;

'melon'의 데이터베이스를 workbench를 통해 생성한 후 접속해보면,
정상적으로 'vw_memberprofile'이 'melon'에 생성되고 select 권한이 부여된 것을 확인할 수 있음.

 

 

문제3

DAO, DTO를 활용한 영어단어장 만들기

#1. DTO역할의 class 생성 (교환)


class Words:

  def __init__(self, eng, kor, lev=1):
    self.eng = eng
    self.kor = kor
    self.lev = lev

  def setEng(self, eng):
    self.eng = eng

  def getEng(self):
    return self.eng
  
  def setKor(self, kor):
    self.kor = kor
  
  def getKor(self):
    return self.kor

  def setLev(self,lev):
    self.lev = lev

  def getLev(self):
    return self.lev

  def printWord(self):
    print(f'단어: {self.eng}, 뜻: {self.kor}, 레벨: {self.lev}')

word = Words('apple','사과',1)




         # word.lev = 2 로 변경하고 싶은 경우.
         word.setLev(2)

         # 변경된 내용의 확인이 필요한 경우.
         word.printWord() 
         단어: apple, 뜻: 사과, 레벨: 2


 

#2. DAO 역할의 class (조회, 추가, 수정, 삭제)


class WordsDao:

  def __init__(self):
    self.datas = []
    
  def insert(self, word):
    self.datas.append(word)

  def update(self, word):
    for i in self.datas:
      if i.getEng() == word.getEng(): # 기존에 저장된 단어와 수정할 단어가 같다면,
        i.setKor(word.getKor()) # 기존에 저장된 뜻에 수정할 단어의 뜻을 수정
        i.setLev(word.getLev())

  def search(self, eng): # 특정 영단어가 입력될 시 뜻과 레벨이 출력될 수 있도록 함.
    for i in self.datas:
      if i.getEng() == eng:
        return i

  def selectAll(self):
    return self.datas

  def delete(self, word):
    self.datas.remove(word)


#3. Service를 담당하는 class


class WordsService:

  def __init__(self):
    self.dao = WordsDao()

  def insertWord(self):
    eng = input('단어를 입력하세요:')
    kor = input('뜻을 입력하세요:')
    lev = input('레벨을 입력하세요:')
    word = Words(eng, kor, lev)
    self.dao.insert(word) #WordsDao class의 insert 함수로 들어가서 word가 datas로 append되는 상황.
    
  def printAll(self): # 모든 datas의 list를 출력.
    datas = self.dao.selectAll()
    for i in datas:
      i.printWord() # i 안에서 Words class의 printWord()가 실행됨. → 전체 data가 찍히게 됨.

  def searchWord(self):
    eng = input('검색할 단어를 입력하세요:')
    word = self.dao.search(eng)
    if word == None: # word가 찾는 값이 none인 경우.
      print('찾는 단어가 없습니다.')
    else:
      word.printWord() # printWord()를 실행함.

  def editWord(self):
    eng = input('수정할 단어를 입력하세요:')
    word = self.dao.search(eng)
    if word == None: # word가 찾는 값이 none인 경우.
      print('수정할 단어를 찾지 못했습니다.')
    else:
      kor = input('새로운 뜻을 입력하세요.')
      lev = input('새로운 레벨을 입력하세요.')
      word = Words(eng, kor, lev)
      self.dao.update(word)

  def delWord(self):
    eng = input('삭제할 단어를 입력하세요:')
    word = self.dao.search(eng) # 단어를 찾아옴.
    if word == None: # word가 찾는 값이 none인 경우.
      print('삭제할 단어를 찾지 못했습니다.')
    else:
      self.dao.delete(word)

 

#4. View 역할을 하는 class


class Menu:
  
  def __init__(self):
    self.service = WordsService() # self.service로 WordsService의 class를 가져와서 사용할 예정.
    
  def run(self): # 프로그램이 동작을 함.
    while True:
      try:
          menu = int(input('1. 등록하기 \n2. 출력하기 \n3. 검색하기 \n4. 수정하기 \n5. 삭제하기 \n6. 종료하기 \n'))
          if menu == 1:
            self.service.insertWord()
          elif menu == 2:
            self.service.printAll()
          elif menu == 3:
            self.service.searchWord()
          elif menu == 4:
            self.service.editWord()
          elif menu == 5:
            self.service.delWord()
          elif menu == 6:
            break
      except:
        print('다시 입력하세요.')


 

#5. 프로그램을 실행.


start = Menu()
start.run()

 


과제

 

내용 : 지금까지 배운 python과 mySQL을 이용하여 자유주제로 프로그램을 제작해보기.

기한 : 3/27(월) 오전 9시 이전까지.

참고 : 첨부한 '화면설계서' ppt파일을 작성하면서 프로그램 제작.

화면설계서 양식.pptx
0.08MB