[14일차-3] MySQL을 활용한 단어장 (작성중)

2026. 6. 9. 23:41KDT/3. Python과 MySQL 연동

 

# 사용할 MySQLdb 모듈 선택
import MySQLdb
class Word:
    def __init__(self, eng, kor, lev=1):
        self.eng = eng
        self.kor = kor
        self.lev = lev

    def __repr__(self):     # 매직메서드
        return f"Word(eng={self.eng}', kor='{self.kor}', lev={self.lev})"
    
    @property               # 제너레이터
    def eng(self):
        return self.__eng

    @eng.setter
    def eng(self,eng):
        if not eng:         # eng가 존재하지 않으면 에러
            raise ValueError('영어 단어는 비워둘 수 없습니다')
        self.__eng = eng
    
    @property
    def kor(self):
        return self.__kor
    
    @kor.setter
    def kor(self, kor):
        if not kor:
            raise ValueError('뜻을 비워둘 수 없습니다')
        self.__kor = kor

    @property
    def lev(self):
        return self.__lev
    
    @lev.setter
    def lev(self, lev):
        lev = int(lev)
        if lev < 1:
            raise ValueError('레벨은 1 이상이어야 합니다')
        self.__lev = lev
# db 관리하는 클래스
# Data Access Object : db에 연결시켜주는 객체
class WordsDAO:
    def __init__(self):
        self.db = None

    def connect(self):
        self.db = MySQLdb.connect(host='localhost', user='apple', password='1111', db='ai', charset='utf8')

    def disconnect(self):
        if self.db:
            self.db.close()

    def insert(self, word):     # word 객ㅊ
        self.connect()
        cur = self.db.cursor()
        sql = "insert into voca (eng, kor, lev) values (%s, %s, %s)"
        data = (word.eng, word.kor, word.lev)
        cur.execute(sql, data)
        self.db.commit()
        cur.close()
        self.disconnect()

    def select_all(self):
        self.connect()
        cur = self.db.cursor(MySQLdb.cursors.DictCursor)
        sql = "select eng, kor, lev from voca order by eng asc"
        cur.execute(sql)
        rows = cur.fetchall()
        cur.close()
        self.disconnect()
        return rows
    
    def search_all(self, eng):
        self.connect()
        cur = self.db.cursor(MySQLdb.cursors.DictCursor)
        # sql = "select eng, kor, lev from voca where eng like '%%s%'" -> 이상하도다. concat으로 연결 %%두개는 %하나로 실행
        sql = "select eng, kor, lev from voca where eng like concat('%%', %s, '%%')"
        cur.execute(sql, (eng,))        
        rows = cur.fetchall()
        cur.close()
        self.disconnect()
        return rows
    
    def search(self, eng):
        self.connect()
        cur = self.db.cursor(MySQLdb.cursors.DictCursor)
        sql = "select eng, kor, lev from voca where eng=%s"
        cur.execute(sql, (eng,))
        row = cur.fetchone()
        cur.close()
        self.disconnect()
        return row
    
    def update(self, word):
        self.connect()
        cur = self.db.cursor()
        sql = "update voca set kor=%s, lev=%s where eng=%s"
        data = (word.kor, word.lev, word.eng)
        result = cur.execute(sql, data)
        self.db.commit()
        cur.close()
        self.disconnect()
        return result
    
    def delete(self, eng):
        self.connect()
        cur = self.db.cursor()
        sql = "delete from voca where eng=%s"
        result = cur.execute(sql, (eng,))
        self.db.commit()
        cur.close()
        self.disconnect()
        return result
