1.  패키지

🚀  패키지는 클래스와 소스 파일을 관리하기 위한 디렉토리 구조의 저장 공간
      ✓ 현재 클래스가 어떤 패키지(디렉토리)에 있는지 표시
      ✓ 디렉토리가 계층 구조로 만들어져 있으면 점(.)으로 구분해서 각 디렉토리를 모두 나열해 줌

package 메인 디렉토리. 서브 디렉토리
class 클래스 {
}


🚀  이 디렉토리 구조라면 윈도우의 파일 탐색에서 보면 메인 디렉토리 아래에 서브 디렉토리가 있고, 서브 디렉토리 안에 실제 코드가 있는 클래스.kt 파일이 있음

🚀  하나의 패키지에 여러 개의 파일을 생성할 수 있기 때문에 '서로 관계가 있는 파일을 동일한 패키지로 만들어 두면 관리가 용이

 


2.  추상화

🚀  프로그래밍을 하기 전 개념 설계를 하는 단계에서는 클래스의 이름과 클래스 안에 있음 직한 기능을 유추해서 메서드 이름으로 먼저 나열. 이때 명확한 코드는 설계 단계에서 메서드 블록 안에 직접 코드를 작성하는데, 그렇지 않은 경우에는 구현 단계에서 코드를 작성하도록
메서드의 이름만 작성  ▶️ 이것을 추상화 Abstract 라고 하며 abstract 키워드를 사용해서 명시

 

  ✓ 구현 단계에서는 이 추상화된 클래스를 상속받아서 아직 구현되지 않은 부분을 마저 구현
  ✓ 다음과 같이 추상화된 Aniamal 클래스를 만들고 동물이 사용할 것 같은 기능 중 walk()와 move()를 설계한다고 가정

abstract class Animal {
    fun walk() {
        println("Walking")
    }

    abstract fun move()
}

 

  👾 walk는 명확하게 걸어가는 행위이지만 move는 어떤 동물이냐에 따라서 달라진다고 가정
  👾 이렇게 앞으로 상속받을 자식 클래스의 특징에 따라 코드가 결정될 가능성이 있다면 해당 기능도 abstract 키워드로 추상화
        ➡️  실제 구현 클래스는 이 추상 클래스를 상속받아서 아직 구현되지 않은 추상화되어 있는 기능을 모두 구현해 줌
  👾 추상 클래스는 독립적으로 인스턴스화 할 수 없기 때문에 구현 단계가 고려되지 않는다면 잘못된 설계가 될 수 있음

class Bird : Animal() {
    override fun move() {
        println("Bird move")
    }
}

 


3.  인터페이스

🚀 인터페이스 interface는 실행코드 없이 메서드 이름만 가진 추상 클래스. 즉, 누군가 설계해 놓은 개념 클래스 중에 실행 코드가 한 줄이라도 있으면 추상 클래스, 코드 없이 메서드 이름만 나열되어 있으면 인터페이스

🚀 인터페이스는 안드로이드에서는 주로 상속 관계의 설계보다는 외부 모듈에서 내가 만든 모듈을 사용할 수 있도록 메서드의 이름을 나열해둔 일종의 명세서로 제공

🚀 인터페이스는 interface 예약어를 사용해서 정의할 수 있고 인터페이스에 정의된 메서드를 오버라이드해서 구현할 수 있음
    ✓  코틀린은 프로퍼티도 인터페이스 내부에 정의할 수 있고, 추상 클래스와 다르게 class 키워드는 사용되지 않음

interface 인터페이스명 {
    var 변수 : String
    fun 메서드1()
    fun 메서드2()
}

 

 

1) 인터페이스 만들기

 

interface 예약어로 인터페이스를 정의
코틀린은 인터페이스 내부에 프로퍼티도 정의할 수 있음

interface InterfaceKotlin {
    var variable: String
    fun get()
    fun set()
}

 

 

2) 클래스에서 구현하기


인터페이스를 클래스에서 구현할 때는 상속과는 다르게 생성자를 호출하지 않고 인터페이스 이름만 지정해 주면 됨

class KotlinImpl : InterfaceKotlin {
    override var variable: String = "Default"
    override fun get() {

    }
    override fun set() {

    }
}

 

💡  인터페이스를 코틀린의 상속 형태가 아닌 소스 코드에서 직접 구현할 때도 있는데, object 키워드를 사용해서 구현해야 함
       ➡️  안드로이드 프로젝트에서 자주 사용하는 형태

val kotlinImpl = object : InterfaceKotlin {
    override var variable: String = "Default"

    override fun get() {

    }

    override fun set() {

    }
}

 

 

 

[ 내용 참고 : IT 학원 강의 ]


 

1.  format() 함수

 

👩🏻‍💻  숫자를 문자열로 변환하는 함수로 중괄호{}를 포함한 문자열 뒤에 마침표(.)를 찍고 format() 함수를 사용

       ▶️  중괄호 개수와 format() 함수 괄호 안 매개변수의 개수는 반드시 같아야 함

