전체 글 (135)

728x90

 

수업내용 정리 (VSCode - CSS)

 

1. 홈페이지

 1-0) 미리보기

기본
커서 올려두었을 시

 

 1-1) Index.html ㄱ 

더보기
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./style.css">
</head>
<body>
    <div class="container">
        <!-- logo -->
        <div class="logo">
            <img src="./images/logo_overwatch.png" alt="" id="logo_overwatch">
        </div>
        <div class="heroes">
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div>
            <div class="hero">
                <div class="image"></div>
            </div> <!--hreo end-->
        </div> <!--hreos end-->
        <!-- logo -->
        <div class="logo2">
            <img src="./images/logo_blizzard.png" alt="" id="logo_blizzard">
        </div>
    </div> <!--container end-->
</body>
</html>
  • 이미지가 들어갈 위치를 생성했다.
  • 로고는 이미지를 index에서 바로 넣었고, 로고를 제외한 이미지(캐릭터)는 style에서 넣으려고 위치 생성만 했다.

 

 1-2) style.css

  • 박스 설정
.container{
    padding: 50px 0;
}

.container .heroes{
    display: flex;
    flex-wrap: wrap;
    justify-content: center;
    max-width: 700px;
    padding: 40px 20px;
    margin: 0 auto;
}
  • 로고나 캐릭터가 들어가는 가장 큰 박스에 padding을 주어 양쪽 여백을 준다. (배경X 미리보기에서 보이지 않는 박스)
  • display: flex → .container 안에 있는 .heroes를 수평정렬 한다. (미리보기 내 캐릭터들을 수평정렬해준다. 해당 코드가 없으면 캐릭터들이 한줄에 하나씩만 존재한다.)
더보기
  • display: flex가 존재하지 않을 때
  • flex-wrap: wrap → .container 안에 있는 .heroes를 자동으로 줄바꿈한다. (미리보기 내 캐릭터들을 자동 줄바꿈해준다. 
더보기
  • flex-wrap가 존재하지 않을 때
  • justify-content: center → .container 안에 있는 .heroes를 가운데로 정렬해준다. (미리보기 내 캐릭터들을 가운데 정렬해준다.)
더보기
  • justify-content: center가 존재하지 않을 때
  • max-width: 700px → 넓이가 700px보다 작을 때, 자동으로 재배치한다. (미리보기 내 캐릭터를 배치해준다.)
더보기
  • max-width: 700px가 존재하지 않을 때 (700px 이상일때)

 

  • max-width: 700px를 적고 화면이 700px보다 작을때
  • padding: 40px 20px → .heroes에 padding을 주어 상하/좌우에 여백을 줬다.
더보기
  • padding: 40px 20px가 존재하지 않을 때 (.heroes 밖에 있는 로고와 딱 붙는다.)
  • margin: 0 auto → .container 안에 있는 .heroes에 width가 있고, block일때 가로 가운데 정렬을 해준다.
더보기
  • margin: 0 auto가 존재하지 않을 때

 

  • body 설정
body{
    height: 100%;
    background-image: url("./images/bg.jpg");
    background-size: cover;
    background-repeat: no-repeat;
    background-attachment: fixed;
}
  • height: 100% → 뷰포트 높이 값을 100%로 적용한다.
  • background-image: url("./images/bg.jpg") → 배경이미지 삽입
더보기
  • background-image: url("./images/bg.jpg")가 존재하지 않을 때
  • background-size: cover → 화면 축소 시 배경이미지 가로 너비에 맞춘다.
더보기
  • background-size: cover가 존재하지 않을 때 (화면 너비에 따라 배경 이미지가 가려질 수 있음)
  • background-repeat: no-repeat → 배경 이미지의 반복을 제거한다. (이미지가 끝나도 반복하지 않도록 한다.)
  • background-attachment: fixed → 스크롤해도 배경이미지가 안 움직이도록 고정한다.
더보기
  • background-attachment: fixed가 존재하지 않을 때

 

 

  • 존재할때

 

  • 가장 작은 박스 설정
.container .heroes .hero{
    width: 80px;
    height: 84px;
    background-color: #555;
    margin: 4px;
    border: 3px solid #fff;
    transform: skewX(-14deg);
    border-radius: 10px;
    box-sizing: border-box;
    transition: transform 0.2s,
                background-color 0.5s;
    overflow: hidden;
}
  • width, height → .container 내 .heroes 내 .hero의 크기를 지정한다. (미리보기 내 캐릭터 이미지 크기를 지정해준다.)
  • background-color: #555 → .hero의 배경색을 #555555로 지정한다.
더보기
  • 배경색 지정을 안 했을 때 ( 삽입한 이미지가 투명화가 되어있거나 이미지 삽입을 안 하면 배경 이미지가 배경색이 된다.)
  • margin: 4px → .hero 간 간격을 준다.
더보기
  • 간격을 안 줬을 때
  • border: 3px solid #fff → .hero에 선을 그리고, 그 선의 색상을 지정한다.
더보기
  • 선을 그리지 않았을 때
  • transform: skewX(-14deg) → .hero를 x축으로 14도만큼 기울인다.
더보기
  • 기울이지 않았을 때
  • border-radius: 10px → .hero의 네모칸을 둥글게 깎는다.
더보기
  • 둥글게 깎지 않았을 때 
  • box-sizing: border-box → .hero의 사이즈가 처음 설정한 사이즈에서 벗어나지 않도록 한다.
더보기
  • 설정하지 않았을 때

 

  • 설정했을 때 (차이가 보일진 모르겠으나 설정했을 때 사이즈가 더 작다.)
  • transition: transform 0.2s, background-color 0.5s → 0.2초 동안 전환, 배경색은 0.5초동안 전환한다. (밑에 hover에서 설정을 해놨기 때문에 커서를 올렸을 때 전환)
  • overflow: hidden → 이미지가 넘치는 것을 제어한다.
더보기
  • 넘침 제어를 하지 않았을 때
.container .heroes .hero:hover{
    /* 배경 그라데이션 */
    background: linear-gradient(to top, #555, rgb(112,194,190));
    /* background-color: rgb(112,194,190); */   /* 단색 */
    transform: scale(1.4) skewX(-14deg);
    z-index: 1;
}
  • background: linear-gradient(to top, #555, rgb(112,194,190)) → .hero에 커서를 올려두었을 때 배경을 그라데이션으로 채운다.
  • transform: scale(1.4) skewX(-14deg) → .hero의 크기를 1.4배 확대하고, x축을 -14만큼 이동한다.
  • z-index: 1  → 커서를 올렸을 때 캐릭터를 가장 맨 위로 올린다.
더보기
  • z-index를 사용하지 않았을 때 
.container .heroes .hero .image{
    /* 부모 .hero의 크기를 기준으로설정, 크기 줘야 배경이 보임 */
    width: 140%;
    height: 100px;
    /* 이미지 가운데 정렬 */
    background-position: center;
    /* 이미지 축소 */
    background-size: 90px;
    /* 이미지 반복 제거 */
    background-repeat: no-repeat;
    /* 기울임 제거, 왼쪽+위로 이미지 이동 */
    transform: skewX(14deg) translateX(-16px) translateY(-10px);
}

 

  • 캐릭터 이미지 설정 ㄱ 
더보기
/* .hero가 첫째인 요소의 .image에 캐릭터 이미지 설정 */
.container .heroes .hero:nth-child(1) .image{ background-image: url("./images/hero1.png"); }
.container .heroes .hero:nth-child(2) .image{ background-image: url("./images/hero2.png"); }
.container .heroes .hero:nth-child(3) .image{ background-image: url("./images/hero3.png"); }
.container .heroes .hero:nth-child(4) .image{ background-image: url("./images/hero4.png"); }
.container .heroes .hero:nth-child(5) .image{ background-image: url("./images/hero5.png"); }
.container .heroes .hero:nth-child(6) .image{ background-image: url("./images/hero6.png"); }
.container .heroes .hero:nth-child(7) .image{ background-image: url("./images/hero7.png"); }
.container .heroes .hero:nth-child(8) .image{ background-image: url("./images/hero8.png"); }
.container .heroes .hero:nth-child(9) .image{ background-image: url("./images/hero9.png"); }
.container .heroes .hero:nth-child(10) .image{ background-image: url("./images/hero10.png"); }
.container .heroes .hero:nth-child(11) .image{ background-image: url("./images/hero11.png"); }
.container .heroes .hero:nth-child(12) .image{ background-image: url("./images/hero12.png"); }
.container .heroes .hero:nth-child(13) .image{ background-image: url("./images/hero13.png"); }
.container .heroes .hero:nth-child(14) .image{ background-image: url("./images/hero14.png"); }
.container .heroes .hero:nth-child(15) .image{ background-image: url("./images/hero15.png"); }
.container .heroes .hero:nth-child(16) .image{ background-image: url("./images/hero16.png"); }
.container .heroes .hero:nth-child(17) .image{ background-image: url("./images/hero17.png"); }
.container .heroes .hero:nth-child(18) .image{ background-image: url("./images/hero18.png"); }
.container .heroes .hero:nth-child(19) .image{ background-image: url("./images/hero19.png"); }
.container .heroes .hero:nth-child(20) .image{ background-image: url("./images/hero20.png"); }
.container .heroes .hero:nth-child(21) .image{ background-image: url("./images/hero21.png"); }
.container .heroes .hero:nth-child(22) .image{ background-image: url("./images/hero22.png"); }
.container .heroes .hero:nth-child(23) .image{ background-image: url("./images/hero23.png"); }
.container .heroes .hero:nth-child(24) .image{ background-image: url("./images/hero24.png"); }
.container .heroes .hero:nth-child(25) .image{ background-image: url("./images/hero25.png"); }
.container .heroes .hero:nth-child(26) .image{ background-image: url("./images/hero26.png"); }
.container .heroes .hero:nth-child(27) .image{ background-image: url("./images/hero27.png"); }
.container .heroes .hero:nth-child(28) .image{ background-image: url("./images/hero28.png"); }
.container .heroes .hero:nth-child(29) .image{ background-image: url("./images/hero29.png"); }
.container .heroes .hero:nth-child(30) .image{ background-image: url("./images/hero30.png"); }
.container .heroes .hero:nth-child(31) .image{ background-image: url("./images/hero31.png"); }
.container .heroes .hero:nth-child(32) .image{ background-image: url("./images/hero32.png"); }

 

  • 로고 설정
/* logo 이미지 설정 */
.container .logo{
    max-width: 300px;
    margin: 0 auto;
    padding: 0 20px;
}
.container .logo img{
    width: 300px;
}
.container .logo2{
    max-width: 100px;
    margin: 0 auto;
    padding: 0 20px;
}
.container .logo2 img{
    width: 100px;
}

 


 

전체 피드백

  • 오늘 오전에 선생님이 하시는 것 따라하는 식으로 수업을 진행했는데 이번 수업은 생각보다 재미있었다. 물론, 자바를 할 때가 제일 재밌었다..

 


728x90
728x90

 

수업내용 정리 (VSCode - CSS)

 

1. 테두리

 1-1) 선

<body>
    <div class="container">
        <div class="item">item1</div>
        <div class="item">item2</div>
    </div>
</body>
    <style>
        .container .item{
            width: 100px;
            height: 100px;
            background-color: rgb(118,118,180);
        }
        .container *:first-child{
            /* 선 두께, 종류, 색상(기본값 검정) (일반적 순서) */
            /* border: 4px solid #f90; /#ff9900을 줄여서 사용할 수 있음 둘둘둘일 경우 */
            border: 4px solid rgb(25,25,120);

            /* 선 굵기 */
            border-width: 1px;

            /* 선 색 */
            border-color: #24272B;

            /* 선 종류 */
            border-style: dashed; /* 점선 */
        }
    </style>
  • border: 선 두께, 종류, 색상 한 번에 설정 가능
  • border-width: 선 굵기
  • border-color: 선 색
  • border-style: 선 종류

 

 1-2) 둥글게

<body>
    <div></div>
</body>
    <style>
        div{
            width: 100px;
            height: 100px;
            background-color: #24272B;
            margin: 20px;
            border-radius: 20px;
        }
    </style>
  • border-radius: 모서리를 깎아서 둥글게 만든다.

 

 

2. 크기계산

<body>
    <div class="item">Hello</div>
    <div class="item">Hello</div>
</body>
    <style>
        .item {
            width: 100px;
            height: 100px;
            background-color: #24272B;
        }

        .item:first-child {
            padding: 20px;
            border: 5px solid;
            box-sizing: border-box;
            /*border-box: 요소의 내용+padding+border로 크기(width:100px)를 계산
              기본값: content-box: 요소의 내용만으로 크기(width:100px)를 계산  */
        }
    </style>

 

 

3. 넘침 제어

<body>
    <div class="parent">
        <div class="child"></div>
    </div>
</body>
    <style>
        .parent{
            background-color: rgb(118,118,180);
            width: 200px;
            height: 200px;
            /* 넘침제어 */
            overflow: hidden;
            /* overflow: auto; */
        }
        .child{
            width: 300px;
            height: 100px;
            background-color: rgb(25,25,120);
        }
    </style>
  • overflow 속성: 넘침을 방지 / 부모에게 줘야함
  • visible: 넘침 내용을 그대로 보여줌(기본값)
  • hidden: 넘침 내용을 잘라냄
  • sroll: 넘침 내용을 잘라냄
  • auto: 넘침 내용이 있는 경우에만 잘라내고 스크롤바 생성

 

 

4. 출력특성

<body>  
    <span>Hello World!</span>
    <br>
    <!-- 아래 a태그에 가로세로 사이즈 주기 -->
    <a href="http://www.naver.com">네이버</a>
    <a href="http://www.daum.net">다음</a>
</body>
    <style>
        body{
            font-size: 20px;
            margin: 20px;
        }
        span{
            /* dispaly는 사이즈 안 먹음 block이면 먹음 */
            /* none 안 보임 */
            display: block;
            width: 100px;
            height: 50px;
            background-color: rgb(118,118,180);
            color: aliceblue;
        }
         a{
            /* visibility: hidden; / 영역은 유지하지만 사라짐 */
            /* display: none; / 영역까지 사라짐*/
            display: block;
            width: 100px;
            height: 80px;
            background-color: rgb(118,118,180);
            color: aliceblue;
            border: 1px solid #24272B;
            box-sizing: border-box;
            text-align: center;
         }
    </style>
  • a 태그에 가로세로 크기 주기는 문제였다.
        /* display속성: 요소의 화면출력 특성
          1.각 요소에 이미 지정되어 있는 값
          -block: 상자(레이아웃) 요소
          -inline: 글자 요소(width,height안됨)
         -inline-block: 글자+상자요소
         2.따로 지정해서 사용하는 값
         -flex: 플렉스 박스(1차원 레이아웃,주로 수평정렬시 사용)
         -grid: 그리드(2차원 레이아웃)
         -none: 화면에서 사라짐(영역이 사라진다.유용함)
         -기타: table, table-row, table-cell 등.. */

 

 

5. 투명도

<body>
    <div class="parent">
        <div class="child"></div>
    </div>
</body>
    <style>
        .parent {
            background-color: rgb(118, 118, 180);
            width: 200px;
            height: 200px;
            /* 넘침제어 */
            overflow: hidden;
            /* overflow: auto; */
        }

        .child {
            width: 300px;
            height: 100px;
            background-color: rgb(25, 25, 120);
            /* .07(7%) / .5(50%) / 1(100%) */
            opacity: 0.5;
        }
    </style>

 

 

6. 글꼴 (p 문단 출처: 링크)

<body>
    <h1>Hello World!</h1>
    <p>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit.
        Phasellus vel tempor ex, sit amet dignissim nulla. In vel libero arcu.
        In faucibus, libero sed fringilla hendrerit, dolor lectus pulvinar ante, in aliquam ligula neque sed ante.
        Ut tortor purus, mollis ac dui nec, finibus dignissim elit. Aliquam at ipsum erat. Aenean vitae porttitor lectus, eu mollis est.
        Etiam blandit felis ut tellus accumsan tempus. Quisque dapibus risus id finibus sagittis.
        Maecenas semper nisl ac quam commodo, in pharetra neque condimentum.
    </p>
</body>
    <style>
        h1{
            font-size: 24px;
            /* 100~900 */
            font-weight: 700;
            font-style: italic;
            /* sans-serif(고딕체계열), serif(바탕체계열) */
            font-family: 'Times New Roman', Times, sans-serif;
        }
        p{
            width: 350px;
            height: 200px;
            padding: 10px;
            border: 1px solid;
            box-sizing: border-box;
            text-align: center;

            /* 줄 높이(세로 가운데 정렬 시 사용) 현재는 flex로 정렬 / 단위: px */
            /* line-height: 16px; */
            line-height: 2; /* 글자크기의 두배 */
            
            margin: 0 auto; 
        }
    </style>

 

 

7. 문자

<body>
    <a href="https://google.com">Google</a>
    <p>
        1. 동해물과 백두산이 마르고 닳도록
        하느님이 보우하사 우리나라 만세
        무궁화 삼천리 화려 강산
        대한 사람 대한으로 길이 보전하세
    
        2. 남산 위에 저 소나무 철갑을 두른 듯
        바람 서리 불변함은 우리 기상일세
        무궁화 삼천리 화려 강산
        대한 사람 대한으로 길이 보전하세
      </p>
</body>
    <style>
        a{
        display: block;
        width: 200px;
        height: 100px;
        background-color: rgb(118,118,180);
        font-size: 24px;
        color: aliceblue;
        text-decoration: none;
        text-align: center;

        /* 세로 가운데 정렬(편법) */
        line-height: 100px;
        }
        p{
            /* text-align: center; */
            /* 들여쓰기(양수)/내어쓰기(음수) */
            text-indent: 50px;
        }
    </style>

 

 

8. 배경

<body>
    <div></div>
    <!-- <img src="http://via.placeholder.com/640x480" alt=""> -->
</body>
    <style>
        div{
            width: 300px;
            height: 400px;
            background-color: #24272b;
            background-image: url("../img/Jinx.png");
            /* background-size: 300px 400px; 위 이미지를 늘린것 */
            /* 이미지 사이즈(비율 유지 확대/축소): 기본값(auto), px */
            background-size: contain;
            background-repeat: no-repeat; /* 반복 안 함 */
            /*  방법1: top, bottom, left, rifht(조합 가능), center
                방법2: x축:100px y축:30px */
            background-position: center;
            background-attachment: fixed; /* 스크롤해도 이미지는 움직이지 않음 */
        }
        body{
            height: 3000px;
        }
    </style>
  • cover: 더 넓은 너비에 맞춤
  • contain: 더 짧은 너비에 맞춤

 

 

9. 띄움

 9-1) float