# 실질적으로 작동하는 알고리즘
class WordsService:
    def __init__(self):
        self.dao = WordsDAO()

    def insert_word(self):
        eng = input("단어를 입력하세요: ")
        kor = input("뜻을 입력하세요: ")
        lev = input("레벨을 입력하세요: ")

        word = Word(eng, kor, lev)
        self.dao.insert(word)
        print("단어가 등록되었습니다")

    def print_all(self):
        words = self.dao.select_all()
        if not words:
            print("등록된 단어가 없습니다")
            return
        for word in words:
            print(f"{word['eng']} 뜻:{word['kor']}, 레벨:{word['lev']}")

    def search_words(self):
        eng = input("검색할 단어를 입력하세요: ")
        words = self.dao.search_all(eng)
        if not words:
            print("찾는 단어가 없습니다")
            return
        for word in words:
            print(f"{word['eng']} 뜻:{word['kor']}, 레벨:{word['lev']}")

    def edit_word(self):
        eng = input("수정할 단어를 입력하세요: ")
        word = self.dao.search(eng)
        if not word:
            print("수정할 단어가 없습니다")
            return
        kor = input("새로운 뜻을 입력하세요: ")
        lev = input("새로운 레벨을 입력하세요: ")
        word = Word(eng, kor, lev)
        result = self.dao.update(word)
        if result > 0:
            print("수정되었습니다")
        else:
            print("수정에 실패했습니다")

    def delete_word(self):
        eng = input("삭제할 단어를 입력하세요: ")
        word = self.dao.search(eng)
        if not word:
            print("삭제할 단어가 없습니다")
            return
        result = self.dao.delete(eng)
        if result > 0:
            print("삭제되었습니다")
        else:
            print('삭제에 실패했습니다')
class Menu:
    def __init__(self):
        self.service = WordsService()

    def run(self):
        while True:
            try:
                print()
                print("===== 단어장 프로그램 =====")
                print("1. 등록하기")
                print("2. 출력하기")
                print("3. 검색하기")
                print("4. 수정하기")
                print("5. 삭제하기")
                print("6. 종료하기")
                menu = int(input("메뉴를 선택하세요"))

                if menu ==  1:
                    print("단어를 등록합니다")
                    self.service.insert_word()

                elif menu == 2:
                    print("단어를 출력합니다")
                    self.service.print_all()
                    
                elif menu == 3:
                    print("단어를 검색합니다")
                    self.service.search_words()

                elif menu == 4:
                    print("단어를 수정합니다")
                    self.service.edit_word()

                elif menu == 5:
                    print("단어를 삭제합니다")
                    self.service.delete_word()

                elif menu == 6:
                    print("프로그램을 종료합니다")
                    break
                
                else:
                    print("메뉴는 1부터 6까지 입력해주세요")
            except Exception as e:
                print("오류: ", e)
                print("다시 입력하세요")
menu = Menu()
menu.run()

# class Word

 

# class WordsDAO

 

# class WordsService

 

# class Menu

 

# 1. 등록하기

1. Menu에서 self.service.insert_word() 만들기

2. WordsService에서 insert_word()만들고 안에서 insert()

3. WordsDAO에 insert() 만들기

4. WordService에서 마저 작성

 

# 2. 출력하기
1. Menu에서 self.service.print_all() 만들기
2. WordsService에서 print_all()만들고 안에서 select_all()
3. WordsDAO에 select_all() 만들기
4. WordsService에서 마저 작성

# 3. 검색하기
1. Menu에서 self.service.search_words() 만들기
2. WordsService에서 search_words()만들고 안에서 self.dao.search_all(eng)
3. WordsDAO에 search_all(eng) 만들기
4. WordsService에서 마저 작성

# 4. 수정하기
1. Menu에서 self.service.edit_word() 만들기
2. WordsService에서 edit_word()만들고 안에서 self.dao.search(eng)
3. WordsDAO에 search(eng) 만들기
4. WordsService에서 마저 작성하다가 self.dao.update(word) 만들기
5. WordsDAO에 update(word) 만들기

 

# 5. 삭제하기

1. Menu에서 self.service.delete_word()

2. WordsService에서 delete_word()만들고 안에서 self.dao.search(eng)

3. WordsDAO에 있는 search(eng) 재사용

4. WordsService에 마저 작성하다가 self.dao.delete(eng) 만들기

5. WordsDAO에 delete(eng)만들기

6. WordsService에 마저 작성

 


* 모든 코드를 한번에 작성하려고 하지 말 것

 

* 우선 코드 흐름을 파악하는 것에 집중

 

* 번호로 정리해 둔 내용을 보며 작성하는 흐름에 익숙해져보자

 

* 객체지향적인 코드를 작성해보았는데, 앞으로도 이런 코드를 사용할거라고 생각하니 걱정이 된다. 복습을 꼼꼼히 해야할 필요가 있다.

'KDT > 3. Python과 MySQL 연동' 카테고리의 다른 글

[14일차-2] MySQL 연동  (1) 2026.06.09