"{}".format(10)
"{} {}".format(10,20)

 

   📌 위의 구문과 같이 앞쪽에 있는 문자열 {} 기호가 format() 함수 괄호 안에 있는 매개 변수로 차례로 대치되면서 숫자가 문자열로 되는 것

 

zipcode = '06236'
print('우편번호 : {}'.format(zipcode)) # format() 메서드를 이용해 출력
# 결과) 우편번호 : 06236

zipcode_str = '우편번호 : {}'.format(zipcode)
print(zipcode_str)
# 결과) 우편번호 : 06236

address = '''서울특별시 강남구
테헤란로 146''' # multi line
print('주소 : {addr}'.format(addr=address))  # format() 메서드의 변수 이용
# 결과) 주소 : 서울특별시 강남구
# 테헤란로 146

 

  📌  {} 기호의 개수가 format() 함수의 매개변수 개수보다 많으면 IndexError 예외가 발생

 


2.  format() 함수의 다양한 기능

 

1) 정수 출력의 다양한 형태

# 정수를 특정 칸에 출력하기

# 정수
num_a = "{:d}".format(52)

# 특정 칸에 출력하기
num_b = "{:5d}".format(52)  # 5칸
num_c = "{:10d}".format(52) # 10칸

# 빈칸을 0으로 채우기
num_d = "{:05d}".format(52)  # 양수
num_e = "{:05d}".format(-52) # 음수

print('# 기본')
print(num_a)
print('# 특정 칸에 출력하기')
print(num_b)
print(num_c)
print('# 빈칸을 0으로 채우기')
print(num_d)
print(num_e)

 

실행결과

 

📌  {:d}는 int 자료형의 정수를 출력하겠다고 직접적으로 지정하는 것

       ➡️ 매개변수로 정수만 올 수 있다.

📌  {:5d}는 5칸을 빈칸으로 잡고 뒤에서부터 52라는 숫자를 채운다.

📌  {:05d}는 5칸을 잡고 뒤에서부터 52라는 숫자를 넣은 후 앞의 빈곳을 0으로 채운다.

       ➡️ 부호가 있을 때는 맨 앞자리를 부호로 채우고 나머지 빈 곳을 0으로 채움

 

 


# 기호와 함께 출력하기
num_a = "{:+d}".format(33)  # 양수
num_b = "{:+d}".format(-33) # 음수
num_c = "{: d}".format(33) # 양수: 기호 부분 공백
num_d = "{: d}".format(-33)# 음수: 기호 부분 공백

print("# 기호와 함께 출력하기")
print(num_a)
print(num_b)
print(num_c)
print(num_d)

 

 

📌  {:+d} 와 같이 d앞에 +기호를 붙이면 양수와 음수 기호를 표현할 수 있다.

📌  {: d} 처럼 앞에 공백을 두어 기호 위치를 비워주면 함수에 입력한 기호가 표현된다.

 

 

 

 

# < : 지정된 공간 내에서 왼쪽 정렬
# > : 지정된 공간 내에서 오른쪽 정렬
# ^ : 지정된 공간 내에서 가운데 정렬

# 10d는 10자리의 필드 폭을 의미
print("10자리 폭 왼 쪽 정렬 '{:<10d}'".format(123))  
# 10자리 폭 왼 쪽 정렬 '123       '

print("10자리 폭 오른 쪽 정렬 '{:>10d}'".format(123))  
# 10자리 폭 오른 쪽 정렬 '       123'

print("10자리 폭 가운데 정렬 '{:^10d}'".format(123))  
# 10자리 폭 가운데 정렬 '   123    '
print()

# 채움문자를 지정하면 공백 대신 채움문자가 빈자리를 채움
print("10자리 폭 왼 쪽 정렬 채움문자 '{:*<10d}'".format(123))  
# 10자리 폭 왼 쪽 정렬 채움문자 '123*******'
print("10자리 폭 오른 쪽 정렬 채움문자 '{:*>10d}'".format(123))  
# 10자리 폭 오른 쪽 정렬 채움문자 '*******123'
print("10자리 폭 가운데 쪽 정렬 채움문자 '{:*^10d}'".format(123))  
# 10자리 폭 가운데 쪽 정렬 채움문자 '***123****'

 

 


 

# 조합하기
num_a = "{:+5d}".format(33)  # 기호를 뒤로 밀기: 양수
num_b = "{:+5d}".format(-33) # 기호를 뒤로 밀기: 음수
num_c = "{:=+5d}".format(33) # 기호를 앞으로 밀기: 양수
num_d = "{:=+5d}".format(-33) # 기호를 앞으로 밀기: 음수
num_e = "{:+05d}".format(33)  # 0으로 채우기: 양수
num_f = "{:+05d}".format(-33) # 0으로 채우기: 음수

print("# 조합하기")
print(num_a)
print(num_b)
print(num_c)
print(num_d)
print(num_e)
print(num_f)

 

 

 