<body>
    <img id="img1" src="../img/Viego.png" alt="비에고" width="150">
    <img id="img2" src="../img/Jinx.png" alt="징크스">
    <!-- <div style="border: 1px solid rgb(118,118,180);">영역</div> -->
    <p>
        Lorem ipsum dolor sit amet, consectetur adipiscing elit.
        In vehicula tempus sagittis.
        Ut non sagittis velit.
        Integer pretium commodo erat eget pellentesque.
        Proin in malesuada arcu, a tincidunt neque.
        Integer turpis libero, mollis mollis eros vitae, ullamcorper
        pulvinar dolor.
    </p>
    <p class="second">
        Cras volutpat odio ac aliquam mattis.
        In fermentum purus massa, id congue dolor lacinia eu. Nulla facilisi.
        Vivamus a scelerisque tortor, sit amet maximus mi.
        Morbi condimentum velit eget felis commodo, vel ornare lectus volutpat.
        In ac gravida neque.
        Suspendisse ex enim, efficitur et nunc quis, ullamcorper sollicitudin magna.
    </p>
</body>
    <style>
        #img1 {
            /* 흐름에서 제외 */
            float: right;
        }
        #img2 {
            float: left;
        }
        .second{
            clear:both;
        }
    </style>
  • float 속성: 가장 위 레이어에서 자리는 차지하나, 정상흐름에서 제외된다.

 

 9-2) float_clear

<body>
    <h2>넘침 제어</h2>
    <div class="container">
        <div class="box_container">
            <div class="box">Box1</div>
            <div class="box">Box2</div>
            <div class="box">Box3</div>
            <div class="box">Box4</div>
        </div>
    </div>
</body>
    <style>
        .container {
            margin-top: 35px;
        }

        .box_container {
            overflow: hidden;
            padding: 10px;
            background-color: bisque;
        }

        .box_container .box {
            float: left;
            width: 100px;
            height: 100px;
            background-color: #09f;
        }

        /* 가족간에 붕괴된 레이아웃 잡는 방법 세가지 */
        /* 설정하지 않으면 부모높이가 0이 된다. */
        /* 부모에게 overflow:hidden 적용*/
        /* 부모에게 float 적용*/
        /* 부모에게 clearfix 적용- 많이 사용하지만 귀찮음*/

        /* .box_container .box1,
        .box_container .box2 {
            float: left;
        }
        .box_container .box3 {
            clear: both; / float을 무시 /
        } */
    </style>

 

 

10. 배치

 10-1)

<body>
    <div class="static">
        position:static
    </div>
    <div class="relative">
        position:relative 
		<div class="absolute">position:<br/>absolute</div>		
    </div>  
    <div class="fixed">
        position:fixed
    </div>
</body>
    <style>
        body{
            height: 3000px;
        }
        div{
            width: 200px;
            height: 200px;
            text-align: center;
        }
        div.static{
			position: static;
            /*기본값이고 문서의 정상적인 흐름에 따라 배치됨*/
            background-color: yellow;
            /*stacit에서는 top, left적용되지 않음*/
			top:100px;
            left: 200px;
        }
        div.relative{
            background-color: aqua;
            position: relative;
            /*정상적인 위치에서 상대적으로 요소가 배치됨*/
            top: 100px;
            left: 20px;
        }
        div.absolute{
            position: absolute;
            /*static 부모 역할 못함
              부모(보통relative)가 있다면 부모좌상단을 기준으로 배치됨*/
            width: 100px;
            height: 100px;
            border: 3px solid red;
            left: 50%;
            top: 50%;
        }
        div.fixed{
            background-color: coral;
            position:fixed;
            /*화면스크롤시 같은 위치에 고정됨*/ 
            top: 10%;
            right:10%;
        }
    </style>

 

 10-2)

<body>
  <!--부모 div는 overflow:hidden으로 설정한다.-->
  <div id="parent">
    <div class="child">자식 DIV</div>
    <div class="child">자식 DIV</div>
  </div>
</body>
  <style>
    #parent{
            /*부모 Div는 overflow:hidden을 무조건 설정
			 부모보다 자식의 width,height가 큰 경우 잘라내기 위해 */
             border:3px solid black;
            overflow:hidden;
            /*z-index: 부모가 무조건 자식 아래에 위치한다.*/
            
        }
        .child{
            border:1px solid blue;
            float:left;
            /*디테일하게 영역을 설정하기 위해선 float을 사용할 것.*/ 
            /*display: inline-block;*/
            height: 100px;
           background-color: antiquewhite;
           margin:10px;
        }
  </style>

 

 

11. 배치

 11-1)

<body>
  <!-- position속성: 요소의 위치 지정 기준 
    static: 기준없음(기본값)
    relative: 요소 자신을 기준(부모 역할)
    absolute: 위치 상 부모 요소를 기준(자식 역할)
    fixed: 뷰포트(브라우저)를 기준
    
    <position과 같이 사용하는 방향속성들:음수 가능>
      top, bottom, left, right, z-index(중요)
 -->
  <div class="wrap">
    <div class="container">
      <div class="item">1</div>
      <div class="item">2</div>
      <div class="item">3</div>
    </div>
  </div>
</body>
  <style>
    
    .wrap{
      width: 400px;
      height: 300px;
      background-color: tomato;
      /* 여기도 위치상 부모가 아니면 브라우저가 부모가 된다. */
      /* position: relative; */
    }
    .container {
      width: 300px;
      background-color: royalblue;
      /* absolute, fixed는 위치상의 부모 구조가 무너지는 경우가 있다. */
      position: relative;
    }

    .container .item {
      border: 4px dashed red;
      /* background-color: orange; */
    }
    .container .item:nth-child(1) {
      width: 100px;
      height: 100px;
      background-color: antiquewhite;
    }

    .container .item:nth-child(2) {
      width: 140px;
      height: 70px;
      background-color: azure;
      /*relative는 원래영역은 차지하고 있고 지정 좌표에 나타나므로 사용되지 않음*/
	  /* position: relative; */
      /*absolute는 위치상 부모요소를 기준으로 배치하므로 형제들을 신경쓰지 않고 위치한다.*/
      position: absolute;
      top: 30px;
      right: 30px;
	  /*container div가 위치상 부모요소가 되려면 
      position: relative;로 설정해야 함 
      만약 relative가 아니고 할아버지 요소가 relative면
      위치상 부모는 할아버지 요소가 된다. 
      그것도 아니면 화면(뷰포트)기준으로 배치한다. */
    /*fixed: 뷰포트(브라우저)를 기준으로 생성:스크롤시 위치 고정 */
      /* position: fixed; */
      
    }
    /* position: fixed; 테스트시 설정*/ 
    body{
      height: 3000px;
    }
    .container .item:nth-child(3) {
      width: 70px;
      height: 120px;
      background-color: aquamarine;
    }
  </style>

 

 11-2) 

<body>
  <!-- 요소 쌓임 순서: Stack order 
    1.요소에 position속성의 값이 있는 경우 위에 쌓임(static 제외)
    2.1번 조건이 같은 경우, z-index속성의 숫자 값이 높을 수록 위에 쌓임
    3.1번2번 조건까지 같은 경우, html의 다음 구조일 수록 위에 쌓임
  -->
  <div class="container">
    <div class="item">1</div>
    <div class="item">2</div>
    <div class="item">3</div>
  </div>
</body>
  <style>
    .container {
      width: 300px;
      background-color: royalblue;
      /* absolute, fixed는 위치상의 부모 구조가 무너지는 경우가 있다. */
      position: relative;
    }

    .container .item {
      width: 100px;
      height: 100px;
      border: 4px dashed red;
      /* background-color: orange; */
    }
    .container .item:nth-child(1) {
      background-color: orange;
      position: relative;
      /* z-index 기본값:0, 없으면 2번째가 위로 온다  */
      /* z-index: 1;  */
      
    }
    .container .item:nth-child(2) {
      background-color: orangered;
      position: absolute;
      top: 50px;
      left: 50px;
    }
    .container .item:nth-child(3) {
      background-color: aqua;
      /* position이 없이 z-index가 높아도 우선순위에 밀린다. */
      position: fixed;
      z-index: 3;
      top: 30px;
      left: 30px;
    }
  </style>

 

 11-3)

<body>
  <!-- z-index속성: 값이 높을수록 위에 쌓인다(기본값:auto(0), 너무큰수는 관리가 힘듬) 
    1.요소에 position속성의 값이 있는 경우 위에 쌓임(static 제외)
    2.1번 조건이 같은 경우, z-index속성의 숫자 값이 높을 수록 위에 쌓임
    3.1번2번 조건까지 같은 경우, html의 다음 구조일 수록 위에 쌓임
  -->
  <div class="container">
    <div class="item">1</div>
    <div class="item">2</div>
    <div class="item">3</div>
  </div>
  <hr>
  <span>Hello!</span>
</body>
  <style>
    .container {
      width: 300px;
      background-color: royalblue;
      /* absolute, fixed는 위치상의 부모 구조가 무너지는 경우가 있다. */
      position: relative;
      /* overflow: hidden; */
    }

    .container .item {
      width: 120px;
      height: 120px;
      border: 4px dashed red;
    }

    .container .item:nth-child(1) {
      /* position:static; */
      background-color: orange;
      
    }

    .container .item:nth-child(2) {
      background-color: orangered;
      position: absolute;
      top: 50px;
      left: 100px;
      z-index: 1;
    }

    .container .item:nth-child(3) {
      background-color: aqua;
      /* position이 없이 z-index가 높아도 우선순위에 밀린다. */
      position: absolute;
      bottom: -30px;
      right: -10px;
      z-index:2;
    }
    span{
      width: 100px;
      height: 100px;
      background: orange;
      font-size: 40px;
      /* absolute or fixed일때 display는 block로 변환된다.*/
      position:absolute;
    }
  </style>

 

 

12. Light-Box

<body>
  <div id="bg">
    <div id="popup">
      <h2>공지사항-LightBox</h2>
    </div>
  </div>
</body>
  <style>
    #bg {
      /* display: flex;   */
      /* flex-wrap:wrap ;           */
      background-color: black;
      opacity: .5;
      /* width: auto;     */
      height: 100vh;
      /*하늘에서 바라본 건물의 높이이다.
      부모,자식div간에는 적용되지 않음
    */
      /* z-index: 2; */
    }

    #popup {
      text-align: center;
      width: 500px;
      height: 600px;
      margin: 0 auto;
      /*width있을 때덩어리 가운데 정렬*/
      background-color: yellow;
      /* z-index: 3; */
    }
  </style>

 

 

13. Flex

 13-1)

<body>
    <div class="container">
        <div class="item">1</div>
        <div class="item">2</div>
        <div class="item">3</div>
    </div>
    
    <div class="container">
        <div class="item">1</div>
        <div class="item">2</div>
        <div class="item">3</div>
    </div>
</body>
    <style>
        /*Flex Container(부모 요소)*/
        .container {
            background-color: royalblue;
            /*display:부모전용속성,
			flex:부모요소는 block, 자식요소는 수평정렬함
			inline-flex(사용빈도적음):부모요소는 inline, 자식요소는 수평정렬함 
			*/
            /*수평 주축 설정: 기본값(row),row-reverse: 자식요소를 오른쪽->왼쪽 배치 */
            /* flex-direction: row-reverse; */
            /*수직 주축 설정(사용빈도없음, display:block시 어짜피 수직이므로): column,column-reverse */
            /* flex-direction: column-reverse; */
            padding: 10px;
            margin: 10px;
       }

        /*Flex Items(자식 요소)*/
        .container .item {
            width: 100px;
            height: 100px;
            border: 3px dashed red;
            background-color: orange;
        }
    </style>

 

 13-2) 

<body>
    <div class="container">
        <div class="item">1</div>
        <div class="item">2</div>
        <div class="item">3</div>
        <div class="item">4</div>
        <div class="item">5</div>
    </div>
</body>
    <style>
        /*Flex Container(부모 요소)*/
        .container {
            background-color: royalblue;
            /*display(부모전용속성): flex;
            부모요소는 block이고,  Flex Items(자식 요소)를 수평정렬함*/
            display: flex;
            /*display: inline-flex; 부모요소는 inline이고, 자식요소는 수평정렬(사용빈도 적음) */
            /*수평 주축 설정: 기본값(row),row-reverse: 자식요소를 오른쪽->왼쪽 배치 */
            /*flex-direction: row-reverse;*/
            padding: 10px;
            margin: 10px;

            width: 300px;
            /* 자식높이가 부모높이를 초과시 height 삭제 */
            /* height: 200px;  */
            height: 400px; 
            /*flex-wrap: 기본값(nowrap)_Flex Items(자식 요소)를 줄바꿈 안함(너비가 줄어들수 있음)
              wrap: 자식요소를 줄바꿈(너비 줄지 않음)
            */
            flex-wrap: wrap;

            /*justify-content: 자식요소 수평 정렬방식*/
            /*기본값:flex-start(왼쪽정렬),flex-end(오른쪽정렬), center(가운데정렬)  */
            /* justify-content:center ; */
            
            /*align-content: 자식요소가 여러줄일때 수직 정렬방식(한줄일때 동작안함????테스트해보니 한줄도 정렬됨)
              flex-wrap: wrap설정해야 정렬가능함, 그래서 align-items를 많이 사용함 */
            /*기본값:stretch(높이를 늘림), flex-start(위쪽정렬),flex-end(아래쪽정렬), center(가운데정렬)  */
            /* align-content:flex-end ; */

             /*align-items: 자식요소를 한줄마다 수직 정렬방식(align-content보다 많이 사용)*/
            /*기본값:stretch(높이를 늘림), flex-start(위쪽정렬),flex-end(아래쪽정렬), center(가운데정렬)  */
            align-items: flex-start;
    

        }

        /*Flex Items(자식 요소)*/
        .container .item {
            width: 100px;
            /* 수직 정렬 stretch시 height생략해 볼것 */
            height: 100px;
            border: 3px dashed red;
            background-color: orange;
        }
    </style>

 

 13-3) 

<body>
  <h2>Flex: 정렬</h2>
  <div id="wrap">
    <div class="floating-box">box1</div>
    <div class="floating-box">box2</div>
    <div class="floating-box">box3</div>
    <div class="floating-box">box4</div>
    <div class="floating-box">box5</div>
    <div class="floating-box">box6</div>
    <div class="floating-box">box7</div>
    <div class="floating-box">box8</div>
  </div>
</body>
  <style>
    /* Flex Container(부모요소) */
    #wrap {
      /* overflow: hidden;  필요없음*/
      display: flex;
      /* 너비 설정하지 말것 */
      max-width: 300px;
      height: 500px;
      /* 자동 줄바꿈 */
      flex-wrap: wrap;
      /* 수평 정렬 */
      justify-content: center;
      /* 수직 정렬1:  flex-wrap:wrap 설정해야 정렬가능함*/
      /* align-content: center; */
      /* 수직 정렬2: flex-wrap:wrap 필요없음,
      자식요소를 한줄마다 수직 정렬방식(align-content보다 많이 사용) */
      align-items:center;
      /* 수직 정렬 stretch시 자식요소 height 삭제할것  */
      /* align-items: stretch; */
      padding: 10px;
      border: 1px dashed red;
    }
 /* Flex Items (자식 요소)*/
    .floating-box {
      /* div내 컨텐츠(문자) 정렬위해 설정 */
      display: flex;
      /* 컨텐츠(문자) 수평 정렬 */
      justify-content: center;
      /* 컨텐츠(문자) 수직 정렬 */
      align-content: center;
      width: 50px;
      /* 수직 정렬 stretch시 height생략해 볼것 */
      height: 100px;
      border: 3px solid orange;
      margin: 10px;
    }
  </style>

 

  13-4) 

<body>
    <div class="container">
        <div class="item">1</div>
        <div class="item">2</div>
        <div class="item">3</div>
    </div>
</body>
    <style>
        /*Flex Container(부모 요소)*/
        .container {
            width: 500px;
            height: 400px; 
            display: flex;
            background-color: royalblue;
            justify-content: center;
            /* align-items: stretch; 기본값*/
            align-items: center;
    

        }

        /*Flex Items(자식 요소)*/
        .container .item {
            width: 100px;
            /* 수직 정렬 stretch시 height:auto 또는 생략해 볼것 */
            height: 100px;
            border: 3px dashed red;
            background-color: orange;
        }
    </style>

 

 13-5)

<body>
    <div class="container">
        <div class="item">1</div>
        <div class="item">2</div>
        <div class="item">3</div>
    </div>
</body>
    <style>
        /*Flex Container(부모 요소)*/
        .container {
            width: 500px;
            height: 400px; 
            display: flex;
            background-color: royalblue;
            justify-content: center;
            /* align-items: stretch; 기본값*/
            align-items: center;
        }

        /*Flex Items(자식 요소)*/
        .container .item {
            width: 100px;
            /* 수직 정렬 stretch시 height:auto 또는 생략해 볼것 */
            height: 100px;
            border: 3px dashed red;
            background-color: orange;
            /* Flex Item의 증가 너비 비율: 기본값(0),
            부모수평영역에 자식요소가 1:1:1비율의 수평 배치 */
            flex-grow: 1;
            /* Flex Item의 공간 배분 전 기본 너비: 기본값(auto, 요소 내용 너비)*/
            /* 0px: 요소 내용 너비 무시 */
            flex-basis: 0;
        }
        .container .item:nth-child(3) {
            flex-grow: 2;
        }
    </style>

 

 13-6)

<body>
    <h1> Flex: 정렬 </h1>
    <div id="wrap">
        <div class="item">box1</div>
        <div class="item">box2</div>
        <div class="item">box3</div>
        <div class="item">box4</div>
        <div class="item">box5</div>
        <div class="item">box6</div>
        <div class="item">box7</div>
        <div class="item">box8</div>
    </div>
</body>
    <style>
        /* Flex Container(부모요소) */
        #wrap{
            /* overflow: hidden; */
            display: flex;
            max-width: 500px;
            height: 500px;
            /* 자동 줄바꿈 */
            flex-wrap: wrap;
            /* 수평정렬 */
            justify-content: center;
            /* 정렬방향 */
            /* justify-content: flex-start; 왼쪽정렬 */
            /* 수직정렬 */
            align-items: center;

            padding: 10px;
            border: 1px dashed red;
        }
        /* Flex Items(자식요소) */
        .item{
            /* float: left; */
            width: 50px;
            height: 100px;
            border: 3px solid orange;
            display: flex;
            /* 수평정렬 */
            justify-content: center;
            /* 수직정렬 */
            align-items: center;
        }
    </style>

 


728x90
728x90

 

수업내용 정리 (VSCode - CSS)

 

1. 해당 태그에 직접 설정

<body>
    <!-- 인라인 방식: 다른 것보다 우선순위가 높지만 관리가 힘들다.
        같은 디자인을 입력하고 싶을 때 코드가 길어지고 귀찮음 -->
    <div style="color:rgb(118,118,180); margin: 40px; border: 1px solid rgb(25,25,112);">영역</div>
</body>
</html>
  • 인라인 방식
  • 다른 것보다 우선 순위가 높지만 관리가 힘들다.
  • 같은 디자인을 여러번 입력하고 싶을 때, 코드가 길어지고 귀찮다.

 

2. css 링크로 설정

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./css/myStyle.css">
    <!-- rel: 링크에 대한 관계 -->
</head>
<body>
    <div>영역2</div>
</body>
</html>
/* css */
div{
    color: rgb(118,118,180);
    margin: 100px;
    padding: 40;
    border: 1px solid rgb(25,25,112);
}
  • 링크를 직접 타이핑해도 되지만 ./ 치면 해당 폴더의 파일들이 뜨니 여기서 선택하는 것이 편하다.

 

 

3. 선택자

<body>
    <div>
        <ul>
            <li>사과</li>
            <li>딸기</li>
            <li id="orange" class="orange">오렌지</li>
        </ul>
        <div>당근</div>
        <p>토마토</p>
        <span class="orange">오렌지</span>
    </div>
</body>

 

 3-1) 기본 선택자

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        /* 전체 선택자 */
        *{color: rgb(118,118,180)}
        /* 태그 선택자 */
        li{color: rgb(25,25,112);}
        /* 클래스 선택자 */
        .orange{color: rgb(0,0,0);}
        /* 아이디 선택자 */
        #orange{color: rgb(255,255,255);}
    </style>
</head>

  • 아이디>클래스>태그>전체 순으로 우선 순위를 가진다.
  • 밑으로 내려가면 동일한 부분은 덮어쓰기한다.

 

 3-2) 복합 선택자

    <style>
        /* 일치 선택자: 순서 바뀌면 안 됨 */
        /* span태그이면서 class가 oragne인것 / 띄어쓰기하면 전혀 다른 의미가 되어버림 */
        span.orange{
            color: rgb(25,25,118);
        }
        /* 자식 선택자 */
        ul>.orange{color: rgb(118,118,180);}
        /* 하위(후손) 선택자: 자식선택자보다 많이 사용 / div >후손< 중 클래스가 orange인 */
        div .orange{color: aliceblue;}
    </style>

  • 띄어쓰기에 주의할 것

 

 3-3) 복합 선택자2

<body>
    <ul>
        <li>딸기</li>
        <li>수박</li>
        <li class="orange">오렌지</li>
        <li>망고</li>
        <li>사과</li>
      </ul>
</body>
    <style>
        /* 인접 형제 선택자: .orange의 다음 형제 요소를 하나 선택 */
        .orange+li{
            color: rgb(118,118,180);
        }
        /* 일반 형제 선택자: .orange의 다음 형제 요소들을 선택 */
        .orange~li{
            color: rgb(25,25,120);
        }
    </style>

 

 

 

4. 선택자

 4-1) 가상클래스

.box{
    width: 100px;
    height: 100px;
    background-color: rgb(118, 118, 180);
    transition: 1s;
}
/* hover: 마우스를 올렸을때 */ /*hover, focus는 외울것*/
.box:hover{
    width: 300px;
    background-color: rgb(210, 222, 240);
}
.box:active{
    width: 300px;
    background-color: aliceblue;
}
.box:focus{
    width: 300px;
    background-color: aquamarine;
}
a:hover{
    color: rgb(118, 118, 180);
}
a:active{
    color: rgb(210, 222, 240);
}
a:active{
    color: aliceblue;
}
input:focus{
    background-color: azure;
}
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" href="./css/main.css">
</head>

<body>
    <div class="box" tabindex="1">tabindex속성으로 foucs 선택자 사용</div> <!--tabindex -1 : tab키 불가-->
    <a href="https://www.naver.com">네이버</a><br>
    <input type="text" name="id" />