📌  기호와 공백을 조합할 때 '=' 기호를 앞에 붙일 수 있다.

        ➡️ 5칸의 공간을 잡았을 때 기호를 빈칸 앞에 붙일 것인지, 숫자 앞에 붙일 것인지 지정

 

 

 

 

 

 

 


# 부동 소수점 출력의 다양한 형태
num_a = "{:f}".format(12.345)
num_b = "{:15f}".format(12.345)   # 15칸 만들기
num_c = "{:+15f}".format(12.345)  # 15칸에 부호 추가하기
num_d = "{:+015f}".format(12.345) # 15칸에 부호 추가하고 0으로 채우기

print(num_a)
print(num_b)
print(num_c)
print(num_d)

 

실행 결과

 

# 소수점 아래 자릿수 지정하기
num_a = "{:15.3f}".format(12.345)
num_b = "{:15.2f}".format(12.345)
num_c = "{:15.1f}".format(12.345)

print(num_a)
print(num_b)
print(num_c)

실행 결과

 

📌  15칸을 잡고 소수점을 각각 3자리, 2자리, 1자리로 출력

        ➡️  자동으로 반올림도 일어남

 

 

 


# 의미없는 소수점 제거
num_a = 33.0
num_b = "{:g}".format(num_a)

print(num_a)
print(num_b)

실행 결과

 


3. f-문자열

👩🏻‍💻  formatted strings ; 파이썬 3.6이후 버전에서 사용 가능

👩🏻‍💻  문자열 앞에 'f'를 붙여서 만드는데, 문자열 내부에 표현식을 {} 괄호로 감싸서 삽입할 수 있다.

 

f'문자열{표현식}문자열'

 

who = 'you'
how = 'happy'
print(f'{who} make me {how}') # you make me happy / 문자열에 f 또는 F라는 접두어 prefix를 붙임

age = 25
print(f'내년엔 {age + 1}살이 됩니다.')  # 내년엔 26살이 됩니다.

 

  📌  format() 함수보다 간단하고 직관적이라 대부분 f-문자열을 사용하는 편

 

 

💡 format() 함수를 사용하는 것이 더 좋은 경우

 

   a)  문자열 내용이 너무 많을 때

      - f-문자열을 사용하면 어떤 데이터를 삽입하여 출력하는지 확인하기 위해 문자열을 모두 읽어야 하는 문제가 있다.

   b)  데이터를 리스트에 담아서 사용할 때

     - 리스트를 f-문자열로 형식화해서 출력하려면 [] 기호로 일일이 리스트 요소에 접근해야 하지만,

        format() 함수와 전개 연산자를 사용하면 더 간단하게 입력하여 리스트 요소를 한꺼번에 출력 가능

 

data = ['별', 2, 'M', '서울특별시 강서구', 'Y']
f"""이름: {data[0]}
나이: {data[1]}
성별: {data[2]}
지역: {data[3]}
중성화 여부: {data[4]}"""

"""이름: {}
나이: {}
성별: {}
지역: {}
중성화 여부: {}""".format(*data)

'''
실행결과)
이름: 별
나이: 2
성별: M
지역: 서울특별시 강서구
중성화 여부: Y
'''

 


4. 문자열의 구성 파악하기: isOO()

 

👩🏻‍💻  문자열이 소문자로만 구성되어 있는지, 알파벳으로만 구성되어 있는지, 숫자로만 구성되어 있는지 등을 확인할 때 사용

isalnum() 문자열이 알파벳 또는 숫자로만 구성되어 있는지 확인
isalpha() 문자열이 알파벳으로만 구성되어 있는지 확인
isidentifier() 문자열이 식별자로 사용할 수 있는지 확인
isdecimal() 문자열이 정수 형태인지 확인
isdigit() 문자열이 숫자로 인식될 수 있는 것인지 확인
isspace() 문자열이 공백으로만 구성되어 있는지 확인
islower() 문자열이 소문자로만 구성되어 있는지 확인
isupper() 문자열이 대문자로만 구성되어 있는지 확인

 

print("Python1".isalnum())
# 실행결과) True

print("33".isdigit())
# 실행결과) True

 

 

 


 

5.  문자열과 'in 연산자'

👩🏻‍💻  문자열 내부에 어떤 문자열이 있는지 확인할 때 'in 연산자' 사용

👩🏻‍💻  리턴 값은 boolean 형 (True / False)

 

print("영희" in "내 이름은 영희입니다.")  # True
print("안녕" in "내 이름은 영희입니다.")  # False

 

 

 

 

 

[ 내용 참고 : 책 '혼자 공부하는 파이썬' 및 IT 학원 강의 자료 ]

 


 

1.  자료형과 기본 자료형

 

1) 자료형 data type ; 자료의 형식

 

  👩🏻‍💻  type() 함수로 자료의 형식을 확인