</body>

 

 4-2) 가상클래스2

<body>
    <div class="fruits">
        <span>딸기</span>
        <span>수박</span>
        <div>오렌지</div>
        <p>망고</p>
        <h3>사과</h3>
      </div>
</body>
        /* .fruits의 후손 중에서 span이 첫 자식이면 선택 */
        .fruits span:first-child{
            color: rgb(118,118,180);
        }
        /* .fruits의 후손 중에서 div가 첫 자식이면 선택 (없음) */
        .fruits div:first-child{
            color: rgb(25,25,112);
        }
        /* .fruits의 후손 중에서 h3이 첫 자식이면 선택 */
        .fruits h3:first-child{
            color: rgb(155, 180, 222);
        }
        /* .fruits의 후손 중에서 두번째 자식을 선택 */
        .fruits *:nth-child(2){
            color: rgb(151, 199, 159);
        }
        /* .fruits의 후손 중에서 짝수번째 자식을 선택 */
        /* n은 0,1,2,....., 짝수번째 선택 */
        .fruits *:nth-child(2n){
            color: rgb(228, 166, 214);
        }
        /* .fruits의 후손 중에서 홀수번째 자식을 선택 / 1+2n 안 됨 */
        .fruits *:nth-child(2n+1){
            color: rgb(228, 166, 214);
        }
        /* .fruits의 후손 중에서 span이 아닌 자식 선택(부정선택자) */
        .fruits *:not(span){
            color: rgb(228, 166, 214);
        }

 

 4-3) 속성

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        /* 속성 선택자 */
        [disabled] {color: red;}

        [type] {color: blue;}

        /*따옴표 쓰는 것을 권장 */
        [type="password"] {color: aqua;}

        /*data속성 선택자 */
        [data-fruit-name] {color: coral;}

        button,
        [type="button"] {color: brown;}
    </style>
</head>

<body>
    <input type="text" value="cha">
    <input type="password" value="1234">
    <input type="text" value="ABCD" disabled>
    <span data-fruit-name="apple">사과</span>
    <button>btn1</button>
    <input type="button" value="btn2">
</body>

 

 4-4) 스타일 상속

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    .animal {
      color: red;
    }

    /*강제 상속 css  */
    .parent {
      width: 300px;
      height: 200px;
      background-color: red;
    }

    .child {
      width: 100px;
      height: inherit;
      /*부모크기를 강제 상속함*/
      background-color: inherit;
      /*부모색상을 강제 상속함*/
      position: fixed;
      top: 100px;
      right: 10px;
    }
  </style>
</head>

<body>
  <!-- 상속되는 CSS 속성들
   -모든 글자/문자 관련 속성들!
   (모든 글자/문자 속성은 아님 주의!)
   font-style: 글자 기울기
   font-weight: 글자 두께
   font-size: 글자 크기
   line-height: 줄 높이(간격)
   font-family: 폰트(글꼴)
   color: 글자 색상
   text-align: 정렬
  ... -->
  <div class="ecosystem">생태계
    <div class="animal">동물
      <div class="tiger">호랑이</div>
      <div class="lion">사자</div>
      <div class="elephant">코끼리</div>
    </div>
    <div class="plant">식물</div>
  </div>
  <H3>강제 상속</H3>
  <div class="parent">
    <div class="child"></div>
  </div>
</body>

 

 4-5) 우선순위

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    div{color: red !important;  } /* 무한메달*/
    #color_yellow{color:yellow;}  /* 금메달*/
    .color_green{color:green;}   /* 은메달*/
    div{color:blue;}             /* 동메달*/
    *{color:darkblue;}          /* 참가메달*/
    body{color:violet;}         /* 상속은 메달없음*/
  </style>
</head>

<body>
  <!-- 점수가 높은 선언이 우선함
  점수가 같으면 가장 마지막에 해석된 선언이 우선함 -->
  <div id="color_yellow" class="color_green"
    style="color: orange;">  <!--인라인: 특메달-->
    Hello world!
  </div>
</body>

 

 4-6) 우선순위2

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <style>
    div{ font-size:70px;   }
    div.hello{color:green;}
    .hello{color:red !important;} /*인라인CSS와 함께 권장하지 않음*/
    *{ /*참가상*/   }
    div{ /*동메달*/   }
    .hello{/*은메달*/    }
    #hello{ /*금메달*/   }
  </style>
</head>

<body>
  <div id="hello" class="hello" style="color: orange">Hello World!</div>
</body>

 

 

5. 너비

<body>
 <div>DIV</div>
 <span>SPAN</span>
 <span>SPAN</span>
 <hr>
 <div class="parent">
  <div class="child"></div>
 </div> 
</body>
  <style>
     /* div의 기본값: width:auto; 브라우저 너비만큼 
        div의 기본값: height:auto; 컨텐츠 높이만큼 */
     /* div{
      width: 100px;
      height: 100px;
      background-color: orange; 
    }  */

    /* span의 기본값: width:auto; 컨텐츠(글자) 너비만큼 
       span의 기본값: height:auto; 기본값: 컨텐츠(글자) 높이만큼
       span은 보통 글자를 제어하므로 width, height적용되지 않음*/
    /* span{
       width: 100px; 
      height: 100px;
      background-color: aqua; 
    }*/

    /**** 위의 div css 주석후 실행 ****/
    .parent{
      /* 자식에서 max width 설정시 부모width는 auto 또는 크게 설정할것*/
      width:auto; 
      /* 자식에서 min width 설정시 부모width는 작게 설정할것*/
      /* width: 300px;  */
      height: 200px;
      background-color: blue;
    } 
    /*자식 div가 위로 배치됨*/
    .child{
      /*max(min)-width설정시 삭제 또는 width:auto로 설정*/
      /* width: 300px; */
      /*부모 너비(높이)를 벗어나지 않음, 기본값: none */
      max-width: 500px ;
      /*부모 너비(높이)를 벗어날 수 있음, 기본값: 0 */
      /* min-width: 400px; */
      height: 100px;
      background-color: yellow;
    }
  </style>

 

 

6. CSS 단위

<body>
  <div class="parent">
    <div class="child"></div>
   </div> 
</body>
  <style>
    /* px, %, em(요소글꼴의 크기), rem(root(html)요소 글꼴의 크기), vw,vh)
    0px==0%==0em==0rem==0  따라서 단위를 붙이지 않는다. */
    html{
      /* font-size: 16px; 브라우저 기본값 후손으로 상속됨*/
    }
    .parent{
      width: 300px; 
      height: 200px;
      background-color: blue;
      /* font-size: 10px; */
    }
    .child{
      /* width: 200px; */
      /* width: 50%; */
      /* width: 20em;   글꼴크기*20  */
      width: 20rem;   /*root(html)태그 글꼴크기*20  */
      height: 100px;
      background-color: yellow;
    }
  </style>

 

 

7. 여백

<body>
  <div class="container">
    <div class="item"></div>
    <div class="item"></div>
    <div class="item"></div>
  </div>
</body>

 7-1) 외부

  <style>
    .container .item{
      width: 100px;
      height: 100px;
      background-color:  orange;
      border: 4px solid red;
      /* 브라우저가 여백을 계산, 가로너비가 있을때 가운데 정렬됨 */
      /* margin: 0;  기본값 */
      /* margin: auto;   */
      /* 다른 여백에서도 사용되는 규칙 */
      /* margin-top,margin-bottom,margin-left,margin-right:10px */
      /* margin: 10px;  */
      /*top,bottom:10px, left,right:20px */
      /* margin: 10px 20px ; */
      /* top:10px, left,right:20px, bottom:30px  */
      /* margin: 10px 20px 30px; */
      /* top:10px, right:20px, bottom:30px, right:40px(시계방향) */
      /* margin: 10px 20px 30px 40px; */
      /* 음수값으로 겹치게 할수 있음 */
      /* margin:-20px 10px; */
    }
  </style>

 

 7-2) 내부

  <style>
    .container .item{
      width: 100px;
      height: 100px;
      background-color: orange;
      border: 4px solid red;
    }
    .container .item:first-child{
      /* margin과 같은 방식으로 여백지정 */
      padding: 20px;
    }
  </style>

 


728x90
728x90

 

수업내용 정리 (VSCode - html)

 

0. 시작

더보기
  • 새 파일을 누르면 파일 이름을 적을 수 있게 되는데 이때 파일 이름 뒤에 파일 형식을 꼭 적어야 한다.

 

 

  • 아무것도 없는 상태에서 !(느낌표)를 치고 enter를 치면 자동으로 기본값이 생성된다.
  • html>head+body / html>(head+body) 이라고 치고 enter를 치면 html 안에 head와 body가 생성된다. (부모>자식 / 부모>자식+자식 으로 생각하면 된다.)

 

  • <nn>, </nn> : 시작, 끝 태그 | <nn/> : 시작과 끝 태그

 

 

1. H Tag

  • 강조
  • 1~6까지 가능하고, 숫자가 클수록 글자의 크기가 작아진다.
<head>
	<title>제목</title>
</head>
<body>
	<h1>큰 제목</h1>
	<h2>두번째 큰 제목</h2>
	<h3>세번째 큰 제목</h3>
</body>

 

 

2. A Tag

  • 하이퍼 링크 태그 / 링크 이동에 사용
<body>
	<a href="http://www.naver.com" target="_blank">네이버</a>
</body>
  • href: 링크 주소 입력. 인터넷 주소가 아닌 파일 주소도 가능하다. (./ : 해당 파일 위치의 파일들을 작성할 수 있다.)
  • target: 링크를 열 때 해당 창을 바꿀지, 아니면 새 창으로 띄울지 정함. target을 안 적으면 해당 창을 바꾸는 것이 기본 설정이다. (_blank: 새 창)
  • >네이버< : 네이버 자리가 링크를 이동할 때 보여지는 이름

 

 

2. Table

  • caption: 테이블 제목
  • tr: 행
  • th: 열 / 칼럼 글자를 굵게 만듦
  • td: 열 / 일반 데이터
  • colspan / rowspan: 열 / 행 합침
    <table border="1" align="center" width="200" hight="150">
        <caption>명단</caption>
        <thead>
            <tr align="center">
                <th>firstName</th>
                <th>lastName</th>
                <th>Point</th>
            </tr> <!-- tr>th*3 -->
        </thead>
        <tbody>
            <tr align="center">
                <td>홍길동</td>
                <td>길동</td>
                <td>100</td>
            </tr> <!-- tr>td*3 -->
            <tr>
                <td>이</td>
                <td>순신</td>
                <td>100</td>
            </tr> <!-- tr>td*3 -->
            <tr>
                <td>신</td>
                <td>사임당</td>
                <td>100</td>
            </tr> <!-- tr>td*3 -->
        </tbody>
    </table>

  • table 안에 tr, tr 안에 th와 td를 넣어 사용한다.
  • tr>td*3 실행 시 행 하나, 열 세 개가 자동 생성된다.
  • table에 붙어있는 border, align 등은 원래 head에서 style을 통해 넣어야 하지만 연습 겸 table에 넣었다.

 

<table border="1" align="center" width="200" hight="150">
    <caption>명단</caption>
    <thead>
        <tr align="center">
            <th colspan="2">Name</th>
            <!-- <th>lastName</th> -->
           <th>Point</th>
        </tr> <!-- tr>th*3 -->
    </thead>
    <tbody>
        <tr align="center">
            <td colspan="2">홍길동</td>
            <!-- <td>길동</td> -->
            <td rowspan="3">100</td>
        </tr> <!-- tr>td*3 -->
        <tr>
            <td>이</td>
            <td>순신</td>
            <!-- <td>100</td> -->
        </tr> <!-- tr>td*3 -->
        <tr>
            <td>신</td>
            <td>사임당</td>
            <!-- <td>100</td> -->
        </tr> <!-- tr>td*3 -->
    </tbody>
</table>

  • colspan이나 rowspan을 사용하면 합쳐지는 위치의 다른 칸은 지워줘야 한다.

 

 

3. List

  • ul - 순서가 없는 리스트
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        li{padding: 10px; border: 1px solid rgb(118, 118, 180);}
    </style>
</head>
<body>
    <h2>ul - 순서가 없는 리스트</h2>
    <ul style="list-style-type: none;"> <!-- css 속성 = css문법-->
        <a href="http://www.naver.com" target="_blank"><li>html</li></a>
        <a href="./02_table.html" target="_blank"><li>css</li></a>
        <li><a href="http://www.chrome.com">java</a></li>
        <a href="http://www.nexon.com" target="_blank"><li>javaScript</li>
        <li>jQuery</li></a>
    </ul>
</body>

  • ul>li*5 실행 시 하나의 리스트에 5칸이 생긴다.
  • a 태그 를 통해 링크를 넣을 수 있다.
  • a 태그를 li 안에 넣으면 글씨만 링크로 이동할 수 있도록 하고, 밖에 넣으면 네모칸 전체가 링크로 이동할 수 있도록 한다.
  • 링크는 아무거나 넣었다.

 

  • ol
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        li{
            list-style-type: none;
            float: left;
            padding: 20px;
            background-color: rgb(118, 118, 180);
        }
        li:hover{
            background-color: rgb(20, 20, 118);
        }
    </style>
</head>
<body>
    <ul>
        <li>HTML</li>
        <li>CSS</li>
        <li>JAVASCRIPT</li>
        <li>JQUERY</li>
    </ul>
</body>

  • style을 통해 네모 칸의 크기를 지정할 수 있다.
  • li:hover을 통해 칸에 마우스가 올라가면 색이 바뀌게 설정할 수도 있다.

 

  • li - 순서가 있는 리스트
<body>
    <h2>ol - 순서가 있는 리스트</h2>
    <ol style="list-style-type: lower-roman;">
        <li>html</li>
        <li>css</li>
        <li>js</li>
        <li>jq</li>
    </ol>
</body>

  • ol>li*4 실행 시 하나의 리스트에 4까지의 순서가 생긴다.
  • list-style-tye으로 순서를 다르게 표기할 수 있다. 설정 안 할 시 기본타입(1. 2. 3.)으로 나온다.

 

  • 더블 리스트
<body>
    <ul>
      <li>Java</li>
      <li>DB</li>
      <ul>
        <li>오라클</li>
        <li>MySQL</li>
      </ul>
      <li>Front-End</li>
      <ul>
        <li>html</li>
        <li>css</li>
        <li>js</li>
        <li>jq</li>
      </ul>
    </ul>
  </body>

  • list 안에 list를 넣어 더블 리스트를 만들 수도 있다.

 

 

4. i - Frame

  • 다른 url의 페이지를 삽입한다.
<body>
    <h1>iFrame.html</h1>
    <iFrame src="06_menuList.html" frameborder="1" width="500"></iFrame>
</body>

  • 입력한 링크의 페이지를 보여준다.

 

 

5. Input

  • 입력 폼 (<input type="n" ~~></form> n 자리에 타입을 적는다.)
  • text: 텍스트를 적는 칸을 생성
  • password: 텍스트를 적으면 암호화되어 보인다.
    <fieldset>
        <legend>text&password&hidden&button</legend>
        <form action="access" method="get">
            아이디: <input type="text" id="id" name="userId" value="aa"> <br>
            비밀번호: <input type="password" id="pw" name="userPw"> <br>
            hidden: <input type="hidden" name="point" value="100">
            <input type="submit" value="로그인">
            <!-- method="get"  // 보안처리 안 함
                file:///C:/data/vsCode/HTML/access?userId=aa&userPw=aa&point=100
                /요청url/쿼리스트링: ?파라미터명=값&파라미터명=값&파라미터명=값 -->
            <!-- method="post" // 보안처리
                file:///C:/data/vsCode/HTML/access -->
            <button>서버전송</button>   <!--서버전송버튼-->
            <input type="button" value="그냥버튼" onclick="alert('경고창')">
            <input type="button" onclick="showIdPw()" value="아이디, 비번 출력">
        </form>
    </fieldset>
    <script>
        // 자바스크립트js
        function showIdPw(){
            let id=document.getElementById('id');
            console.log('id: ', id.value);
            let pw=document.getElementById('pw').value;
            console.log('pw: ', pw); // 오브젝트와 적을때는 콤마(,)를 사용해야함
        }
    </script>

  • id: 중복이 안 되고, 중복해서 적으면 처음 적은 애만 적용된다. 서버(파라미터) 전달용
  • name / value: 중복이 가능하다. 식별용

 

  • checkbox: fieldset 내의 타입 checkbox 중 택 다
  • radio: fieldset 내의 타입 radio 중 택 1
    <fieldset>
        <legend> checkbox & radio & label</legend>
        <!--선택사항(택 다)-->
        <input id="apple" name="fruit" type="checkbox" value="사과">
        <label for="apple">Apple</label>
        <input id="grape" name="fruit" type="checkbox" value="포도">
        <!--fruit라는 파라미터에 체크한값(value) 저장-->
        <label for="grape">Grape</label> <br>

        <!--택 1-->
        성별: <input type="radio" name="gender" value="male"> 남자
        <input type="radio" name="gender" value="female" checked> 여자
    </fieldset>

  • label이 아니라 input 뒤에 이름을 붙여도 똑같이 나오지만 체크박스를 클릭해야만 체크가 되므로 불편하다. label로 묶으면 글자를 클릭해도 체크박스에 체크가 되므로 사용자가 편하게 사용할 수 있게 된다.
  • chexked: 기본적으로 선택되게 만든다.

 

  • file: 파일을 올린다.
    <fieldset>
        <legend>file</legend>
        <input type="file" name="attach">
        <!--파일 선택-->
    </fieldset>

 

  • select: select 내 option 중 택 1
    <fieldset>
        차: <select name="cars">
            <!--선택-->
            <option value="default">선택하시오</option>
            <option value="volvo">볼보</option>
            <option value="kia">기아</option>
            <option value="porshe">포르쉐</option>
            <option value="benz">벤츠</option>
        </select>
    </fieldset>

  • selected / default: 기본적으로 선택되게 만든다.

 

  • submit: 값을 서버에 전송하는 버튼
    <fieldset>
        <legend>e-mail & url</legend>
        <form action="test">
            email: <input type="email" name="email"> <br>
            url: <input type="url"> <br>
            <input type="submit" value="전송">
            <!--form 태그 안에 있는 값을 서버에 submit(전송)함-->
        </form>
    </fieldset>

 

 

6. form

<body>
    <form id="frm" name="loginForm" method="get"></form>
    <input type="text" name="id" id="id" placeholder="아이디입력하셈">
    <input type="password" name="pw" id="pw" placeholder="비밀번호입력하셈">
    <button>전송1</button>
    <input type="submit" value="전송2">
    <input type="button" value="버튼" onclick="check()"> <!--검증용-->
</body>
<script>
    function check(){
        let idElem=document.getElementById('id');
        console.dir(idElem);

        let id=idElem.value;
        let pw=document.getElementById('pw').value;
        console.log(id.length, pw.length);

        if(id.length<4 || id.length>6){
            alert('아이디 길이는 4~6자');
            return false;
        }
        let pwLen=pw.length;
        if(pwLen<4 || pwLen>6){
            alert('비밀번호 길이는 4~6자');
            return false;
        }
        document.loginForm.submit();    // name이 loginForm인 것을 서버로 전송
    };
</script>

alert

  • placeholder: 도움말
  • 전송1, 전송2는 서버에 바로 전송한다.
  • 버튼은 일반 버튼을 검증 후 맞으면 서버에 전송하도록 메소드를 사용했다. (주로 사용!)

 


 

전체 피드백

  • html을 할 때마다 내 길이 아닌 것 같다는 생각만 든다..자바가 더 재밌는듯 ㅠㅠ 

 


728x90
728x90

 + 코드블럭을 추가하면 한가지만 설정되는 것이 너무 거슬린다..SQL은 SQL, Java는 Java 이런 식으로 저장하고 싶은데 ㅠㅠ 


 

수업내용 정리 (Jdbc)

 

1. 과제

이전에 하던 전화번호부 프로젝트를 조건에 맞춰 완성하기
1. HashSet 대신 전화번호 리스트를 MySQL 서버 테이블에 저장
2. 저장 테이블(칼럼명): PHONEMEMBER(name,phone,major,year,company,kind)
 2-1. PK키: name, phone
 2-2. 자료형: VARCHAR(20) / 단, year은 int, kind(N,U,C)는 CHAR(1)로 한다.
3. 메뉴 입력 오류 시 예외처리
4. JDBC를 활용하여 DB 접속

등 이 외에도 전체 출력 시 AllayList 활용 등 조건이 있었지만 전부 작성하진 않았다.

 

 1-1) MySQL ㄱ 

더보기
create table PHONEMEMBER(
	PM_NO int unsigned auto_increment not null,
	NAME varchar(20),
	PHONE varchar(20),
	MAJOR varchar(20),
	YEAR tinyint unsigned,
	COMPANY varchar(20),
	KIND char(1) not null,
	constraint primary key PK_PM(PM_NO, NAME, PHONE)
);
desc phonemember;
  • DB 테이블
  • 조건에 맞춰 칼럼을 작성했고, 추가적으로 정렬할 때 전화번호를 입력한 순서대로 정렬하기 위해 자동으로 번호가 정렬되는 PM_NO 칼럼을 하나 더 작성했다.
  • auto_increment는 기본키에 사용할 수 있다고 떠서 PK가 조건인 NAME, PHONE과 묶었다. (PK키인데 not null을 붙인 이유는 PK를 붙이기 전에 적고 넘어갔기 때문이다..)
  • desc phonemember;는 phonemember 테이블에 대한 구조를 확인하는 코드다.

 

create or replace view pm_view
as select PM_NO, NAME, PHONE, MAJOR, YEAR, COMPANY, KIND
from phonemember order by pm_no;
  • select로 검색할 때 어느 테이블에서 무엇을 어떻게 검색할 것인지 적은 view 생성

 

-- 검색 수정 삭제용 더미데이터
insert into phonemember(name, phone, kind) values('a', '1234', 'N');
insert into phonemember(name, phone, major, year, kind) values('b', '2222', 'af', '1', 'U');
insert into phonemember(name, phone, company, kind) values('c', '3333', 'ge', 'C');

-- 연습용
delete from phonemember;
select*from pm_view;
select*from pm_view where name='a';
update phonemember set name='aa' where name='a';
  • Java에서 검색, 수정, 삭제할 때 사용할 더미데이터 및 문법 연습용 코드
  • 나중에 추가적으로 중복이름에 관해 코드를 엎을 때는 데이터를 새로 더 추가하고 사용했다.

 

commit;
rollback;

 

 

 1-2) Java - common (db 관련 자주 쓸 메소드 클래스) ㄱ

더보기
package common;

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