print(type('안녕하세요') # 결과 : <class 'str'>
print(type(100))  # 결과 : <class 'int'>
print(type(3.14)) # 결과 : <class 'float'>
print(type(True)) # 결과 : <class 'bool'>

 

  📌  파이썬의 기본 데이터 타입 4가지 :  정수, 실수, 불, 문자열
  📌  파이썬의 컬렉션 데이터 타입 4가지 :  list, tuple, set, dict

 


 

2) 문자열  String

 

  👩🏻‍💻  글자들이 나열된 것을 '문자열 (String)' 이라고 함

  👩🏻‍💻  문자열 만들 때 큰 따옴표("") 나 작은 따옴표('') 사용

 

     💡  문자열 내부에 따옴표 넣기

print(""안녕하세요"라고 말했다.")

# 결과) SyntaxError: invalid syntax

 

    ⚡️  파이썬 프로그래밍 언어는 자료(문자열)와 자료(문자열)를 단순하게 나열할 수 x

    ⚡️  위의 구문에서 문자열로 인식하는 부분은  [ ""        "라고 말했다." ]

    ⚡️  큰 따옴표를 내부에 넣고 싶으면 작은 따옴표로 문자열을 만들면 됨

           ▶️ 반대로 작은 따옴표를 문자열 내부에 넣고 싶으면 큰 따옴표로 문자열을 만들면 됨

print('"안녕하세요"라고 말했다.')
# 결과 : "안녕하세요"라고 말했다.

 

   


 

① 이스케이프 문자 escape character

 

  -  역슬래시( \ ) 기호와 함께 조합해서 사용하는 특수한 문자를 의미

  · \"   :  큰 따옴표
  · \'    :  작은 따옴표
  · \n   :  줄바꿈
  · \t    :  탭 (띄어쓰기)
  · \\    :  역슬래시(\)를 의미

 

print('Hello \'World\'')
print('*\n**\n***') 
print('이름\t연락처')

''' 
실행결과
Hello 'World'
*
**
***
이름	연락처
'''

 


 