// jdbc 공통 메소드
public class JdbcUtil {
	static {
		try {
			Class.forName("com.mysql.cj.jdbc.Driver");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
	
	public static Connection getConnection() {
		try {
			Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "icia", "1234");
			return con;
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	public static void dbClose(ResultSet rs, PreparedStatement pstmt, Connection con) {
		try {
			if(rs!=null) rs.close();
			if(pstmt!=null) pstmt.close();
			if(con!=null) con.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	public static void txCommit(Connection con) {
		try {
			con.commit();
		} catch (SQLException e) {
			System.out.println("commit fail");
			e.printStackTrace();
		}
	}
	public static void txRollback(Connection con) {
		try {
			con.rollback();
		} catch (SQLException e) {
			System.out.println("rollback fail");
			e.printStackTrace();
		}
	}
}
  • db 관련 자주 쓸 메소드 클래스
  • 해당 프로젝트에서는 쓰지 않는 메소드(commit, rollback)도 있지만 Jdbc 공통 메소드 클래스로 사용하고 있기 때문에 따로 삭제는 하지 않았다.

 

 1-3) Java - exception (메뉴 예외 처리) ㄱ 

더보기
package exception;

public class MenuWrongException extends Exception {
	private int wrongMenuNum;
	
	public MenuWrongException(int menuNum) {
		this.wrongMenuNum = menuNum;
	}
	public void showWrongNumInfo() {
		System.out.println(" > "+wrongMenuNum+"에 해당하는 메뉴가 없습니다.");
	}
}
  • 메뉴 예외 처리 클래스
  • 메인 메뉴에서 설정한 번호가 아닌 다른 번호를 선택했을 시 해당 번호에 대한 메뉴가 없다는 메시지를 띄운다.

(서브 메뉴에 넣는 것을 잊어서 메인메뉴에만 존재한다..)

 

 1-4) Java - controller (메인 메뉴 / 메인 메뉴를 처리하는 메소드를 모아둔 클래스)

 메인메뉴 ㄱ 

더보기
package controller;

import java.util.InputMismatchException;
import java.util.Scanner;
import exception.MenuWrongException;

public class JdbcPBMain {
	public static Scanner sc = new Scanner(System.in);
	public static void main(String[] args) {
		
		while(true) {
			try {
				showMenu();
				int menu = sc.nextInt();
				if(menu < 0 || menu > 5) throw new MenuWrongException(menu);
				System.out.println();
				
				switch (menu) {
				case 1:
					System.out.println("===> 전화번호 입력");
					JdbcPBManager.inputData();
					break;

				case 2:
					System.out.println("===> 전화번호 검색");
					JdbcPBManager.serchData();
					break;
					
				case 3:
					System.out.println("===> 전화번호 수정");
					JdbcPBManager.updateData();
					break;

				case 4:
					System.out.println("===> 전화번호 삭제");
					JdbcPBManager.deletData();
					break;
					
				case 5:
					System.out.println("===> 전체 목록");
					JdbcPBManager.showAllData();
					break;
					
				case 0:
					System.out.println(" > 프로그램을 종료합니다.");
					return;

				default:

				}
			} catch (InputMismatchException e) {
				System.out.println(" > 문자를 입력하셨습니다.");
				sc.nextLine();
			} catch (MenuWrongException e) {
				e.showWrongNumInfo();
			}
			System.out.println();
		}
	}

	private static void showMenu() {
		System.out.println("===== 전화번호부 =====");
		System.out.println("""
				------------------
				 1. 전화번호 입력
				 2. 전화번호 검색
				 3. 전화번호 수정
				 4. 전화번호 삭제
				 5. 전체 목록 출력
				 0. 프로그램 종료
				------------------ """);
		System.out.print(" 메뉴선택> ");
	}
}
  • 메인메뉴
  • 메뉴 외의 숫자를 입력하면 throw를 통해 밑의 catch MenuWrongException으로 던져서 MenuWrongException 클래스의 메소드를 실행한다.
  • 숫자가 아닌 문자를 입력했을 경우엔 InputMismatchException으로 들어가서 문자를 입력했다는 문구를 출력한다.

 메인 메뉴를 처리하는 메소드를 모아둔 클래스 ㄱ 

더보기
package controller;

import dao.JdbcPBDAO;

public class JdbcPBManager {
	private static JdbcPBDAO dao = new JdbcPBDAO();
	public static void inputData() {
		System.out.print(" ✏️   이름 입력\t:  ");
		String name = JdbcPBMain.sc.next();
		System.out.print(" ✏️  전화번호 입력\t:  ");
		String phone = JdbcPBMain.sc.next();
		try {
			boolean flag = dao.insert(name, phone);
			if(flag) {
				System.out.println("\n 📃 전화번호 입력 완료!");
			}else {
				System.out.println("\n ❌ 전화번호 입력 실패 ❌");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void serchData() {
		System.out.print(" 📒 검색할 이름: ");
		String serchN = JdbcPBMain.sc.next();
		dao.select(serchN);
	}

	public static void updateData() {
		System.out.print(" ✏️ 수정할 이름: ");
		String corN = JdbcPBMain.sc.next();
		dao.update(corN);
	}

	public static void deletData() {
		System.out.print(" ✂️ 삭제할 이름: ");
		String delN = JdbcPBMain.sc.next();
		dao.delete(delN);
	}

	public static void showAllData() {
		dao.selectAll();
	}
}
  • 메인 메뉴에서 선택한 메뉴들에 해당하는 메소드
  • 처리하기 위해 각 필요한 값을 입력받고, db 작업이 필요한 때에 dao 클래스의 메소드를 호출했다.
  • insert에서 boolean 변수를 통해 입력이 되었다면 true가 반환될테니 입력 완료를 출력하고, 입력이 안 되었다면 false가 반환될테니 입력 실패를 출력한다.

 

 1-5) Java - been (db에서 가져온 정보를 담기 위한 클래스) ㄱ 

더보기
package been;

public class Member {
	String kind;
	String name;
	String phone;
	String major;
	int year;
	String company;
	
	public Member (String kind, String name, String phone) {
		this.kind = kind;
		this.name = name;
		this.phone = phone;
	}
	public Member (String kind, String name, String phone, String major, int year) {
		this(kind, name, phone);
		this.major = major;
		this.year = year;
	}
	public Member (String kind, String name, String phone, String company) {
		this(kind, name, phone);
		this.company = company;
	}
	
	public String getPH(){
		return phone;
	};
	
	public void sel() {
		if(major==null && company==null) {
			System.out.println(" +==================================+");
			System.out.println("   KIND\t  NAME\t  PHNUM");
			System.out.println("  -----\t  -----\t ------");
			System.out.println(" ✨ " + kind + "\t  " + name + "\t  " + phone);
			System.out.println(" +==================================+");
		}else if(company==null) {
			System.out.println(" +==================================+");
			System.out.println("   KIND\t  NAME\t  PHNUM\t MAJOR(YEAR)");
			System.out.println("  -----\t  -----\t ------\t -----------");
			System.out.println(" 🏫 " + kind + "\t  " + name + "\t  "+ phone
					+ "\t   " + major + "(" + year + ")");
			System.out.println(" +==================================+");
		}else if(major==null) {
			System.out.println(" +==================================+");
			System.out.println("   KIND\t  NAME\t  PHNUM\t  COMPANY");
			System.out.println("  -----\t  -----\t  ------  --------");
			System.out.println(" 💼 " + kind + "\t  " + name + "\t  "
					+ phone + "\t   " + company);
			System.out.println(" +==================================+");
		}
	}
	
	public String tS(int i) {
		String str;
		if(major==null && company==null) {
			str=(" "+i+" "+kind+"\t"+name+"\t "+phone);
		}else if(company==null) {
			str=(" "+i+" "+kind+"\t"+name+"\t "+phone+"\t  "+major+"("+year+")");
		}else if(major==null) {
			str=(" "+i+" "+kind+"\t"+name+"\t "+phone+"\t\t\t "+company);
		}else {
			str=null;
		}
		return str;
	}
	@Override
	public String toString() {
		String str;
		if(major==null && company==null) {
			str=(" ✨ "+kind+"\t"+name+"\t "+phone);
		}else if(company==null) {
			str=(" 🏫 "+kind+"\t"+name+"\t "+phone+"\t  "+major+"("+year+")");
		}else if(major==null) {
			str=(" 💼 "+kind+"\t"+name+"\t "+phone+"\t\t\t "+company);
		}else {
			str=null;
		}
		return str;
	}
}
  • ArrayList로 출력할 때 타입이 되어줄 Member 클래스
  • 값을 담아둘 필드들과 값을 받아올 생성자, phone 값을 리턴할 메소드를 제외하곤 거의 꾸밈용으로 인해 코드가 길어졌다..

 

 1-6) Java - dao (메인메뉴를 처리하는 메소드의 동작 / 실상 모든 동작)

(선생님이 따로 dao라는 패키지-클래스를 만들어서 하라고 하셔서 만들었지만, 아직 메소드를 모아둔 클래스에서 바로 처리하지 않는 이유를 잘 이해하지 못하겠다.)

 전체 코드 ㄱ 

더보기
package dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import been.Member;
import common.JdbcUtil;
import controller.JdbcPBMain;

// db 작업 로직
public class JdbcPBDAO {
	Connection con;
	PreparedStatement pstmt;
	ResultSet rs;
	private String major;
	private int year;
	private String company;
	private ArrayList<Member> mList;
	private ArrayList<Member> serchList;

	public boolean insert(String name, String phone) {
		con = JdbcUtil.getConnection();
		String sql = "select*from pm_view where name=? and phone=?";
		try {
			pstmt = con.prepareStatement(sql);
			pstmt.setString(1, name);
			pstmt.setString(2, phone);
			rs = pstmt.executeQuery();
			if (!rs.next()) {
				plusAns();
				if (major == null && company == null) {
					sql = "insert into phonemember(name, phone, kind)" + " values(?, ?, ?)";
					pstmt = con.prepareStatement(sql);
					pstmt.setString(1, name);
					pstmt.setString(2, phone);
					pstmt.setString(3, "N");
				} else if (company == null) {
					sql = "insert into phonemember(name, phone, major, year, kind)" + " values(?, ?, ?, ?, ?)";
					pstmt = con.prepareStatement(sql);
					pstmt.setString(1, name);
					pstmt.setString(2, phone);
					pstmt.setString(3, major);
					pstmt.setInt(4, year);
					pstmt.setString(5, "U");
				} else if (major == null) {
					sql = "insert into phonemember(name, phone, company, kind)" + " values(?, ?, ?, ?)";
					pstmt = con.prepareStatement(sql);
					pstmt.setString(1, name);
					pstmt.setString(2, phone);
					pstmt.setString(3, company);
					pstmt.setString(4, "C");
				}
				pstmt.executeUpdate();
				return true;
			} else {
				System.out.println(" > 이미 입력된 정보입니다.");
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			JdbcUtil.dbClose(rs, pstmt, con);
		}
		return false;
	}

	
	public void selectAll() {
		addArray();
		print(mList);
	}
	
	public void select(String serchN) {
		addArray(serchN);
		if(serchList.size()==1) {
			serchList.get(0).sel();
		}else if(serchList.size()==0){
			System.out.println(" > 정보를 찾을 수 없습니다.");
		}else {
			print(serchList);
		}
	}
	
	
	public void update(String corN) {
		addArray(corN);
		if(serchList.size()==1) {
			update(corN, serchList.get(0).getPH());
		}else if(serchList.size()==0){
			System.out.println(" > 정보를 찾을 수 없습니다.");
		}else {
			print(serchList, 1);
			System.out.println(" ⚠️ 이름이 중복됩니다.\n > 수정할 번호를 선택해주세요.");
			System.out.print(" ✏️ 수정할 번호: ");
			int corNum = JdbcPBMain.sc.nextInt();
			String corPH = serchList.get(corNum-1).getPH();
			update(corN, corPH);
		}
	}
	
	
	public void delete(String delN) {
		addArray(delN);
		if(serchList.size()==1) {
			delete(delN, serchList.get(0).getPH());
		}else if(serchList.size()==0){
			System.out.println(" > 정보를 찾을 수 없습니다.");
		}else {
			print(serchList, 1);
			System.out.println(" ⚠️ 이름이 중복됩니다.\n > 삭제할 번호를 선택해주세요.");
			System.out.print(" ✂️ 삭제할 번호: ");
			int delNum = JdbcPBMain.sc.nextInt();
			String delPH = serchList.get(delNum-1).getPH();
			delete(delN, delPH);
		}
	}
	
	
	
	
	
	
	/* private
	 * 
	 * 
	 * 							private
	 * 
	 * 
	 * 														private */
	
	private void plusAns() {
		major = null;
		year = 0;
		company = null;
		System.out.println("\n > 추가로 입력하시겠습니까?");
		System.out.println("""
				------------------
				 0. 다른 번호 선택 시 입력을 종료합니다.
				 1. 대학
				 2. 회사
				------------------""");
		System.out.print(" 메뉴선택> ");
		int ans = JdbcPBMain.sc.nextInt();
		if(ans<0 || ans>2)
		if (ans == 1) {
			System.out.print("\n ✏️   전공 입력\t:  ");
			major = JdbcPBMain.sc.next();
			System.out.print("\n ✏️   학년 입력\t:  ");
			year = JdbcPBMain.sc.nextInt();
		} else if (ans == 2) {
			System.out.print("\n ✏️   회사 입력\t:  ");
			company = JdbcPBMain.sc.next();
		} else {
			System.out.println(" > 입력을 종료하셨습니다.");
		}
	}

	
	private void addArray() {	// 전체출력을 위한것
		con = JdbcUtil.getConnection();
		String sql = "select*from pm_view";
		try {
			pstmt = con.prepareStatement(sql);
			rs = pstmt.executeQuery();
			mList = new ArrayList<>();
			while (rs.next()) {
				Member m = null;
				if (rs.getString("MAJOR") == null && rs.getString("COMPANY") == null) {
					m = new Member(rs.getString("kind"), rs.getString("NAME"), rs.getString("PHONE"));
				} else if (rs.getString("COMPANY") == null) {
					m = new Member(rs.getString("kind"), rs.getString("NAME"), rs.getString("PHONE"),
							rs.getString("MAJOR"), rs.getInt("YEAR"));
				} else if (rs.getString("MAJOR") == null) {
					m = new Member(rs.getString("kind"), rs.getString("NAME"), rs.getString("PHONE"),
							rs.getString("COMPANY"));
				}
				mList.add(m);
			}
		} catch (SQLException e) {
			System.out.println(" > 정보 불러오기 실패");
			e.printStackTrace();
		} finally {
			JdbcUtil.dbClose(rs, pstmt, con);
		}
	}
	private void addArray(String name) {	// 중복된 이름을 위한 것
		con = JdbcUtil.getConnection();
		String sql = "select*from pm_view where name=?";
		try {
			pstmt = con.prepareStatement(sql);
			pstmt.setString(1, name);
			rs = pstmt.executeQuery();
			serchList = new ArrayList<>();
			while (rs.next()) {
				Member m = null;
				if (rs.getString("MAJOR") == null && rs.getString("COMPANY") == null) {
					m = new Member(rs.getString("kind"), rs.getString("NAME"), rs.getString("PHONE"));
				} else if (rs.getString("COMPANY") == null) {
					m = new Member(rs.getString("kind"), rs.getString("NAME"), rs.getString("PHONE"),
							rs.getString("MAJOR"), rs.getInt("YEAR"));
				} else if (rs.getString("MAJOR") == null) {
					m = new Member(rs.getString("kind"), rs.getString("NAME"), rs.getString("PHONE"),
							rs.getString("COMPANY"));
				}
				serchList.add(m);
			}
		} catch (SQLException e) {
			System.out.println(" > 정보 불러오기 실패");
			e.printStackTrace();
		} finally {
			JdbcUtil.dbClose(rs, pstmt, con);
		}
	}
	

	private void update(String corN, String corPH) {
		con = JdbcUtil.getConnection();
		String sql = "select*from pm_view where name = ? and phone = ?";
		try {
			pstmt = con.prepareStatement(sql);
			pstmt.setString(1, corN);
			pstmt.setString(2, corPH);
			rs = pstmt.executeQuery();
			if (rs.next()) {
				if (rs.getString("KIND").equals("N")) {
					selN(rs.getString("KIND"), rs.getString("NAME"), rs.getString("PHONE"));
					System.out.print(" ✏️   이름 수정\t:  ");
					String reName = JdbcPBMain.sc.next();
					System.out.print(" ✏️  전화번호 수정\t:  ");
					String rePhone = JdbcPBMain.sc.next();
					sql = "update phonemember set name=?, phone=? where name=? and phone=?";
					pstmt = con.prepareStatement(sql);
					pstmt.setString(1, reName);
					pstmt.setString(2, rePhone);
					pstmt.setString(3, corN);
					pstmt.setString(4, corPH);
					pstmt.executeUpdate();

				} else if (rs.getString("KIND").equals("U")) {
					selU(rs.getString("KIND"), rs.getString("NAME"), rs.getString("PHONE"), rs.getString("MAJOR"), rs.getInt("YEAR"));
					System.out.print(" ✏️   이름 수정\t:  ");
					String reName = JdbcPBMain.sc.next();
					System.out.print(" ✏️  전화번호 수정\t:  ");
					String rePhone = JdbcPBMain.sc.next();
					System.out.print(" ✏️   전공 수정\t:  ");
					String reMajor = JdbcPBMain.sc.next();
					System.out.print(" ✏️   학년 수정\t:  ");
					int reYear = JdbcPBMain.sc.nextInt();
					sql = "update phonemember set name=?, phone=?, major=?, year=? where name=? and phone=?";
					pstmt = con.prepareStatement(sql);
					pstmt.setString(1, reName);
					pstmt.setString(2, rePhone);
					pstmt.setString(3, reMajor);
					pstmt.setInt(4, reYear);
					pstmt.setString(5, corN);
					pstmt.setString(6, corPH);
					pstmt.executeUpdate();
					
				} else if (rs.getString("KIND").equals("C")) {
					selC(rs.getString("KIND"), rs.getString("NAME"), rs.getString("PHONE"), rs.getString("COMPANY"));
					System.out.print(" ✏️   이름 수정\t:  ");
					String reName = JdbcPBMain.sc.next();
					System.out.print(" ✏️  전화번호 수정\t:  ");
					String rePhone = JdbcPBMain.sc.next();
					System.out.print(" ✏️   회사 수정\t:  ");
					String reCompany = JdbcPBMain.sc.next();
					sql = "update phonemember set name=?, phone=?, company=? where name=? and phone=?";
					pstmt = con.prepareStatement(sql);
					pstmt.setString(1, reName);
					pstmt.setString(2, rePhone);
					pstmt.setString(3, reCompany);
					pstmt.setString(4, corN);
					pstmt.setString(5, corPH);
					pstmt.executeUpdate();
				}
				System.out.println("\n > 수정이 완료되었습니다!");
			}
		} catch (SQLException e) {
			System.out.println(" ❌ 수정 실패 ❌");
			e.printStackTrace();
		} finally {
			JdbcUtil.dbClose(rs, pstmt, con);
		}
	}

	
	private void delete(String delN, String delPH) {
		con = JdbcUtil.getConnection();
		String sql = "select*from pm_view where name = ? and phone = ?";
		try {
			pstmt = con.prepareStatement(sql);
			pstmt.setString(1, delN);
			pstmt.setString(2, delPH);
			rs = pstmt.executeQuery();
			if (rs.next()) {
				if (rs.getString("KIND").equals("N")) {
					selN(rs.getString("KIND"), rs.getString("NAME"), rs.getString("PHONE"));
				} else if (rs.getString("KIND").equals("U")) {
					selU(rs.getString("KIND"), rs.getString("NAME"), rs.getString("PHONE"), rs.getString("MAJOR"), rs.getInt("YEAR"));
				} else if (rs.getString("KIND").equals("C")) {
					selC(rs.getString("KIND"), rs.getString("NAME"), rs.getString("PHONE"), rs.getString("COMPANY"));
				}
				sql = "delete from phonemember where name=? and phone = ?";
				pstmt = con.prepareStatement(sql);
				pstmt.setString(1, delN);
				pstmt.setString(2, delPH);
				pstmt.executeUpdate();
				System.out.println("\n > 삭제가 완료되었습니다.");
			}

		} catch (SQLException e) {
			System.out.println(" ❌ 삭제 실패 ❌");
			e.printStackTrace();
		}
	}
	
	
	
	private void print(ArrayList<Member> list) {
		if(list.size()!=0) {
			System.out.println(" > 입력한 순서대로 출력됩니다.");
			column();
			for (Member m : list) {
				if(mList.get(0) != m) {
					System.out.println(" |----\t-----\t------\t----------\t-------|");
				}
				System.out.println(m);
			}
			System.out.println(" +=============================================+");
		}else {
			System.out.println(" ⚠️ 저장된 정보가 없습니다.");
		}
	}
	private void print(ArrayList<Member> list, int i) {
		column();
		for (Member m : list) {
			if(list.get(0) != m) {
				System.out.println(" |----\t-----\t------\t----------\t-------|");
			}
			System.out.println(m.tS(i++));
		}
		System.out.println(" +=============================================+");
	}
	
	
	private void column() {
		System.out.println(" +=============================================+");
		System.out.println("  KIND\tNAME\tPHNUM\tMAJOR(YEAR)\tCOMPANY");
		System.out.println(" |=============================================|");
	}
	private void selN(String selK, String selN, String selPH) {
		System.out.println(" >---------------------+");
		System.out.println("   KIND\t  NAME\t  PHNUM");
		System.out.println(" >---------------------+");
		System.out.println(" ✨ " + selK + "\t  " + selN + "\t  " + selPH);
	}

	private void selU(String selK, String selN, String selPH, String selM, int selY) {
		System.out.println(" >----------------------------------+");
		System.out.println("   KIND\t  NAME\t  PHNUM\t MAJOR(YEAR)");
		System.out.println(" >----------------------------------+");
		System.out.println(" 🏫 " + selK + "\t  " + selN + "\t  " + selPH + "\t   " + selM + "(" + selY + ")\n");
	}

	private void selC(String selK, String selN, String selPH, String selC) {
		System.out.println(" >----------------------------------+");
		System.out.println("   KIND\t  NAME\t  PHNUM\t  COMPANY");
		System.out.println(" >----------------------------------+");
		System.out.println(" 💼 " + selK + "\t  " + selN + "\t  " + selPH + "\t   " + selC + "\n");
	}
}

 코드 설명 ㄱ 

더보기
package dao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import been.Member;
import common.JdbcUtil;
import controller.JdbcPBMain;
  • package 및 import 정보

 

 

Connection con;
PreparedStatement pstmt;
ResultSet rs;
private String major;
private int year;
private String company;
private ArrayList<Member> mList;
private ArrayList<Member> serchList;
  • 필드
  • Connection: DB 연결
  • PreparedStatement: sql 문장 전달
  • ResultSet: DB에서 가져올 값 저장
  • String major, int year, String company: 잠깐 값을 저장해두기 위한 필드 변수
  • ArrayList<Member> mList: 전체출력을 위해 정보를 담아둘 ArrayList
  • ArrayList<Member> serchList: 동명이인이 있을 경우을 계산해서 동명이인 정보만 담아둘 ArrayList

 

 

public boolean insert(String name, String phone) {
	con = JdbcUtil.getConnection();
	String sql = "select*from pm_view where name=? and phone=?";
	try {
		pstmt = con.prepareStatement(sql);
		pstmt.setString(1, name);
		pstmt.setString(2, phone);
		rs = pstmt.executeQuery();
		if (!rs.next()) {
			plusAns();
			if (major == null && company == null) {
				sql = "insert into phonemember(name, phone, kind)" + " values(?, ?, ?)";
				pstmt = con.prepareStatement(sql);
				pstmt.setString(1, name);
				pstmt.setString(2, phone);
				pstmt.setString(3, "N");
			} else if (company == null) {
				sql = "insert into phonemember(name, phone, major, year, kind)" +
			 		" values(?, ?, ?, ?, ?)";
				pstmt = con.prepareStatement(sql);
				pstmt.setString(1, name);
				pstmt.setString(2, phone);
				pstmt.setString(3, major);
				pstmt.setInt(4, year);
				pstmt.setString(5, "U");
			} else if (major == null) {
				sql = "insert into phonemember(name, phone, company, kind)" +
					" values(?, ?, ?, ?)";
				pstmt = con.prepareStatement(sql);
				pstmt.setString(1, name);
				pstmt.setString(2, phone);
				pstmt.setString(3, company);
				pstmt.setString(4, "C");
			}
			pstmt.executeUpdate();
			return true;
		} else {
			System.out.println(" > 이미 입력된 정보입니다.");
		}
	} catch (SQLException e) {
		e.printStackTrace();
	} finally {
		JdbcUtil.dbClose(rs, pstmt, con);
	}
	return false;
}
private void plusAns() {
	major = null;
	year = 0;
	company = null;
	System.out.println("\n > 추가로 입력하시겠습니까?");
	System.out.println("""
			------------------
			 0. 다른 번호 선택 시 입력을 종료합니다.
			 1. 대학
			 2. 회사
			------------------""");
	System.out.print(" 메뉴선택> ");
	int ans = JdbcPBMain.sc.nextInt();
	if(ans<0 || ans>2)
	if (ans == 1) {
		System.out.print("\n ✏️   전공 입력\t:  ");
		major = JdbcPBMain.sc.next();
		System.out.print("\n ✏️   학년 입력\t:  ");
		year = JdbcPBMain.sc.nextInt();
	} else if (ans == 2) {
		System.out.print("\n ✏️   회사 입력\t:  ");
		company = JdbcPBMain.sc.next();
	} else {
		System.out.println(" > 입력을 종료하셨습니다.");
	}
}
  • insert (정보 입력)
  • Manager에서 입력받아온 매개변수를 통해 정보가 있는지 확인(이름과 전화번호가 같은지)하고 만약 정보가 없다면 plusAns 메소드를 통해 정보를 입력받을지(대학이나 회사) 물어보고 만약 입력한다면 정보를 입력받은 뒤 다시 돌아온다. (입력받지 않아도 돌아온다.)
  • 만약 필드 변수 major과 company가 null 값이라면, 그렇지 않고 필드 변수 company가 null 값이라면, 그렇지 않고 major이 null 값이라면. 세 경우에 따라 sql 문장을 달리해서 insert로 db에 값을 저장한다.
  • 저장이 성공적으로 완료되었다면 true를 return하고, 저장에 실패했다면 false를 return한다.

 

 

public void selectAll() {
	addArray();
	print(mList);
}
private void addArray() {	// 전체출력을 위한것
	con = JdbcUtil.getConnection();
	String sql = "select*from pm_view";
	try {
		pstmt = con.prepareStatement(sql);
		rs = pstmt.executeQuery();
		mList = new ArrayList<>();
		while (rs.next()) {
			Member m = null;
			if (rs.getString("MAJOR") == null && rs.getString("COMPANY") == null) {
				m = new Member(rs.getString("kind"), rs.getString("NAME"), rs.getString("PHONE"));
			} else if (rs.getString("COMPANY") == null) {
				m = new Member(rs.getString("kind"), rs.getString("NAME"), rs.getString("PHONE"),
						rs.getString("MAJOR"), rs.getInt("YEAR"));
			} else if (rs.getString("MAJOR") == null) {
				m = new Member(rs.getString("kind"), rs.getString("NAME"), rs.getString("PHONE"),
						rs.getString("COMPANY"));
			}
			mList.add(m);
		}
	} catch (SQLException e) {
		System.out.println(" > 정보 불러오기 실패");
		e.printStackTrace();
	} finally {
		JdbcUtil.dbClose(rs, pstmt, con);
	}
}
private void print(ArrayList<Member> list) {
	if(list.size()!=0) {
		System.out.println(" > 입력한 순서대로 출력됩니다.");
		column();
		for (Member m : list) {
			if(mList.get(0) != m) {
				System.out.println(" |----\t-----\t------\t----------\t-------|");
			}
			System.out.println(m);
		}
		System.out.println(" +=============================================+");
	}else {
		System.out.println(" ⚠️ 저장된 정보가 없습니다.");
	}
}
private void column() {
	System.out.println(" +=============================================+");
	System.out.println("  KIND\tNAME\tPHNUM\tMAJOR(YEAR)\tCOMPANY");
	System.out.println(" |=============================================|");
}
  • selectAll (DB의 모든 정보 출력)
  • addArray 메소드를 통해 DB의 모든 값을 Member 객체에 저장한 후 ArrayList(mList)에 하나씩 추가한다. Member 객체에 저장할 때, 타입(kind)에 따라 저장하는 값을 다르게 했다.
  • addArray 메소드가 끝나고 selectAll 메소드로 돌아오면 print(ArrayList<Member>) 메소드를 통해 모든 멤버를 출력하도록 했다.
  • column 메소드는 꾸밈용 메소드다.

 

 

public void select(String serchN) {
	addArray(serchN);
	if(serchList.size()==1) {
		serchList.get(0).sel();
	}else if(serchList.size()==0){
		System.out.println(" > 정보를 찾을 수 없습니다.");
	}else {
		print(serchList);
	}
}
private void addArray(String name) {	// 중복된 이름을 위한 것
	con = JdbcUtil.getConnection();
	String sql = "select*from pm_view where name=?";
	try {
		pstmt = con.prepareStatement(sql);
		pstmt.setString(1, name);
		rs = pstmt.executeQuery();
		serchList = new ArrayList<>();
		while (rs.next()) {
			Member m = null;
			if (rs.getString("MAJOR") == null && rs.getString("COMPANY") == null) {
				m = new Member(rs.getString("kind"), rs.getString("NAME"), rs.getString("PHONE"));
			} else if (rs.getString("COMPANY") == null) {
				m = new Member(rs.getString("kind"), rs.getString("NAME"), rs.getString("PHONE"),
						rs.getString("MAJOR"), rs.getInt("YEAR"));
			} else if (rs.getString("MAJOR") == null) {
				m = new Member(rs.getString("kind"), rs.getString("NAME"), rs.getString("PHONE"),
						rs.getString("COMPANY"));
			}
			serchList.add(m);
		}
	} catch (SQLException e) {
		System.out.println(" > 정보 불러오기 실패");
		e.printStackTrace();
	} finally {
		JdbcUtil.dbClose(rs, pstmt, con);
	}
}
private void print(ArrayList<Member> list) {
	if(list.size()!=0) {
		System.out.println(" > 입력한 순서대로 출력됩니다.");
		column();
		for (Member m : list) {
			if(mList.get(0) != m) {
				System.out.println(" |----\t-----\t------\t----------\t-------|");
			}
			System.out.println(m);
		}
		System.out.println(" +=============================================+");
	}else {
		System.out.println(" ⚠️ 저장된 정보가 없습니다.");
	}
}
  • select (검색)
  • 다른 것들보다 검색이 쉬울 것 같아서 검색부터 진행했다.
  • addArray(String) 메소드를 통해 DB에서 매개변수로 받아온 이름과 중복된 이름이 있다면 Member 객체에 저장한 후, 새로운 ArrayList(serchList)에 하나씩 추가했다. 이때, 전체 출력과 마찬가지로 타입(kind)에 따라 저장하는 값을 다르게 했다.
  • select로 돌아오면 serchList의 길이(size)에 따라 if문으로 나눴다.
  • 만약 serchList의 길이가 1이라면 그대로 출력한다.
  • 그렇지 않고 serchList의 길이가 0이라면 정보를 찾을 수 없다는 문구를 출력한다.
  • 전부 아니라면 print(ArrayList<Member>) 메소드를 통해 serchList의 값을 출력한다.

 

 

public void update(String corN) {
	addArray(corN);
	if(serchList.size()==1) {
		update(corN, serchList.get(0).getPH());
	}else if(serchList.size()==0){
		System.out.println(" > 정보를 찾을 수 없습니다.");
	}else {
		print(serchList, 1);
		System.out.println(" ⚠️ 이름이 중복됩니다.\n > 수정할 번호를 선택해주세요.");
		System.out.print(" ✏️ 수정할 번호: ");
		int corNum = JdbcPBMain.sc.nextInt();
		String corPH = serchList.get(corNum-1).getPH();
		update(corN, corPH);
	}
}
private void addArray(String name) {	// 중복된 이름을 위한 것
	con = JdbcUtil.getConnection();
	String sql = "select*from pm_view where name=?";
	try {
		pstmt = con.prepareStatement(sql);
		pstmt.setString(1, name);
		rs = pstmt.executeQuery();
		serchList = new ArrayList<>();
		while (rs.next()) {
			Member m = null;
			if (rs.getString("MAJOR") == null && rs.getString("COMPANY") == null) {
				m = new Member(rs.getString("kind"), rs.getString("NAME"), rs.getString("PHONE"));
			} else if (rs.getString("COMPANY") == null) {
				m = new Member(rs.getString("kind"), rs.getString("NAME"), rs.getString("PHONE"),
						rs.getString("MAJOR"), rs.getInt("YEAR"));
			} else if (rs.getString("MAJOR") == null) {
				m = new Member(rs.getString("kind"), rs.getString("NAME"), rs.getString("PHONE"),
						rs.getString("COMPANY"));
			}
			serchList.add(m);
		}
	} catch (SQLException e) {
		System.out.println(" > 정보 불러오기 실패");
		e.printStackTrace();
	} finally {
		JdbcUtil.dbClose(rs, pstmt, con);
	}
}
private void print(ArrayList<Member> list, int i) {
	column();
	for (Member m : list) {
		if(list.get(0) != m) {
			System.out.println(" |----\t-----\t------\t----------\t-------|");
		}
		System.out.println(m.tS(i++));
	}
	System.out.println(" +=============================================+");
}
private void print(ArrayList<Member> list, int i) {
	column();
	for (Member m : list) {
		if(list.get(0) != m) {
			System.out.println(" |----\t-----\t------\t----------\t-------|");
		}
		System.out.println(m.tS(i++));
	}
	System.out.println(" +=============================================+");
}
private void update(String corN, String corPH) {
	con = JdbcUtil.getConnection();
	String sql = "select*from pm_view where name = ? and phone = ?";
	try {
		pstmt = con.prepareStatement(sql);
		pstmt.setString(1, corN);
		pstmt.setString(2, corPH);
		rs = pstmt.executeQuery();
		if (rs.next()) {
			if (rs.getString("KIND").equals("N")) {
				selN(rs.getString("KIND"), rs.getString("NAME"), rs.getString("PHONE"));
				System.out.print(" ✏️   이름 수정\t:  ");
				String reName = JdbcPBMain.sc.next();
				System.out.print(" ✏️  전화번호 수정\t:  ");
				String rePhone = JdbcPBMain.sc.next();
				sql = "update phonemember set name=?, phone=? where name=? and phone=?";
				pstmt = con.prepareStatement(sql);
				pstmt.setString(1, reName);
				pstmt.setString(2, rePhone);
				pstmt.setString(3, corN);
				pstmt.setString(4, corPH);
				pstmt.executeUpdate();
                
				} else if (rs.getString("KIND").equals("U")) {
				selU(rs.getString("KIND"), rs.getString("NAME"), rs.getString("PHONE"), rs.getString("MAJOR"), rs.getInt("YEAR"));
				System.out.print(" ✏️   이름 수정\t:  ");
				String reName = JdbcPBMain.sc.next();
				System.out.print(" ✏️  전화번호 수정\t:  ");
				String rePhone = JdbcPBMain.sc.next();
				System.out.print(" ✏️   전공 수정\t:  ");
				String reMajor = JdbcPBMain.sc.next();
				System.out.print(" ✏️   학년 수정\t:  ");
				int reYear = JdbcPBMain.sc.nextInt();
				sql = "update phonemember set name=?, phone=?, major=?, year=? where name=? and phone=?";
				pstmt = con.prepareStatement(sql);
				pstmt.setString(1, reName);
				pstmt.setString(2, rePhone);
				pstmt.setString(3, reMajor);
				pstmt.setInt(4, reYear);
				pstmt.setString(5, corN);
				pstmt.setString(6, corPH);
				pstmt.executeUpdate();
				
			} else if (rs.getString("KIND").equals("C")) {
				selC(rs.getString("KIND"), rs.getString("NAME"), rs.getString("PHONE"), rs.getString("COMPANY"));
				System.out.print(" ✏️   이름 수정\t:  ");
				String reName = JdbcPBMain.sc.next();
				System.out.print(" ✏️  전화번호 수정\t:  ");
				String rePhone = JdbcPBMain.sc.next();
				System.out.print(" ✏️   회사 수정\t:  ");
				String reCompany = JdbcPBMain.sc.next();
				sql = "update phonemember set name=?, phone=?, company=? where name=? and phone=?";
				pstmt = con.prepareStatement(sql);
				pstmt.setString(1, reName);
				pstmt.setString(2, rePhone);
				pstmt.setString(3, reCompany);
				pstmt.setString(4, corN);
				pstmt.setString(5, corPH);
				pstmt.executeUpdate();
			}
			System.out.println("\n > 수정이 완료되었습니다!");
		}
	} catch (SQLException e) {
		System.out.println(" ❌ 수정 실패 ❌");
		e.printStackTrace();
	} finally {
		JdbcUtil.dbClose(rs, pstmt, con);
	}
}
  • updata (수정)
  • updata(String,String) 코드 줄이기를 안 한 상태이다.
  • select(검색)처럼 addArray(String) 메소드를 통해 중복된 이름은 serchList에 저장했다.
  • updata로 돌아오면 serchList의 사이즈가 1이면 바로 매개변수와 serchList에 저장된 번호를 updata(String, String)의 매개변수로 적는다.
  • serchList의 사이즈가 0이면 정보를 찾을 수 없다고 출력한다.
  • serchList의 사이즈가 1, 0 둘 다 아니라면 print(ArrayList<Member>, int) 메소드를 통해 중복된 이름의 정보들을 출력한 후, 이름이 중복된다고 출력한다. 수정할 번호를 입력받아 해당 번호의 1을 뺀 인덱스에 저장된 번호와 매개변수를 updata(String, String)의 매개변수로 적는다. 이때, int는 출력 순서의 시작 번호이기 때문에 고정값 1을 적는다.  출력이 모두 끝나고 다시 돌아오면 수정할 번호를 입력받고, updata(String,String) 메소드에 매개변수와 serchList의 입력받은 수정할 번호에서 1을 뺀 인덱스에 저장된 번호를 적는다.
  •  updata(String, String)에서 입력받은 매개변수들을 통해 정보를 select(검색)해오고 kind 값에 따라 if문으로 나누어 수정하게 했다. 

 

 

public void delete(String delN) {
	addArray(delN);
	if(serchList.size()==1) {
		delete(delN, serchList.get(0).getPH());
	}else if(serchList.size()==0){
		System.out.println(" > 정보를 찾을 수 없습니다.");
	}else {
		print(serchList, 1);
		System.out.println(" ⚠️ 이름이 중복됩니다.\n > 삭제할 번호를 선택해주세요.");
		System.out.print(" ✂️ 삭제할 번호: ");
		int delNum = JdbcPBMain.sc.nextInt();
		String delPH = serchList.get(delNum-1).getPH();
		delete(delN, delPH);
	}
}
private void addArray(String name) {	// 중복된 이름을 위한 것
	con = JdbcUtil.getConnection();
	String sql = "select*from pm_view where name=?";
	try {
		pstmt = con.prepareStatement(sql);
		pstmt.setString(1, name);
		rs = pstmt.executeQuery();
		serchList = new ArrayList<>();
		while (rs.next()) {
			Member m = null;
			if (rs.getString("MAJOR") == null && rs.getString("COMPANY") == null) {
				m = new Member(rs.getString("kind"), rs.getString("NAME"), rs.getString("PHONE"));
			} else if (rs.getString("COMPANY") == null) {
				m = new Member(rs.getString("kind"), rs.getString("NAME"), rs.getString("PHONE"),
						rs.getString("MAJOR"), rs.getInt("YEAR"));
			} else if (rs.getString("MAJOR") == null) {
				m = new Member(rs.getString("kind"), rs.getString("NAME"), rs.getString("PHONE"),
						rs.getString("COMPANY"));
			}
			serchList.add(m);
		}
	} catch (SQLException e) {
		System.out.println(" > 정보 불러오기 실패");
		e.printStackTrace();
	} finally {
		JdbcUtil.dbClose(rs, pstmt, con);
	}
}
private void delete(String delN, String delPH) {
	con = JdbcUtil.getConnection();
	String sql = "select*from pm_view where name = ? and phone = ?";
	try {
		pstmt = con.prepareStatement(sql);
		pstmt.setString(1, delN);
		pstmt.setString(2, delPH);
		rs = pstmt.executeQuery();
		if (rs.next()) {
			if (rs.getString("KIND").equals("N")) {
				selN(rs.getString("KIND"), rs.getString("NAME"), rs.getString("PHONE"));
			} else if (rs.getString("KIND").equals("U")) {
				selU(rs.getString("KIND"), rs.getString("NAME"), rs.getString("PHONE"), rs.getString("MAJOR"), rs.getInt("YEAR"));
			} else if (rs.getString("KIND").equals("C")) {
				selC(rs.getString("KIND"), rs.getString("NAME"), rs.getString("PHONE"), rs.getString("COMPANY"));
			}
			sql = "delete from phonemember where name=? and phone = ?";
			pstmt = con.prepareStatement(sql);
			pstmt.setString(1, delN);
			pstmt.setString(2, delPH);
			pstmt.executeUpdate();
			System.out.println("\n > 삭제가 완료되었습니다.");
		}
	} catch (SQLException e) {
		System.out.println(" ❌ 삭제 실패 ❌");
		e.printStackTrace();
	}
}
  • delete (삭제)
  • delete(String,String) 코드 줄이기를 안 한 상태이다.
  • select(검색), updata(수정)처럼 addArray(String) 메소드를 통해 중복된 이름은 serchList에 저장했다.
  • 돌아오면 serchList의 사이즈가 1이면 바로 매개변수와 serchList에 저장된 번호를 delete(String, String)의 매개변수로 적는다.
  • serchList의 사이즈가 0이면 정보를 찾을 수 없다고 출력한다.
  • serchList의 사이즈가 1, 0 둘 다 아니라면 print(ArrayList<Member>, int) 메소드를 통해 중복된 이름의 정보들을 출력한 후, 이름이 중복된다고 출력한다. 수정할 번호를 입력받아 해당 번호의 1을 뺀 인덱스에 저장된 번호와 매개변수를 delete(String, String)의 매개변수로 적는다. 이때, int는 출력 순서의 시작 번호이기 때문에 고정값 1을 적는다.  출력이 모두 끝나고 다시 돌아오면 수정할 번호를 입력받고, delete(String,String) 메소드에 매개변수와 serchList의 입력받은 수정할 번호에서 1을 뺀 인덱스에 저장된 번호를 적는다.
  • delete(String, String)에서 입력받은 매개변수들을 통해 정보를 한 번 더 select(검색)해오고 kind 값에 따라 if문으로 나누어 출력을 한 번 해준 후, 삭제를 진행했다.

 

 


  • 밑은 꾸밈용 메소드
private void column() {
	System.out.println(" +=============================================+");
	System.out.println("  KIND\tNAME\tPHNUM\tMAJOR(YEAR)\tCOMPANY");
	System.out.println(" |=============================================|");
}
private void selN(String selK, String selN, String selPH) {
	System.out.println(" >---------------------+");
	System.out.println("   KIND\t  NAME\t  PHNUM");
	System.out.println(" >---------------------+");
	System.out.println(" ✨ " + selK + "\t  " + selN + "\t  " + selPH);
}
private void selU(String selK, String selN, String selPH, String selM, int selY) {
	System.out.println(" >----------------------------------+");
	System.out.println("   KIND\t  NAME\t  PHNUM\t MAJOR(YEAR)");
	System.out.println(" >----------------------------------+");
	System.out.println(" 🏫 " + selK + "\t  " + selN + "\t  " + selPH + "\t   " + selM + "(" + selY + ")\n");
}
private void selC(String selK, String selN, String selPH, String selC) {
	System.out.println(" >----------------------------------+");
	System.out.println("   KIND\t  NAME\t  PHNUM\t  COMPANY");
	System.out.println(" >----------------------------------+");
	System.out.println(" 💼 " + selK + "\t  " + selN + "\t  " + selPH + "\t   " + selC + "\n");
}

 


 

전체 피드백

  • 테이블은 하나이든 셋이든 상관이 없다고 하셨는데 나는 DB는 내 길이 아닌지 너무 어려워서 비교적 간단한 하나로 진행했다.
  • 과제에서 메인 메뉴 부분을 이전에 만들었던 것으로 재활용했다가 서브 메뉴들에서 메뉴 입력 오류 시 예외처리 하는 것을 잊고 제출해버렸다. 처음부터 끝까지 직접 짰면 하지 않았다는 것을 기억했을텐데, 하는 아쉬움이 남았지만 간단하지만 조금 귀찮은 부분을 타이핑하느라 시간을 보내기 싫었던 탓이라 나중에는 조금 더 꼼꼼히 확인해야겠다.
  • 코드를 줄이고 싶어서 메소드를 생성해두고 메소드 안에서 그 메소드를 사용하는 식으로 했는데 너무 메소드 안에 메소드인가 싶어지기도 해서 고민이 많았다.
  • 제출하고 나니 자꾸 아쉬운 부분이 보여서 슬펐다.

 

  • VSCode로 html도 잠깐 배웠는데 내일 함께 정리해서 올릴 예정이다.

 


728x90
1 2 3 4 5 6 7 8 ··· 27