②  여러 줄 문자열

 

  -  삼중 큰 따옴표(""") 및 작은 따옴표(''')사용하면 여러 줄 문자열 기능 지원

      ▶️  주석도 가능

address = '''우편번호 12345
서울시 영등포구 여의도동
서울빌딩 501호'''

print(address)
# 결과
# (공백)
# 우편번호 12345
# 서울시 영등포구 여의도동
# 서울빌딩 501호
# (공백)

 


 

③  줄바꿈 없이 문자열 만들기

 

  - 역슬래시 ( \ ) 사용하면 의도하지 않은 줄바꿈이 들어가지 않게끔 한다.

address = '''\
우편번호 12345
서울시 영등포구 여의도동
서울빌딩 501호\
''' 
print(address)
# 결과
# 우편번호 12345
# 서울시 영등포구 여의도동
# 서울빌딩 501호
# -> 위 아래로 공백 구간이 생기지 않음

 

 


3) 문자열 연산자

 

# 시퀀스 연산자 : 순서가 있는 시퀀스(리스트, 튜플, range, 문자열 등)에서 사용할 수 있는 연산자
# + : 연결하기
# * : 반복하기

tree = '#'
space = ' '
print(space * 4 + tree * 1) #    #
print(space * 3 + tree * 3) #   ###
print(space * 2 + tree * 5) #  #####
print(space * 1 + tree * 7) # #######
print(space * 0 + tree * 9) ##########
print('-' * 20) # --------------------

 

 

💡 문자열 연결 연산자 : +


 "문자열" + "문자열"

   -  두 문자열을 연결해서 새로운 문자열을 만들어 냄

print('안녕' + '하세요')
# 결과 ) 안녕하세요

 

   📌  문자열은 무조건 문자열끼리 + 연산자를 사용해서 연결해야함

   📌  숫자를 연결하고 싶다면 큰따옴표나 작은따옴표를 붙여 문자열로 인식시켜야 함

print('안녕하세요' + '1')
# 결과: 안녕하세요1

 

 


 

💡  문자열 반복 연산자: *

 

    - 문자열을 숫자와 * 연산자로 연결하면 숫자만큼 문자열을 반복할 수 있다.

print('반가워요' * 3)
print(3 * '반가워요')
# 결과 : 반가워요반가워요반가워요

 


 

💡 문자 선택 연산자(인덱싱): []

 

    - 문자열 내부의 문자 하나를 선택하는 연산자

    - 대괄호 [] 안에 선택할 문자의 위치를 지정하며, 이 숫자를 인덱스 index라고 부른다.

    - 파이썬은 제로 인덱스 유형을 사용  ▶️ 숫자를 0부터 세는 인덱스 

 

h e l l o
[0] [1] [2] [3] [4]
[-5] [-4] [-3] [-2] [-1]

 

s = 'hello'
print(s[1]) # e
# 마이너스(-) 인덱스는 문자열 뒤에서 부터 부여, 마지막 인덱스는 -1이 됨
print(s[1] == s[-4]) # True

 


 

💡  문자열 범위 선택 연산자(슬라이싱): [ : ]

 

    -  문자열의 특정 범위를 선택할 때 사용

        ex.  문자열에서 첫 번째 문자부터 세 번째 문자까지 선택 (범위 지정)

    -  범위는 대괄호 안에 위치를 콜론(:)으로 구분해서 지정

    - 파이썬은 범위 지정시 마지막 숫자를 포함하지 않는다.

# s[start:stop:step]
# start : 시작 인덱스를 지정. 생락하면 처음부터 추출
# stop :  종료 인덱스를 지정. 생략하면 끝까지 추출
# step : 인덱스의 증감값, 생략하면 1씩 변화
print()
s = 'banana'
print(s[0:3])  # ban / 종료 인덱스는 포함하지 않음
print(s[0:6:2])  # bnn
print(s[:6:2])  # bnn
print(s[::])  # banana
print(s[2::2])  # nn

 

 


 

💡  IndexError(index out of range) 예외

 

    - 발생 이유 : 리스트/문자열의 수를 넘는 요소/글자를 선택할 때 발생

        ex. '안녕하세요'[10]  ▶️  다섯 글자인데 10번째 문자에 접근  ▶️  IndexError

 


 

4) 문자열 길이 구하기

 

👩🏻‍💻 len() 함수를 사용하여 문자열의 길이를 구함

 

print(len('안녕하세요'))
# 결과: 5

 

 

 

 

 

[ 내용 참고 : IT학원 강의 및 책 '혼자 공부하는 파이썬' ]


 

 

1.  파이썬 용어

 

1) 문장  statement

 

  ·  실행할 수 있는 코드의 최소 단위

  ·  문장들이 모여 프로그램 program 이 된다.

# 실행되는 모든 한 줄 코드는 문장
print('Hello World!!')
10 + 20

 


2) 표현식 expression

 

  · 어떠한 값을 만들어 내는 간단한 코드

     ex.  숫자, 수식, 문자열

 

2024
10 + 20 + 30
"Hello Python!!"

 


 

3) 키워드 keyword

 

  ·  특별한 의미가 부여된 단어로 파이썬이 만들어질 때 이미 사용하겠다고 예약해 놓은 것

  ·  이름을 정할 때 키워드를 사용하면 안 된다.

  ·  파이썬은 대소문자를 구분

       ex.  True는 키워드지만 true는 키워드 x

 

# 키워드인지 확인하는 방법
import keyword
print(keyword.kwlist)

 


 

4) 식별자 identifier

 

  ·  이름을 붙일 때 사용하는 단어, 주로 변수 또는 함수 이름 등으로 사용

     

     📌  규칙

        a. 키워드를 사용 x

        b. 특수 문자는 언더 바(_)만 허용

        c. 숫자로 시작 x

        d. 공백 포함 x

 

  👾  공백 사용 대신 쓰이는 방법

      - 스네이크 케이스 : 단어 사이에 언더 바(_) 기호를 붙여 식별자를 만든다

      - 캐멀 케이스 : 단어들의 첫 글자를 대문자로 만들어 식별자를 만든다

    

  👾  식별자 구분하기

      - 파이썬에서는 첫 번째 글자를 소문자로 적는 캐멀 케이스는 사용 x

      - 캐멀 케이스 ➡️ 클래스 ➡️  뒤에 괄호가 있으면 클래스 생성자

      - 스네이크 케이스 ➡️  함수 또는 변수 ➡️ 뒤에 괄호가 붙어 있으면 함수, 없으면 변수

 


5) 주석 comment

 

  ·  프로그램의 진행에 전혀 영향을 주지 않는 코드

  ·  파이썬은 '#' 기호를 붙여 주석 처리

print('Hello World!!') 
# 문자열을 작은 따옴표나 큰 따옴표 둘 중 택1 붙여서 사용 가능, 세미콜론 안 붙여도 됨

 


 

6) 연산자와 자료

 

  · 연산자는 값과 값 사이에 무언가 기능을 적용할 때 사용하는 것을 말함

        ex. +, -

  ·  리터럴(literal) = 자료 :  숫자이든 문자이든 어떠한 '값' 자체를 의미

 


7) 출력: print()

 

  · 파이썬의 기본적인 출력 방법

print(출력1, 출력2, ... )

 

  ⚡️  여러 개 출력시 내용을 쉼표로 연결해서 여러개 적으면 된다.

print("안녕하세요", "저의", "이름은", "홍길동입니다!") 
# 결과 : 안녕하세요 저의 이름은 홍길동입니다!)

 

 

  ⚡️ print() 함수 괄호 안에 아무것도 입력하지 않으면 단순하게 줄바꿈을 한다.

print("# 아무것도 출력하지 않습니다.")
print("--- 확인 전용선 ---")
print()
print()
print("--- 확인 전용선 ---")
''' 실행결과 )
# 아무것도 출력하지 않습니다.
--- 확인 전용선 ---


--- 확인 전용선 ---
'''

 

 

 

 

[ 내용 참고 : 책 '혼자공부하는파이썬' 및 IT 학원 강의 ]

 


 

 

1. 조인 Join

 

👾 두 개 이상의 테이블을 서로 묶어서 하나의 결과 집합으로 만들어내는 것

 ⚡️ 데이터베이스 테이블은 중복과 공간 낭비를 피하고 데이터 무결성을 위해 여러 개 테이블로 분리해 저장

 ⚡️ 분리된 테이블은 서로 관계 Relation 를 맺고 있는데, 가장 많이 사용하는 관계는 '1대 다' 관계

     ex. 학생 한 명이 여러 과목의 학점을 받는 것, 한 개의 아이디로 여러 상품을 주문하는 것

 


 

1) INNER JOIN (내부 조인)

 

 SELECT <열 목록>
 FROM <첫 번째 테이블>
      INNER JOIN <두 번째 테이블>
      ON <조인될 조건>
 [WHERE 검색조건]
 

 

· 첫 번째 테이블은 구매테이블(buytbl), 두 번째 테이블은 회원테이블(usertbl)

 

 SELECT * FROM buytbl
      INNER JOIN usertbl
         ON buytbl.userID = usertbl.userID
      WHERE buytbl.userID = 'JYP';
 
실행 결과

  📌  추출 과정

     1.  구매 테이블의 userID인 'JYP'를 추출한다.

     2.  'JYP'와 동일한 값을 회원 테이블의 userID열에서 검색한 후 찾으면 구매 테이블과 회원 테이블의 두 행을 결합

 

  📌 WHERE 절을 생략하면 buytbl 테이블의 모든 행에 대해서 위와 동일한 방식으로 추출

WHERE절을 생략한 결과

 

 


 

👾 필요한 열만 추출하는 방법

 SELECT userID, name, prodName, addr, CONCAT(mobile1, mobile2) AS '연락처'
    FROM buytbl
      INNER JOIN usertbl
         ON buytbl.userID = usertbl.userID
      ORDER BY num;
 

  📌 위의 구문을 실행하면 다음과 같은 에러 코드가 뜬다.

Error Code: 1052. Column 'userID' in field list is ambiguous
 

  💡 userID의 경우 두 테이블 모두에 들어 있어 어느 테이블의 userID 추출할 지 명시해줘야 함

 SELECT buytbl.userID, name, prodName, addr, CONCAT(mobile1, mobile2) AS '연락처'
    FROM buytbl
      INNER JOIN usertbl
         ON buytbl.userID = usertbl.userID
      ORDER BY num;
 
결과

 

 

👾 코드가 길어지면 복잡해 보이기 때문에 각 테이블에 '별칭 Alias' 을 부여하는 방법

 SELECT B.userID, U.name, B.prodName, U.addr, CONCAT(U.mobile1, U.mobile2) AS '연락처'
    FROM buytbl B
      INNER JOIN usertbl U
         ON B.userID = U.userID
      WHERE B.userID = 'JYP';
 

  📌 위와 같이 FROM 절에 나오는 테이블의 이름 뒤에 별칭을 붙여주면 된다.

결과

 

 

 

👾 세 개의 테이블을 조인하는 방법

· 첫 번째 stdTbl(학생테이블) / 두 번째 stdclubTbl / 세 번째 clubTbl

 

-- 학생 테이블, 동아리 테이블, 학생동아리 테이블을 이용해서 학생을 기준으로 학생 이름/지역/가입한 동아리/동아리방을 출력
SELECT S.stdName, S.addr, C.clubName, C.roomNo
  FROM stdTbl S
     INNER JOIN stdclubTbl SC
        ON S.stdName = SC.stdName
     INNER JOIN clubTbl C
        ON SC.clubName = C.clubName
  ORDER BY S.stdName; 
 
결과

 

 

 

2) OUTER JOIN (외부 조인)

 

 

👾 주종관계에 있는 테이블에서 주테이블의 모든 레코드를 보여주고 조건을 만족하는 부테이블의 필드를 같이 출력

 SELECT <열 목록>
 FROM <첫 번째 테이블(LEFT 테이블)>
  <LEFT|RIGHT|FULL> OUTER JOIN <두 번째 테이블 (RIGHT 테이블)>
       ON <조인될 조건>
 [WHERE 검색조건];
 

 

  📌 전체 회원의 구매기록 구하기 (단, 구매 기록 없는 회원도 출력)

 SELECT U.userID, U.name, B.prodName, U.addr, CONCAT(U.mobile1, U.mobile2) AS '연락처'
    FROM usertbl U
      LEFT OUTER JOIN buytbl B     -- LEFT OUTER JOIN은 왼쪽 테이블(usertbl)의 것은 모두 출력되어야 한다는 뜻
         ON U.userID = B.userID
    ORDER BY U.userID;
 
결과

 

 

📌 RIGHT OUTER JOIN을 사용해서 동일한 결과 값을 얻으려면 단순히 왼쪽과 오른쪽 테이블 위치만 바꿔주면 됨

 

 

 

💡  FULL OUTER JOIN (전체 조인) : LEFT JOIN + RIGHT JOIN

      ➡️  왼쪽 테이블과 오른쪽 테이블의 모든 행을 반환. 조인 조건에 맞는 데이터가 없는 경우, 해당 테이블의 열에는 NULL 값이 채워짐

 

 

 

3) CROSS JOIN (상호 조인)

 

 

👾 한쪽 테이블의 모든 행들과 다른 쪽 테이블의 모든 행을 조인시키는 기능

➡️ 결과 개수는 두 테이블의 개수를 곱한 개수

👾 카티션 곱 Cartesian Product이라고도 부른다.

👾 ON 구문 사용 x, 용도는 테스트로 사용할 많은 용량의 데이터를 생성할 때 주로 사용

 

 

  📌 회원 테이블과 구매 테이블의 CROSS JOIN 구문

 SELECT COUNT(*) AS '데이터 개수' FROM buytbl CROSS JOIN usertbl;
 
결과

 

 

 

4) SELF JOIN (자체 조인)

 

 

👾 자기 자신과 자기 자신이 조인한다는 의미

👾 대표적인 예가 조직도와 관련된 테이블

 

empTbl

 

 -- 우대리 상관의 연락처를 확인
 SELECT A.emp AS '부하직원' , B.emp AS '직속상관', B.empTel AS '직속상관연락처'
   FROM empTbl A
      INNER JOIN empTbl B
         ON A.manager = B.emp
   WHERE A.emp = '우대리';
 
결과

 

 

 

 

 

 

[ 내용 참고 : 책 '이것이 MySQL'이다 ]

 

 


 

 

1. DB 연결

 

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class connection {

 public static void main(String[] args) {
    -- try 블럭 안에 넣으면 finally 구문에서 연결끊기가 실행 안됨.
	Connection conn = null; 
	try {
		-- JDBC Driver를 메모리로 로딩하고, DriverManager에 등록
		Class.forName("com.mysql.cj.jdbc.Driver");
		    
		-- 연결하기
		conn = DriverManager.getConnection(
		    	"jdbc:mysql://localhost:3306/sample",
		    	"(아이디)",
		    	"(비밀번호)"
		       );
		    		
		    System.out.println("연결 성공");
		    	    
	} catch (ClassNotFoundException e) {
			e.printStackTrace(); -- 예외 종류, 발생 이유, 어디서 발생했는지 추적한 내용까지 출력
	} catch (SQLException e) {
			e.printStackTrace();
	} finally {
		 if (conn != null) { -- null 이면 굳이 닫을 필요 없기 때문.
			try {
				/* 연결 끊기 (try 구문 안에 넣으면 예외 발생시 실행이 안되기 때문에 
                finally 구문에서 무조건 실행되도록 함.) */
				conn.close();
				System.out.println("연결 끊기");
			} catch (SQLException e) {}
		}
	}
 }
}
 

 


 

2.  INSERT

 

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class UserInsert {

   public static void main(String[] args) {
	 Connection conn = null;
	 try {
		  Class.forName("com.mysql.cj.jdbc.Driver");
		    
		  conn = DriverManager.getConnection(
		    	 "jdbc:mysql://localhost:3306/sample",
		    	 "(아이디)",
		    	 "(비밀번호)"
		    	 );
		    		
		  System.out.println("연결 성공");
		    
		  -- 매개변수화된 SQL문 작성
		  String sql = "" + "INSERT INTO users (
                       userid, username, userpassword, userage, useremail) " +
		    		   "VALUES (?,?,?,?,?)"; // 매개변수에 들어갈 값을 물음표로 표현해준다.
		    		
		   -- PreparedStatement 얻기 및 값 지정
		   PreparedStatement pstmt = conn.prepareStatement(sql); 
		   -- 연결 객체를 통해 sql문을 실행해서 결과문을 받을 statement를 준비하고,
	       -- 구현객체가 리턴되어 PreparedStatement 인터페이스 변수에 대입된다. 
              (아직 실행된 상태는 아니다.)
		    
		   pstmt.setString(1,  "winter"); 
		   pstmt.setString(2, "한겨울");
		   pstmt.setString(3, "12345");
		   pstmt.setInt(4, 25);
		   pstmt.setString(5, "winter@mycompany.com");
		    
		   -- SQL문 실행
		   int rows = pstmt.executeUpdate(); -- DB에서 insert문을 실행하는 메소드
		   System.out.println("저장된 행 수: " + rows); -- DB에 반영된 행의 수를 뜻함.
		   -- 정상적으로 실행되었다면 1이 나옴.		
		    
		   -- PreparedStatement 닫기
		   pstmt.close();
		   
	} catch (ClassNotFoundException e) {
			e.printStackTrace();
	} catch (SQLException e) {
			e.printStackTrace();
	} finally {
		if (conn != null) { 
			try {
				-- 연결 끊기 
				conn.close();
				System.out.println("연결 끊기");
			} catch (SQLException e) {}
		}
	}

 } 
}
 

 


 

3. UPDATE

 

import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;

public class BoardUpdate {

	public static void main(String[] args) {
		Connection conn = null;
		try {
		    Class.forName("com.mysql.cj.jdbc.Driver");
		    
		    conn = DriverManager.getConnection(
		    		"jdbc:mysql://localhost:3306/sample",
		    		"(아이디)",
		    		"(비밀번호)"
		    		);
		    		
		    -- 매개변수화된 SQL문 작성
		    String sql = new StringBuilder() -- 문자열 연결 메서드
                   .append("UPDATE boards SET ")
                   .append("btitle=?, ")
                   .append("bcontent=?, ")
                   .append("bfilename=?, ")
                   .append("bfiledata=? ")
                   .append("WHERE bno=?")
                   .toString();
		    
		    -- PreparedStatement 얻기 및 저장
		    PreparedStatement pstmt = conn.prepareStatement(sql);
		
		    pstmt.setString(1, "눈사람");
		    pstmt.setString(2, "눈으로 만든 사람");
		    pstmt.setString(3, "snowman.jpg");
		    pstmt.setBlob(4, new FileInputStream("src/DBtest/photo2.jpg"));
		    pstmt.setInt(5, 3); // boards 테이블에 있는 게시물 번호(bno) 지정
		    
		    -- SQL문 실행
		    int rows = pstmt.executeUpdate();
		    System.out.println("수정된 행 수: " + rows);
		    
		    -- PreparedStatement 닫기
		    pstmt.close();
		    
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if(conn != null) {
				try {
				-- 연결 끊기
				conn.close();
			} catch (SQLException e) {}
		}
	}
	}

}
 

 


 

4. DELETE

 

public class BoardDelete {

	public static void main(String[] args) {
		Connection conn = null;
		try {
		    Class.forName("com.mysql.cj.jdbc.Driver");
		    
		    conn = DriverManager.getConnection(
		    		"jdbc:mysql://localhost:3306/sample",
		    		"(아이디)",
		    		"(비밀번호)"
		    		);
		    		
		    -- 매개변수화된 SQL문 작성
		    String sql = "DELETE FROM boards WHERE btitle=?";
		    
		    -- PreparedStatement 얻기 및 저장
		    PreparedStatement pstmt = conn.prepareStatement(sql);
		    pstmt.setString(1, "눈사람");
		    
		    
		    -- SQL문 실행
		    int rows = pstmt.executeUpdate();
		    System.out.println("삭제된 행 수: " + rows);
		    
		    -- PreparedStatement 닫기
		    pstmt.close();
		    
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if(conn != null) {
				try {
				-- 연결 끊기
				conn.close();
			} catch (SQLException e) {}
		}
	}
	}

}
 

 


 

5.  SELECT

 

import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.DriverManager;
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 com.mysql.cj.jdbc.Blob;

public class BoardSelect {

	public static void main(String[] args) {
        Connection conn = null;
		
		try {
			-- JDBC Driver 등록
		    Class.forName("com.mysql.cj.jdbc.Driver");
		    
		    -- DB 연결
		    conn = DriverManager.getConnection(
                     "jdbc:mysql://localhost:3306/sample", 
                     "(아이디)", 
                     "(비밀번호)");
		    
		    -- 매개변수화된 SQL문 작성
		    String sql = "SELECT bno, btitle,bcontent, bwriter, 
                          bdate, bfilename, bfiledata 
                          from boards where bwriter =?";
		    
		    -- PreparedStatement 얻기 및 값 지정
		    PreparedStatement pstmt = conn.prepareStatement(sql);
		    pstmt.setString(1,"winter");
		    
		    -- SQL문 실행 후, ResultSet을 통해 데이터 읽기.
		    ResultSet rs = pstmt.executeQuery();
		    List<Board> boards = new ArrayList<>();
		    while(rs.next()) {
		    	Board board = new Board(); -- board 테이블의 행을 저장할 객체를 만듦.
		    	board.setBno(rs.getInt("bno"));
		    	board.setBtitle(rs.getString("btitle"));
		    	board.setBcontent(rs.getString("bcontent"));
		    	board.setBwriter(rs.getString("bwriter"));
		    	board.setBdate(rs.getDate("bdate"));
		    	board.setBfilename(rs.getString("bfilename"));
		    	board.setBfileData(rs.getBlob("bfileData"));
		    	
		        System.out.println(board); -- 콘솔에 출력
		    }
		    rs.close();
		    
		    
		    pstmt.close();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (conn != null) { 
				try {
					-- 연결 끊기 
					conn.close();
				} catch (SQLException e) {}
			}
		}
	}
}
 

 

 

 

 

 

 

[ 내용 참고 : 책 '이것이 자바다' ]

 

+ Recent posts