반응형

Day 4

1. Thread(스레드)

  • 하나의 프로세스 내부에서 독립적으로 실행되는 하나의 작업 단위를 말하며,
  • 세부적으로는 운영체제에 의해 관리되는 하나의 작업 혹은 태스크
  • 스레드와 태스크(혹은 작업)은 바꾸어 사용해도 무관
  • 스레드 구현 방법 : 1. 스레드 이용  / 2. Runnable 이용하는 방법
JVM에 의해 하나의 프로세스가 발생하고 main( ) 안의 실행문 들이 하나의 스레드
main( ) 이외의 또 다른 스레드를 만들려면 Thread 클래스를 상속하거나 Runnable 인터페이스를 구현
다중 스레드 작업 시에는 각 스레드 끼리 정보를 주고받을 수 있어 처리 과정의 오류를 줄일 수 있음
프로세스끼리는 정보를 주고받을 수 없음

 

package Lecture.Week2;

//외우기
class CustomThreaded implements Runnable{
    //implements 받아오려면 runaable을 오버라이딩 해줘야 한다. / 오버라이딩 시 throws exception 같은 것은 붙일 수 없다.
    @Override
    public void run() {
        for(int i = 0; i < 100; i++){
            System.out.println("HelloWorld" + i);
        }
    }

}
    public class Test12 {
        public static void main(String[] args){
            //단순한 함수 호출
            Runnable rb = new CustomThreaded();
            rb.run();

            /*new Thread를 하면 가상의 cpu를 OS에서 할당한다. (분신)
            //할당받은 CPU는 생성자에 넘겨진 포인터를 물고 간다.
            start() 호출 : 준비과정을 거쳐 새로운 가상 CPU가 rb.run()을 호출한다.

            1. Runnable  상속받은 클래스 선언
            2. new Thread 하면서 1의 인스턴스의 포인터를 넘긴다
            2. Thread::start() 를 호출하면 가상 CPU(쓰레드) 가 run()을 호출*/
            Thread th = new Thread(rb); //thread의 참조형 변수
            th.start(); //이걸 해야 돌아감
        }
}

2. 프로세스 ,프로그램, 스레드

  • 프로세스 : 데이터(data) + 자원(memory) + 쓰레드(Thread) 로 구성(a running program)
  • 프로그램 : executable file
  • 스레드 : a light-weighted process (독자 행동을 하지만 조금 다르다)
    • 스레드는 프로세스 안에서만 존재가 가능하다
    • 스레드 간 메모리를 공유할 수 있다
    • 프로세스 간 메모리 전달은 가능해도 공유는 불가능하다
    • 프로세스간의 메모리 전달의 대표적 수단이 소켓이다(복사 & 붙이기도 전달로 볼 수 있지만 이건 윈도우에서 국한된 개념)
    • 프로세스 종료 == 프로세스가 가진 모든 쓰레드의 종료
    • start() : 이 스레드가 실행을 시작하도록 함-> 가상 머신 run이 thread의 메소드를 호출한다
    • run() : 이 스레드가 별도의 Runnable 실행 객체를 사용하여 작성한 경우 해당 runnable 객체의 run 메소드 호출
      그렇지 않을 경우 , 이 메서드는 아무것도 수행하지 않고 반환함.
package Lecture.Week2;
class Toilet{
    public void bigWork(String by){
        System.out.println("Step1," + by);
        System.out.println("Step2," + by);
        System.out.println("Step3," + by);
        System.out.println("Step4," + by);
        System.out.println("Step5," + by);

    }
}

/*참조형 : 오른쪽이 가르키는 대상을 왼쪽이 가르친다.
* 멤버변수 : 인스턴스 만들어진 시점에 생성*/


class A implements Runnable{
    private Toilet toilet = null;

    public A(Toilet t){
        toilet = t;
    }

    public void run(){
        for(int i = 0; i < 100;){
//            System.out.println("APPLE");
            toilet.bigWork("APPLE");
            try{
                int time = (int)(Math.random() *1000); //초 단위로 쉬게 하기
                Thread.sleep(time); //try  catch 필요
            }
            catch (InterruptedException e){}
        }
    }
}


class B implements Runnable{
    private Toilet toilet = null;

    public B(Toilet t){
        toilet = t;
    }

    public void run(){
        for(int i = 0; i < 100;){
//            System.out.println("BANANA");
            toilet.bigWork("BANANA");

            try{
                int time = (int)(Math.random() *1000); //초 단위로 쉬게 하기
                Thread.sleep(time); //try  catch 필요
            }
            catch (InterruptedException e){}
        }
    }
}
public class Test13 {
    public static void main(String[] args){
        Toilet t = new Toilet();
        new Thread( new A(t)).start(); //RUNNABLE에서 implements 받은 A의 인스턴스를 생성자에 넣어주고 START
        new Thread( new B(t)).start();
    }
}
/*쓰레드는 독자적으로 돌아가는 프로그램이 된다
* APPLE 과 BANANA 끼어들게 안 짯는데도 결과 가 나옴
* APPLE
BANANA
BANANA
APPLE
BANANA
BANANA
APPLE
BANANA
BANANA
BANANA....
*/

결과 :

Step1,APPLE
Step1,BANANA
Step2,APPLE
Step2,BANANA
Step3,BANANA
Step3,APPLE
Step4,BANANA
Step4,APPLE
Step5,BANANA
Step5,APPLE


* > 아무런 제약이 없다면 이렇게 동시 진행될 수도 있다
* 쓰레드는 독자적이기 떄문에 일어나는 현상
* -> 화장실 문을 잠가야 하니까 

=> 그것을 동기화(Synchronization)이라고 한다.

 

class Toilet{
    public void bigWork(String by){
        synchronized (this) { //this : 참조형 변수 (자기 자신에 대한)
            System.out.println("Step1," + by);
            System.out.println("Step2," + by);
            System.out.println("Step3," + by);
            System.out.println("Step4," + by);
            System.out.println("Step5," + by);
        }
    }
}

 

-모든 인스턴스에는 lock이라는 개념의 자물쇠? 열쇠?가 있다

-synchronized (this) => this가 가리키는 인스턴스가 가지고 있는 록을 획득해야 { .. 에 진입 가능

  획득하지 못하면 쓰레드는 멈추어 기다려야 한다. 

   }로 일을 마쳤으면 lock을 반납한다.

-이런 방법으로 공유하는 메모리에서 작업 도중 끊기는 일을 막을 수 있다. 

 

 

-스레드 조인  / run

package Lecture.Week2;


class A1 implements Runnable{
    public void run(){
        for(int i = 0; i <10; i++){
            System.out.println("A running");
        }
    }
}

class B1 implements Runnable{
    public void run(){
        for(int i = 0; i <10; i++){
            System.out.println("B running");
        }
    }
}

class C1 implements Runnable{
    public void run(){
        for(int i = 0; i <10; i++){
            System.out.println("C running");
        }
    }
}


public class Test14 {
    public static void main(String[] args){
        Thread[] threads = new Thread[3];

        threads[0] = new Thread(new A1());
        threads[1] = new Thread(new B1());
        threads[2] = new Thread(new C1());

        threads[0].start();
        threads[1].start();
        threads[2].start();

        try{
            threads[0].join(); //threads[0]이 끝나기전에는 내려가지 않는다.
            threads[1].join();//join()메소드는 쓰레드가 멈출때까지 기다리게 한다.
            threads[2].join();
        }//모든 쓰레드들이 다 끝나고 난 다음에 최종정리가 찍힌다.
        catch (InterruptedException e){}
//        new Thread(new A1()).start();
//        new Thread(new B1()).start();
//        new Thread(new C1()).start();

        System.out.println("최종정리");
    }
}

3. 자바 - DB 연동

줄 건다 -> 바구니 건다 -> 바구니에 물건 담는다 -> 왕복한다 -> 바구니 내린다 -> 줄 내린다

conn 형성 -> stmt 형성 -> 쿼리 작업 -> stmt.close() -> conn.close()

 

Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/study","root","1111");

Statement stmt = conn.createStatement();//바구니 만든다

String sql = "insert into studentt values ('10107', '또오치','쌍문동')"; //바구니에 담는다

stmt.executeUpdate(sql2);//쿼리 실행-> sql문 실어서 간다

stmt.close(); //바구니 내린다

conn.close(); //줄 푼다.

<전체 코드>

package Lecture.Week2;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;

public class Test15 {
    public static void main(String[] args) throws Exception{
        Class.forName("com.mysql.jdbc.Driver");
        /*Connection은 mysql에 소켓으로 접속하는 것과 관계가 깊음
        * study : 데이터베이스 명
        * root  / 1111 : 계정 및 암호
        * 127.0.0.1 : 네트워크 카드 밖으로 나가지 않고 나에게 접속할 때
        * Statement는 바구니라고 생각하면 된다. */
        Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/study","root","1111");
        //소켓을 이용해서 접속한다-> 줄 단다
        //db 연결

//        System.out.println(conn.toString());
            //connection 객체에 의해 프로그램에 리턴되는 객체에 의해 구현되는 일종의 메소드 집합
        Statement stmt = conn.createStatement();//바구니 건다
        String sql = "insert into studentt values ('10107', '또오치','쌍문동')";
        String sql2 = "delete from studentt where stid = '10107'";
        String sql3 = "update studentt set addr = '이도동' where stid = '10101'";

        stmt.executeUpdate(sql2);//쿼리 실행-> sql문 실어서 간다

        stmt.close(); //바구니 내린다
        conn.close(); //줄 푼다.

        /*Connection : IP, PORT, ID, PWD  -> 줄
        * Statement : SQL, 결과 -> 바구니
        * -> SQL로 -> RETURN 받아 -> STATEMENT.close() (바구니 먼저 내리고) -> CONNECTION.close() (줄 마지막으로 내리고)
        * executeUpdate : 함수의 리턴값은 변경된 레코드 개수 -> select는 레코드를 변경하지 않기 때문에 executeUpdate는 inser/delete/update문장에 사용한다
         */
 }
}

//java -classpath .;mysql-connector-java-5.0.8-bin.jar Test15
package Lecture.Week2;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class Test16 {
    public static void main(String[] args) throws Exception {
        /*static {
            //클래스가 로딩되는 시점에 호출

            /*connection , statement 모두 인터페이스다
            * DriverManager, getConnection 안에서 Connection 상속받은 모종의 클래스의 인스턴스를 리턴한다.
            * -> Mysql에 접속할 수 있는 기능을 구현하고 있다.        }*/

        Class.forName("com.mysql.jdbc.Driver"); //모종의 클래스 세팅하는 코드
        Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/study","root","1111");
//        System.out.println(conn.getClass().getName()); // conn이 어디 클래스에서 가져오나 찍어보는 것 -> com.mysql.jdbc.Connection
        Statement stmt = conn.createStatement(); //바구니 생성
//
        String sql = "select stid,name,addr from studentt";
        ResultSet rs = stmt.executeQuery(sql);

        while (rs.next()){
            String stid = rs.getString("stid");
            String name = rs.getString("name");
            String addr= rs.getString("addr");
            System.out.println(stid + "\t" + name +"\t" +addr);
        }
        rs.close();

        stmt.close();
        conn.close();

    }
}

///암기 하자

-select문에 정보들어가서 바구니에 담긴 걸 : CURSOR이라고 한다. -> 서버 쪽이라서 서버사이드 커서 

-쿼리에서 정보로 넘어갈 때 한 튜플을 채우고 그 밑으로 내려가면서 채운다 

Stid name
←   ↓
←   ↓
←   ↓
←   ↓

 

 

4. O-R Mapping 규칙(Golden Rule, Rule of Thumb)

  • ResultSet 은 CURSOR(select 결과)에 접근 가능한 정보
  • CURSOR는 서버에 생긴다
  • Connection 이 닫인 다음에서는 ResultSet은 사용 불가하다
    (Connection 닫기 전에 사용 끝나야 한다)
    -> connection은 비싼고 제한적인 지원이다
    -> 접속 후에 빨리 끊어주는게 바람직 하다 (콜 센터 연상)

<ArrayList 사용>

package Lecture.Week2;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

class StudentV0{
    /*property : 멤버 변수 -> public으로 열지 않는다.
    -> 대신에 getter , setter을 사용해 가져온다
    -> private 하게 선언 해야한다.*/
    private String stId = null;
    public String getStId(){ return stId;}
    public void setStId(String i){ stId = i;}

    private String name = null;
    public String getName(){ return name;}
    public void setName(String i){ name = i;}

    private String addr = null;
    public String getAddr(){ return addr;}
    public void setAddr(String i){ name = i;}
}




public class Test17{
    public static void main(String[] args) throws Exception {

        Class.forName("com.mysql.jdbc.Driver");
        Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/study","root","1111");
        Statement stmt = conn.createStatement(); //바구니 생성

        /*O-R Mapping 규칙(Golden Rule, Rule of Thumb)

        Field => property
        * table -> class
        * record => instance*/
        //connection은 살아있을때 할거 다해야 하고 / 빨리 끊어야한다 -> 아래 코드에서 이상적으로 구현

        //왜 arrayList 일까? -> 중간 삽입삭제가 필요없고 쌓기만 하는거니까 속도가 빠른 ArrayList
        //VO : Value Object : 값을 담는 객체
        /*테이블 구조와 동일하게 레코드 하나를 인스턴스에 담을 수 있는 역할
        *
        *  DTO : DATA TRANSFER OBJECT
        * Entity 등을 사용하는 경우도 있는데 실은 다 같은 얘기*/
        List<StudentV0> rl = new ArrayList<StudentV0>();

        String sql = "select stid,name,addr from studentt";
        ResultSet rs = stmt.executeQuery(sql);

        while (rs.next()){
            StudentV0 vo = new StudentV0(); //-> 하나의 인스턴스로 만들어 버림
            vo.setStId(rs.getString("stid"));
            vo.setName(rs.getString("name"));
            vo.setAddr(rs.getString("addr"));
            rl.add(vo);
        }
        rs.close();

        stmt.close();
        conn.close();
        //conn.close()이후에도 LIST 안에는 결과가 담겨 있다.
        for(StudentV0 vo : rl){
            System.out.println(vo.getStId() + "\t" + vo.getName() + "\t" + vo.getAddr());
        }
    }
}

<Oracle DB 연동>

package Lecture.Week2;

//import java.sql.Connection;
//import java.sql.DriverManager;
import java.sql.*;

public class Test18 {
    public static void main(String[] args) throws Exception {
        Class.forName("oracle.jdbc.driver.OracleDriver");
        Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521/XE","HR","HR");
        System.out.println(conn.getClass().getName());
        /*oracle.jdbc.driver.T4CConnection -> connection은 인터페이스 -> 모종의 클래스(T4C)를 상속받아 사용 -> 오로지 오라클에서만 사용가능
          2019-07-25 17:23:23.0

          MYSQL과 코드가 거의 틀린점이 없다
          Connection, Statement 를 상속한 ORACLE 과 연동 가능한 클래스를 OracleDriver에서 DriverManager에 세팅해주면 Oracle에 맞추어
          개발된 , Connection Statement ResultSet 등을 상속받은 클래스가 공급되는 구조
         */

        Statement stmt = conn.createStatement();
        //현재 시간 - MYSQL : now() / ORACLE : SYSDATE
        String sql = "SELECT SYSDATE FROM DUAL";
        ResultSet rs = stmt.executeQuery(sql);
        //결과 레코드가 하나인 경우에는 while 대신에 if문 사용한다.
        if (rs.next()){
            //필드명 대신에 숫자 가능 / 1은 나열된 펏번째 필드를 의미
            String l = rs.getString(1); //첫번째 필드 얘기
            System.out.println(l);
        }

        rs.close();
        stmt.close();

        conn.close();
    }
}

 

Day 5

  1. ORACLE
SQL> conn hr/hr;
연결되었습니다.
SQL> CREATE TABLE STUDY01t(
  2  ID NUMBER(3),
  3  DATA VARCHAR2(10)
  4  );
SQL> INSERT INTO STUDY01t VALUES (100, 'HelloWorld');

-오라클 숫자 : NUMBER(3) -최대 3자리 숫자

-VARCHAR2 : 오라클에서 만든 속도가 조금 빠른 VARCHAR

 

SQL> CREATE TABLE STUDY11t(
  2  ID NUMBER(5),
  3  DATA CHAR(10)
  4  );
SQL> CREATE SEQUENCE seq_study11t;

시퀀스가 생성되었습니다.
SQL> insert into study11t values(seq_study11t.NEXTVAL, 'apple');

-오라클은 mysql은 일련번호가 만드는 방법이 다르다

:mysql : auto_increment primary key를 썼다

 

SQL> SELECT ID, DATA || '*' FROM STUDY11t;
:mysql 의 concat과 동일한 기능을 수행한다.
//char여서 조금 더 떨어져 있음 (|| 공백처리)
//CHAR(10)으로 선언한 필드에 'apple'을 넣으면 'apple       '이 된다
//mysql은 그냥 'apple'이 된다

        ID DATA||'*'
---------- ----------------------
         1 apple     *
         2 apple     *
         3 apple     *
         4 apple     *
SQL> SELECT ID, TRIM(DATA) || '*' FROM STUDY11t;
//TRIM() : 좌/우 공백 문자를 제거하는 역할을 한다

        ID TRIM(DATA)||'*'
---------- ----------------------
         1 apple*
         2 apple*
         3 apple*
         4 apple*
SQL> CREATE TABLE Study12t(
  2  THE_TIME DATE
  3  );
SQL> INSERT INTO STUDY12t VALUES(SYSDATE);
SQL> SELECT * FROM STUDY12T;

THE_TIME
--------
19/07/26
SQL> SELECT TO_CHAR(THE_TIME) FROM STUDY12T;

TO_CHAR(THE_TIME
----------------
19/07/26
19/07/26
19/07/26

SQL> SELECT TO_CHAR(THE_TIME,'YYYY-MM-DD') FROM STUDY12T;

TO_CHAR(THE_TIME,'YY
--------------------
2019-07-26
2019-07-26
2019-07-26

//ORACLE 날짜 시간은 DATE자료형을 사용한다

//현재 시간은 SYSDATE를 이용한다

//보여지는 형식은 TO_CHAR을 이용하여 형식을 지정하면 된다.

 

SQL> SELECT TO_CHAR(THE_TIME,'YYYY-MM-DD HH24:MI:SS') FROM STUDY12T;

TO_CHAR(THE_TIME,'YYYY-MM-DDHH24:MI:SS
--------------------------------------
2019-07-26 11:52:54
2019-07-26 11:53:30
2019-07-26 11:53:32

Q. 역삼동 사는 학생들의 국어점수와 STID를 서브쿼리로?

SQL> SELECT * FROM SCORET WHERE STID IN (SELECT STID FROM STUDENTT WHERE ADDR LIKE '%역삼%') AND SUBID = 'KOR1';

STID       SUBID         SCORE
---------- -------- ----------
10101      KOR1             60
10103      KOR1             70

Q. 학생별 평균점수를 GROUP BY로 구하기(GROUP BY 에서 지정한 컬럼은 SELECT 절에서 쓸 수 있다)

 

SQL> SELECT STID, AVG(SCORE) FROM SCORET GROUP BY STID;

STID       AVG(SCORE)
---------- ----------
10104      73.3333333
10101      76.6666667
10102      93.3333333
10103      76.6666667
10105      63.3333333
10106      66.6666667

#INNER JOIN

SQL> SELECT * FROM STUDENTT INNER JOIN SCORET ON STUDENTT.STID = SCORET.STID; 
= SQL> SELECT * FROM STUDENTT, SCORET WHERE STUDENTT.STID = SCORET.STID; //조금 더 직관적


STID       NAME               ADDR               STID       SUBID         SCORE
---------- ------------------ ------------------ ---------- -------- ----------
10101      홍길동             역삼동             10101      KOR1             60
10101      홍길동             역삼동             10101      ENG1             80
10101      홍길동             역삼동             10101      MAT1             90
10102      고길동             개포동             10102      KOR1             90
10102      고길동             개포동             10102      MAT1             90
10102      고길동             개포동             10102      ENG1            100
10103      이기자             역삼동             10103      KOR1             70
10104      박기자             한남동             10104      KOR1             80
10105      김영삼             홍제동             10105      KOR1             50
10106      김대중             한남동             10106      KOR1             60
10103      이기자             역삼동             10103      ENG1             90

STID       NAME               ADDR               STID       SUBID         SCORE
---------- ------------------ ------------------ ---------- -------- ----------
10104      박기자             한남동             10104      ENG1             70
10105      김영삼             홍제동             10105      ENG1             60
10106      김대중             한남동             10106      ENG1             80
10103      이기자             역삼동             10103      MAT1             70
10104      박기자             한남동             10104      MAT1             70
10105      김영삼             홍제동             10105      MAT1             80
10106      김대중             한남동             10106      MAT1             60

# OUTER JOIN 

SQL> SELECT * FROM SUBJECTT LEFT OUTER JOIN SCORET
  2  ON SUBJECTT.SUBID = SCORET.SUBID;

SUBID    NAME               STID       SUBID         SCORE
-------- ------------------ ---------- -------- ----------
KOR1     국어1              10101      KOR1             60
ENG1     영어1              10101      ENG1             80
MAT1     수학1              10101      MAT1             90
KOR1     국어1              10102      KOR1             90
MAT1     수학1              10102      MAT1             90
ENG1     영어1              10102      ENG1            100
KOR1     국어1              10103      KOR1             70
KOR1     국어1              10104      KOR1             80
KOR1     국어1              10105      KOR1             50
KOR1     국어1              10106      KOR1             60
ENG1     영어1              10103      ENG1             90

SUBID    NAME               STID       SUBID         SCORE
-------- ------------------ ---------- -------- ----------
ENG1     영어1              10104      ENG1             70
ENG1     영어1              10105      ENG1             60
ENG1     영어1              10106      ENG1             80
MAT1     수학1              10103      MAT1             70
MAT1     수학1              10104      MAT1             70
MAT1     수학1              10105      MAT1             80
MAT1     수학1              10106      MAT1             60
PHY1     물리
SQL> SELECT * FROM SUBJECTT, SCORET
  2  WHERE SUBJECTT.SUBID = SCORET.SUBID(+);

SUBID    NAME               STID       SUBID         SCORE
-------- ------------------ ---------- -------- ----------
KOR1     국어1              10101      KOR1             60
ENG1     영어1              10101      ENG1             80
MAT1     수학1              10101      MAT1             90
KOR1     국어1              10102      KOR1             90
MAT1     수학1              10102      MAT1             90
ENG1     영어1              10102      ENG1            100
KOR1     국어1              10103      KOR1             70
KOR1     국어1              10104      KOR1             80
KOR1     국어1              10105      KOR1             50
KOR1     국어1              10106      KOR1             60
ENG1     영어1              10103      ENG1             90

SUBID    NAME               STID       SUBID         SCORE
-------- ------------------ ---------- -------- ----------
ENG1     영어1              10104      ENG1             70
ENG1     영어1              10105      ENG1             60
ENG1     영어1              10106      ENG1             80
MAT1     수학1              10103      MAT1             70
MAT1     수학1              10104      MAT1             70
MAT1     수학1              10105      MAT1             80
MAT1     수학1              10106      MAT1             60
PHY1     물리

-> 오라클용 아우터 조인 문법

-NULL 값으로 채워지는 일이 발생하는 쪽에 + 표시 붙인다.

 

-INNER JOIN ON , OUTER JOIN ON => 국제 표준 SQL

-각 DB별로 변형 SQL을 탑재 

-ORCLE 의 변형방법을 다른 DB 업체들이 따라하기도 하고 

-오라클만 쓴느 사람들은 오라클의 방법만 고집하는 경우가 많다

 

SQL> SELECT STID, AVG(SCORE) AS AVG FROM SCORET GROUP BY STID;

STID              AVG
---------- ----------
10104      73.3333333
10101      76.6666667
10102      93.3333333
10103      76.6666667
10105      63.3333333
10106      66.6666667
SQL> SELECT * FROM (SELECT STID, AVG(SCORE) AS AVG FROM SCORET GROUP BY STID);

STID              AVG
---------- ----------
10104      73.3333333
10101      76.6666667
10102      93.3333333
10103      76.6666667
10105      63.3333333
10106      66.6666667
SQL> SELECT X.STID, X.AVG FROM (SELECT STID, AVG(SCORE) AS AVG FROM SCORET GROUP BY STID) X; //테이블 별칭 줄때 AS를 사용하지 않는다.
//MYSQL에서는 쓰인다.


STID              AVG
---------- ----------
10104      73.3333333
10101      76.6666667
10102      93.3333333
10103      76.6666667
10105      63.3333333
10106      66.6666667
SQL>  SELECT x.stid, x.AVG FROM (
  2     SELECT stid, AVG( score ) AS AVG
  3     FROM scoret GROUP BY stid) x;

STID              AVG
---------- ----------
10104      73.3333333
10101      76.6666667
10102      93.3333333
10103      76.6666667
10105      63.3333333
10106      66.6666667

6 개의 행이 선택되었습니다.
SQL>  SELECT y.name, x.AVG FROM (
  2     SELECT stid, AVG( score ) AS AVG
  3     FROM scoret GROUP BY stid) x , studentt y WHERE x.stid = y.stid ;

NAME                      AVG
------------------ ----------
박기자             73.3333333
홍길동             76.6666667
고길동             93.3333333
이기자             76.6666667
김영삼             63.3333333
김대중             66.6666667

Constraint in Oracle

-primary key , foreign key, check, unique, not null

 

SQL> ALTER TABLE STUDENTT ADD CONSTRAINT PK_STUDENTT_STID PRIMARY KEY (STID);

테이블이 변경되었습니다.

-참조 무결성 : FK 쪽에는 PK에 없는 데이터는 존재하면 안된다

SQL> ALTER TABLE SCORET ADD CONSTRAINT FK_SCORET_STID
      2  FOREIGN KEY(STID) REFERENCES STUDENTT (STID);
SQL> DELETE FROM STUDENTT WHERE STID = '10101';
DELETE FROM STUDENTT WHERE STID = '10101'
*
1행에 오류:
ORA-02292: 무결성 제약조건(HR.FK_SCORET_STID)이 위배되었습니다- 자식 레코드가
발견되었습니다
SQL> ALTER TABLE SCORET ADD CONSTRAINT CH_SCORET_SCORE
  2  CHECK (SCORE >= 0 AND SCORE <= 100);

테이블이 변경되었습니다.

SQL> ALTER TABLE SUBJECTT ADD CONSTRAINT UQ_SUBJECT_SUBID
  2  UNIQUE (SUBID);

테이블이 변경되었습니다.
SQL> INSERT INTO SUBJECTT VALUES(NULL, '없음0');

-> NULL 값의 중복은 허용한다

SQL> INSERT INTO SUBJECTT VALUES('KOR1', '없음0');
INSERT INTO SUBJECTT VALUES('KOR1', '없음0')
*
1행에 오류:
ORA-00001: 무결성 제약 조건(HR.UQ_SUBJECT_SUBID)에 위배됩니다

왜? NOT NULL은 보장안함  / NO DUPLICATE 는 보장 

 

 권장사항 : constraint 는 테스트 끝나고서 ,,,,
         ( 회원가입 담당자가 일 다 안한 상태에서 게시판 담당자가 테스트 하려면? 절레절레)
 
-- constraint 지우기(제약 걸어있을 시 순서대로)

SQL> ALTER TABLE subjectt DROP CONSTRAINT uq_subject_subid;

테이블이 변경되었습니다.

SQL>
SQL> ALTER TABLE scoret DROP CONSTRAINT fk_scoret_stid;

테이블이 변경되었습니다.

SQL>
SQL> ALTER TABLE studentt DROP CONSTRAINT pk_studentt_stid;

 

-방명록 만들기

SQL> CREATE TABLE BANGMYUNG_T(
  2  NO INT,
  3  GUL VARCHAR2(100),
  4  THE_THIME DATE
  5  );

테이블이 생성되었습니다.

 


SQL> CREATE SEQUENCE SEQ_BANGMYUNG;

시퀀스가 생성되었습니다.
SQL> INSERT INTO BANGMYUNG_T VALUES(SEQ_BANGMYUNG.NEXTVAL, '만나서 반갑습니다', SYSDATE);

1 개의 행이 만들어졌습니다.

--MYSQL 

CREATE TABLE BANGMYUNG_T(

    NO INT AUTO_INCREMENT PRIMARY KEY,

    GUL VARCHAR(100),

    THE_TIME DATETIME

);

 

INSERT INTO BANGMYUNG_T VALUES (DAFAULT, '만나서 반갑습니다', NOW());

 

오라클 디비 JDBC

package Lecture.Week2;

import java.sql.*;

public class Test20 {
    public static void main(String[] args) throws Exception{
        Class.forName("oracle.jdbc.driver.OracleDriver");
        Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521/XE","HR","HR");
        System.out.println(conn.getClass().getName());

        Statement stmt = conn.createStatement();

        String gul = "HelloWorld";
        //String sql = "INSERT INTO BANGMYUNG_T VALUES" + "(SEQ_BANGMYUNG.NEXTVAL, '만나서 반갑습니다'" +" ,SYSDATE)";

        String sql = "INSERT INTO bangmyung_t VALUES " +
                "( seq_bangmyung.NEXTVAL, '" + gul +"'" +
                ", SYSDATE )";

        stmt.executeUpdate(sql);
        conn.close();
    }
}
package Lecture.Week2;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

class BangMyungV0{
    private Integer no = null;
    public void setNo (Integer i ){no = i;}
    public Integer getNo() {return no;}


    /*멤버 변수는 private 하게 선언하는게 바람직함
    * 멤버 변수는 오버라이딩 개념이 없다
    * 조상에서 생성된 변수는 자손에서 재 정의하는게 바람직하지 않다
    * 멤버 변수는 get, set으로 가져와야 한다. */
    private  String gul = null;
    public  void setGul(String i ){gul = i;}
    public String getGul() {return gul;}

    private String theTime = null;
    public void setTheTime(String i){theTime = i;}
    public String getTheTime(){return theTime;}
}


public class Test21 {
    public static void main(String[] args)throws Exception{
        Class.forName("oracle.jdbc.driver.OracleDriver");

        Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521/XE","HR","HR");
        Statement stmt = conn.createStatement();
        String sql = "select * from bangmyung_t";

        ResultSet rs = stmt.executeQuery(sql);

        List<BangMyungV0> ls = new ArrayList<BangMyungV0>();
        while(rs.next()){
            BangMyungV0 vo = new BangMyungV0();

            vo.setNo(rs.getInt("no"));
            vo.setGul(rs.getString("gul"));
            vo.setTheTime(rs.getString("THE_THIME"));

            ls.add(vo);
        }

        while (rs.next()){
            String no = rs.getString("no");
            String gul = rs.getString("gul");
            String THE_THIME = rs.getString("THE_THIME");

            System.out.println(no);
            System.out.println(gul);
            System.out.println(THE_THIME);
        }
        rs.close();

        stmt.close();
        conn.close();

        for(BangMyungV0 t: ls ){
            System.out.println(t.getNo() + "\t" + t.getGul() + "\t" + t.getTheTime()+"\t");
        }


    }
}

-함수로 선언해서 재사용성을 높였다 

SQL 문장에서 에러 -> stmt.executeUpdate(sql) 에서 예외발생 -> conn.close() 실행 안한다 -> conn은 빨리 끊어야한다. 

 

위의 내용을 왜 아래처럼 짤까? -> executeUpdate 상황에서 에러나도 conn.close()는 되어야 한다?

-> 되어야 한다. finally 영역 도입 시 try 영역에서 에러가 나건 안나건 무조건 실행한다. 

-> stmt.close() con.close()를 finally로 옮김

-> 변수 선언 정리

 

getConnection() 에서 에러나면? conn stmt 는 null 인채로 finally 행

stmt.close() conn.close()가 stmt, conn이 null 이 아닐 때만 호출하도록 개선했다.

 

-try -catch문 사용

package Lecture.Week2;

import java.sql.*;

class BangMyungV0{
    private Integer no = null;
    public void setNo (Integer i ){no = i;}
    public Integer getNo() {return no;}
    private  String gul = null;
    public  void setGul(String i ){gul = i;}
    public String getGul() {return gul;}

    private String theTime = null;
    public void setTheTime(String i){theTime = i;}
    public String getTheTime(){return theTime;}
}


public class Test21 {
    public static void addGul(String gul) throws Exception {
        Connection conn = null;
        Statement stmt = null;

        try{
            conn = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521/XE","HR","HR");

 String sql = "INSERT INTO bangmyung_t VALUES " +
                    "( seq_bangmyung.NEXTVAL, '" + gul +"'" +
                    ", SYSDATE )";
            stmt.executeUpdate(sql);
        }
        catch (Exception e){

        }finally { //try에서 에러가 나건 안나건 무조건 거친다.
            if (stmt != null) {stmt.close();}
            if(conn != null){conn.close();}
        }

public static void main(String[] args)throws Exception{
        Class.forName("oracle.jdbc.driver.OracleDriver");
        addGul("HelloWORLD");

트랜잭션 : 두 개 이상의 업데이트 문장을 하나처럼 묶어주는 작업 

-> LOG 에 쌓인 걸 한번에 반영하거나 버린다  

-> 동일한 CON에서 작업한 내용만 트랜잭션으로 묶을 수 있다. 

 

-비디오 가게에서의 예

대여 : INSERT
대여중 : 대여 기능에 들어가야함
예치금 --
대여중 -> 삭제
대여 기록 -> INSERT
연체금 -> 예치금에서 뺀다
대여중 -> 대여 가능
댓글 입력
댓글 수 ++ 

 

 

//autocommit

SQL> create table txt_tx(
  2  data int
  3  );
package Lecture.Week2;

import java.sql.DriverManager;
import java.sql.*;

/*conn을 통해서 executeUpdate를 하면 LOG를 거쳐 TABLE에 저장된다
* JDBC는 AUTOCOMMIT을 지원한다
* executeUpdate 시에 무조건 commit이 자동으로 먹는다
* 원래 커밋이 자동으로 먹게 되어있다. -> 로그에 잠시 머물다가 곧바로 커밋으로 올라감
* conn.setAutoCommit(false) // commit이 자동으로 먹지 않는다.*/

public class Test23 {
public static void main(String[] args) throws Exception{
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521/XE","HR","HR");

conn.setAutoCommit(false);

Statement stmt = conn.createStatement();
stmt.executeUpdate("insert into txt_tx values (101)");
stmt.executeUpdate("insert into txt_tx values (102)");
stmt.executeUpdate("insert into txt_tx values (103)");
stmt.executeUpdate("insert into txt_tx values (104)");

stmt.close();
conn.commit();//테이블에 올려버린다
// conn.rollback();//로그를 그냥 비운다 => 테이블에 반영이 안된다
conn.close();
}
}
SQL> select * from txt_tx;

      DATA
----------
       100
       101
       102
       103
       104
package Lecture.Week2;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;

public class Test23_2 {
        public static void main(String[] args) throws Exception{
            Class.forName("oracle.jdbc.driver.OracleDriver");
            Connection conn= null;
            Statement stmt = null;

//            conn.setAutoCommit(false); -> 있으면 롤백 에러 잡고 아니면 commit되서 올라감

            try{
                conn = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521/XE","HR","HR");

                stmt = conn.createStatement();
                stmt.executeUpdate("insert into txt_tx values (105)");
                stmt.executeUpdate("insert into txt_tx values (106)");
                stmt.executeUpdate("insert into txt_tx values (107)");
                stmt.executeUpdate("insert into txt_tx values (108)");

                conn.commit();//테이블에 올려버린다

                //에러가 나면 앞에있는 것도 몽땅 다 롤백

            }catch (Exception e){//try 에서 에러가 안나면 catch에서 안잡힘
                if(conn != null){ conn.rollback();}
                throw e;
            }finally {
                if(stmt != null) stmt.close();
                if(conn != null)conn.close();
            }
        }
    }


//향상된 코드 
반응형

'Language Study > Java' 카테고리의 다른 글

제주에서 자바_Week3_2  (0) 2019.07.30
제주에서 자바_Week3_1  (0) 2019.07.29
제주에서 자바_Week2_2  (0) 2019.07.24
제주에서 자바_Week2_1  (0) 2019.07.22
제주에서 자바_Week1  (0) 2019.07.20
반응형

Day 3

1. 데이터 베이스 설계 프로세스 

  1. 업무 분석
    • 명사, 동사 업무 정확하게 기술
    • 업무 파악에 도움되는 어떤 형태의 자료도 확보
    • 가능한 UI를 그려 가며 인터뷰 진행(설계에 결정적인 영향 끼침)
    • 경험이 중요
  2. 엔티티 도출 (Entity)
    • 추상 명사 중에서 PK로 구분되어지는 것이 Entity 가 된다
    • 기록될 만한 가치가 있는 정보인지 판별
    • PK : 단일 필드의 특징이 있어야 한다
      • Primary key (기본키)
        • 레코드를 구분하는 기준으로 사용되는 필드(들)
        • 예 ) 주민번호 , 사번, 군번,...
        • 주민번호처럼 두개의 필드가 결합해서 PK를 이룰 수도 있다
        • 3가지 성격
          • ND (NO DUPLICATE) : 중복되어서는 안된다
          • NN( NOT NULL) : 생략되어서는 안된다
          • NC (NO CHANGE) : 가급적 변경되어서는 안된다.
    • 엔티티 : ERD에서 사각형으로 표현
      • 예 ) 회원, 글, 과목, 학생
  3. 관계 도출(Relation) 
    • 엔티티들 사이에서 동사가 어울리게 존재 가능 -> 기록할 만한 가치가 있다면 그것이 관계
    • 예 ) 회원은 글을 쓴다(쓴다) - 학생은 과목을 수강한다(수강한다)
    • 3가지 종류
      • 1대1 대응 : Be 동사에 해당하는 관계 or 상속관계
        • ex) 사병은 군인이다 / 장교는 군인이다 / 군인은 군번을 구분된다
      • 1대다 대응 : 
        • 회원은 글을 쓴다.
      • 다대다 대응
        • 학생은 과목을 수강하고 -> 회원은 글을 읽는다 -> 추천한다
    • 관계의 물리적인 구현 방법
      • 일대일 대응 : 조상의 PK를 자손이 PK 이자 FK로 참조한다
      • 일대다 대응 : 다 쪽에서 일 쪽의 PK를 FK로 참조한다
      • 다대다 대응: 새로운 테이블 생성 -> 그 PK는 양쪽의 PK를 참조하는 FK를 결합하여 구성
  4. 속성(Attribute) 파악
    • 일반 명사 중 자료형과 값으로 표현될 수 있는 것들
      • 예) 성적, 글쓴 시간, 이름, 전화번호, 주소 ---
    • 엔티티 , Relation 에 1:1로 매핑하는 곳에 배치한다
    • 실제 구현시 필드에 해당
  5. ERD 구성
    • 2가지 종류 : 두가지 다 그릴 줄 알아야한다. 
      • 분석에 가까운 형태
      • 구현에 가까운 형태
    • 엔티티는 사각형, 관계는 마름모 
      관계는 화살표 OR 실선 (도착쪽이 PK)
      PK는 꽉찬 사탕 막대기 , 그 외 필드는 텅빈 사탕 막대기
      NOT NULL 필드는 굵은 글씨로 표기한다
    • 그릴때 용이한 많은 툴이 있다(유료)
      Microsoft Visio
    • 정규화 vs 비정규화
정규화 비정규화
More Table , Less Column Less Table, More Column
속도 느림 속도 빠름
테이블 구조 안정적 테이블 구조 자주 변경될 여지 O
자료 중복저장 허용 X(성적 있으면 등수 자동) 자료의 중복저장 허용O(속도를 위해 등수 필요)

=> 정규화를 중심으로 적절한 비정규화를 추구하는게 방향  / 경험이 가장 중요하다

ER 다이어그램 예시

6. FK (Foreign Key) :외래키

  • 다른 테이블의 PK로 쓰이는 필드를 내쪽에서 참조해서 쓰는 필드(들)
  • 성적 테이블에 stid , subid - 성적 테이블의 stid는 학생테이블에 쓰이는 의미를 가져다가 쓴다. "
    -> 성적테이블의 stid의 10101은 학생테이블 stid의 10101과 동일한 의미이다

7. 비디오 가게 만들기

비디오 가게 ER 다이어그램

8. 정규화

mysql> select stid, name, (kor1 + eng1 + mat1)/3 as avg from score2t;
+-------+-----------+---------+
| stid  | name      | avg     |
+-------+-----------+---------+
| 10101 | 홍길동    | 76.6667 |
| 10102 | 고길동    | 93.3333 |
| 10103 | 이기자    | 76.6667 |
| 10104 | 박기자    | 73.3333 |
| 10105 | 김영삼    | 63.3333 |
| 10106 | 김대중    | 66.6667 |
+-------+-----------+---------+
6 rows in set (0.00 sec)
  • 정규화
    • Less Column  : 테이블당 필드의 개수가 적다 - 5 ~ 12개
    • More Table : score2t 가 한개가 되는 걸 우리는 3개를 만들었다
    • 필드와 데이터의 중복 저장을 허용안한다(비디오점의 대여 여부) 
  • 비정규화 : More Column, Less Table 
    • 필드와 데이터의 중복 저장을 허용한다(속도 문제)

대부분 정규화를 기본으로 해서 적절한 비정규화를 도입한다.

#테이블의 껍데기만 만드는 것
mysql> create table student_xt as
    -> select stid, name, addr from score2t where 0 = 1;
Query OK, 0 rows affected (0.01 sec)
Records: 0  Duplicates: 0  Warnings: 0
#테이블에 select 결과를 입력하는 것mysql> insert into student_xt select stid, name, addr from score2t where 1 = 1;
Query OK, 6 rows affected (0.02 sec)
Records: 6  Duplicates: 0  Warnings: 0

mysql> select * from student_xt;
+-------+-----------+-----------+
| stid  | name      | addr      |
+-------+-----------+-----------+
| 10101 | 홍길동    | 역삼동    |
| 10102 | 고길동    | 개포동    |
| 10103 | 이기자    | 역삼동    |
| 10104 | 박기자    | 한남동    |
| 10105 | 김영삼    | 홍제동    |
| 10106 | 김대중    | 한남동    |
+-------+-----------+-----------+
6 rows in set (0.02 sec)

 

#score_xt //하나도 흘리지 않고 새로운 테이블에 옮겨갈 때

mysql> create table score_xt as
    -> select stid, 'KOR1' as subid, kor1 as score from score2t where 0 =1;
Query OK, 0 rows affected (0.23 sec)
Records: 0  Duplicates: 0  Warnings: 0
mysql> insert into score_xt select stid, 'KOR1', kor1 as score from score2t where 1= 1;
Query OK, 6 rows affected (0.00 sec)
Records: 6  Duplicates: 0  Warnings: 0

mysql> insert into score_xt
    -> select stid, 'ENG1', eng1 as score from score2t where 1=1;
Query OK, 6 rows affected (0.00 sec)
Records: 6  Duplicates: 0  Warnings: 0

mysql> insert into score_xt
    -> select stid, 'MAT1', mat1 as score from score2t where 1=1;
Query OK, 6 rows affected (0.00 sec)
Records: 6  Duplicates: 0  Warnings: 0
mysql> select * from score_xt;
+-------+-------+-------+
| stid  | subid | score |
+-------+-------+-------+
| 10101 | KOR1  |    60 |
| 10102 | KOR1  |    90 |
| 10103 | KOR1  |    70 |
| 10104 | KOR1  |    80 |
| 10105 | KOR1  |    50 |
| 10106 | KOR1  |    60 |
| 10101 | ENG1  |    80 |
| 10102 | ENG1  |    90 |
| 10103 | ENG1  |    90 |
| 10104 | ENG1  |    70 |
| 10105 | ENG1  |    60 |
| 10106 | ENG1  |    80 |
| 10101 | MAT1  |    90 |
| 10102 | MAT1  |   100 |
| 10103 | MAT1  |    70 |
| 10104 | MAT1  |    70 |
| 10105 | MAT1  |    80 |
| 10106 | MAT1  |    60 |
+-------+-------+-------+
18 rows in set (0.00 sec)

#비정규화 된 설계에서 정규화 된 설계로 옮길 수도 있고

정규화된 설계에서 비정규화 된 설계로 옮길 수도 있어야 한다. 

 

9. JOIN -> 서브쿼리와 유사

studentt : stid (pk) <- scoret : stid(fk)

 

-대부분의 join은 pk - fk 사이에서 일어난다 

 

mysql>select * from studentt INNER JOIN scoret ON studentt.stid = scoret.stid;
//studentt에 있는 pk(stid)를 참조 받아 두 테이블을 조인시킴
+-------+-----------+-----------+-------+-------+-------+
| stId  | name      | addr      | stId  | subId | score |
+-------+-----------+-----------+-------+-------+-------+
| 10101 | 홍길동    | 역삼동    | 10101 | KOR1  |   100 |
| 10101 | 홍길동    | 역삼동    | 10101 | ENG1  |   100 |
| 10101 | 홍길동    | 역삼동    | 10101 | MAT1  |   100 |
| 10102 | 고길동    | 개포동    | 10102 | KOR1  |    90 |
| 10102 | 고길동    | 개포동    | 10102 | MAT1  |    90 |
| 10102 | 고길동    | 개포동    | 10102 | ENG1  |   100 |
| 10103 | 이기자    | 역삼동    | 10103 | KOR1  |    70 |
| 10104 | 박기자    | 한남동    | 10104 | KOR1  |    80 |
| 10105 | 김영삼    | 홍제동    | 10105 | KOR1  |    50 |
| 10106 | 김대중    | 한남동    | 10106 | KOR1  |    60 |
| 10103 | 이기자    | 역삼동    | 10103 | ENG1  |    90 |
| 10104 | 박기자    | 한남동    | 10104 | ENG1  |    70 |
| 10105 | 김영삼    | 홍제동    | 10105 | ENG1  |    60 |
| 10106 | 김대중    | 한남동    | 10106 | ENG1  |    80 |
| 10103 | 이기자    | 역삼동    | 10103 | MAT1  |    70 |
| 10104 | 박기자    | 한남동    | 10104 | MAT1  |    70 |
| 10105 | 김영삼    | 홍제동    | 10105 | MAT1  |    80 |
| 10106 | 김대중    | 한남동    | 10106 | MAT1  |    60 |
+-------+-----------+-----------+-------+-------+-------+

- INNER JOIN : PK - FK 데이터가 일치하는 레코드를 짜매준다. 

 mysql>SELECT name, addr, score From studentt INNER JOIN scoret ON studentt.stid = scoret.stid WHERE subid = 'MAT1';
//join을 이용하면 흩어진 데이터를 통합해서 보여지게 할 수 있다 (서브 쿼리도 가능 , 헌대 성능이 틀리다) 
-> 해서 같은 결과를 만들되 성능이 향상되게 만드는 것이 SQL 튜닝의 영역
Q. subjectt , scoret를 inner join해서 10101 국어1 90..이런식으로 나오게
mysql> select stid,name,score from subjectt INNER JOIN scoret ON subjectt.subid = scoret.subid;

+-------+---------+-------+
| stid  | name    | score |
+-------+---------+-------+
| 10101 | 국어1   |   100 |
| 10101 | 영어1   |   100 |
| 10101 | 수학1   |   100 |
| 10102 | 국어1   |    90 |
| 10102 | 수학1   |    90 |
| 10102 | 영어1   |   100 |
| 10103 | 국어1   |    70 |
| 10104 | 국어1   |    80 |
| 10105 | 국어1   |    50 |
| 10106 | 국어1   |    60 |
| 10103 | 영어1   |    90 |
| 10104 | 영어1   |    70 |
| 10105 | 영어1   |    60 |
| 10106 | 영어1   |    80 |
| 10103 | 수학1   |    70 |
| 10104 | 수학1   |    70 |
| 10105 | 수학1   |    80 |
| 10106 | 수학1   |    60 |
+-------+---------+-------+
18 rows in set (0.00 sec)
mysql> select stid,name,score, subjectt.subid from subjectt INNER JOIN scoret ON subjectt.subid = scoret.subid;
//같은이름의 subid 가져오려면 어디서 가져와야하는지 명시 해야한다.
+-------+---------+-------+-------+
| stid  | name    | score | subid |
+-------+---------+-------+-------+
| 10101 | 국어1   |   100 | KOR1  |
| 10101 | 영어1   |   100 | ENG1  |
| 10101 | 수학1   |   100 | MAT1  |
| 10102 | 국어1   |    90 | KOR1  |
| 10102 | 수학1   |    90 | MAT1  |
| 10102 | 영어1   |   100 | ENG1  |
| 10103 | 국어1   |    70 | KOR1  |
| 10104 | 국어1   |    80 | KOR1  |
| 10105 | 국어1   |    50 | KOR1  |
| 10106 | 국어1   |    60 | KOR1  |
| 10103 | 영어1   |    90 | ENG1  |
| 10104 | 영어1   |    70 | ENG1  |
| 10105 | 영어1   |    60 | ENG1  |
| 10106 | 영어1   |    80 | ENG1  |
| 10103 | 수학1   |    70 | MAT1  |
| 10104 | 수학1   |    70 | MAT1  |
| 10105 | 수학1   |    80 | MAT1  |
| 10106 | 수학1   |    60 | MAT1  |
+-------+---------+-------+-------+

 

//subjectt -> y로 scoret -> x로 각각 줄여서 쓰면 이렇게 가능

mysql> select stid, name, score, y.subid FROM scoret as x INNER JOIN subjectt as y ON y.subid = x.subid;
+-------+---------+-------+-------+
| stid  | name    | score | subid |
+-------+---------+-------+-------+
| 10101 | 국어1   |   100 | KOR1  |
| 10101 | 영어1   |   100 | ENG1  |
| 10101 | 수학1   |   100 | MAT1  |
| 10102 | 국어1   |    90 | KOR1  |
| 10102 | 수학1   |    90 | MAT1  |
| 10102 | 영어1   |   100 | ENG1  |
| 10103 | 국어1   |    70 | KOR1  |
| 10104 | 국어1   |    80 | KOR1  |
| 10105 | 국어1   |    50 | KOR1  |
| 10106 | 국어1   |    60 | KOR1  |
| 10103 | 영어1   |    90 | ENG1  |
| 10104 | 영어1   |    70 | ENG1  |
| 10105 | 영어1   |    60 | ENG1  |
| 10106 | 영어1   |    80 | ENG1  |
| 10103 | 수학1   |    70 | MAT1  |
| 10104 | 수학1   |    70 | MAT1  |
| 10105 | 수학1   |    80 | MAT1  |
| 10106 | 수학1   |    60 | MAT1  |
+-------+---------+-------+-------+
18 rows in set (0.00 sec)
mysql> SELECT stid, avg(score) as avg FROM scoret group by stid;
+-------+----------+
| stid  | avg      |
+-------+----------+
| 10101 | 100.0000 |
| 10102 |  93.3333 |
| 10103 |  76.6667 |
| 10104 |  73.3333 |
| 10105 |  63.3333 |
| 10106 |  66.6667 |
+-------+----------+
6 rows in set (0.00 sec)

//서브쿼리를 사용해 JOIN 할 수 있다.

mysql> SELECT * from (SELECT stid, avg(score) as avg FROM scoret group by stid) AS x INNER JOIN studentt AS y ON y.stid = x.stid;
+-------+----------+-------+-----------+-----------+
| stid  | avg      | stId  | name      | addr      |
+-------+----------+-------+-----------+-----------+
| 10101 | 100.0000 | 10101 | 홍길동    | 역삼동    |
| 10102 |  93.3333 | 10102 | 고길동    | 개포동    |
| 10103 |  76.6667 | 10103 | 이기자    | 역삼동    |
| 10104 |  73.3333 | 10104 | 박기자    | 한남동    |
| 10105 |  63.3333 | 10105 | 김영삼    | 홍제동    |
| 10106 |  66.6667 | 10106 | 김대중    | 한남동    |
+-------+----------+-------+-----------+-----------+
6 rows in set (0.00 sec)

10. 외부조인(OUTER JOIN)

mysql> SELECT * FROM subjectt INNER JOIN scoret ON subjectt.subid = scoret.subid;
//일단 subjectt 와 scoret를 조인
+-------+---------+-------+-------+-------+
| subId | name    | stId  | subId | score |
+-------+---------+-------+-------+-------+
| KOR1  | 국어1   | 10101 | KOR1  |   100 |
| ENG1  | 영어1   | 10101 | ENG1  |   100 |
| MAT1  | 수학1   | 10101 | MAT1  |   100 |
| KOR1  | 국어1   | 10102 | KOR1  |    90 |
| MAT1  | 수학1   | 10102 | MAT1  |    90 |
| ENG1  | 영어1   | 10102 | ENG1  |   100 |
| KOR1  | 국어1   | 10103 | KOR1  |    70 |
| KOR1  | 국어1   | 10104 | KOR1  |    80 |
| KOR1  | 국어1   | 10105 | KOR1  |    50 |
| KOR1  | 국어1   | 10106 | KOR1  |    60 |
| ENG1  | 영어1   | 10103 | ENG1  |    90 |
| ENG1  | 영어1   | 10104 | ENG1  |    70 |
| ENG1  | 영어1   | 10105 | ENG1  |    60 |
| ENG1  | 영어1   | 10106 | ENG1  |    80 |
| MAT1  | 수학1   | 10103 | MAT1  |    70 |
| MAT1  | 수학1   | 10104 | MAT1  |    70 |
| MAT1  | 수학1   | 10105 | MAT1  |    80 |
| MAT1  | 수학1   | 10106 | MAT1  |    60 |
+-------+---------+-------+-------+-------+
18 rows in set (0.00 sec)
mysql> INSERT INTO subjectt values('PHY1', '물리');

//이렇게 물리가 추가 된다고 해도 성적데이터가 없으니 짜매어줄 대상이 없다

//회원가입이 되어도 글 쓴게 없으면 조인 걸어도 나타나지 않는다

//-> 한쪽 테이블에서만 보여지고 짜매지지 않는 경우라도 한 건 보여지게 만드는 형태의 조인이 OUTER JOIN이다

// 부족함(NULL 로 채움) 이 나타나는 반대편을 명시한다(LEFT)

mysql> SELECT * FROM subjectt LEFT OUTER JOIN scoret ON subjectt.subid = scoret.subid;
+-------+---------+-------+-------+-------+
| subId | name    | stId  | subId | score |
+-------+---------+-------+-------+-------+
| KOR1  | 국어1   | 10101 | KOR1  |   100 |
| ENG1  | 영어1   | 10101 | ENG1  |   100 |
| MAT1  | 수학1   | 10101 | MAT1  |   100 |
| KOR1  | 국어1   | 10102 | KOR1  |    90 |
| MAT1  | 수학1   | 10102 | MAT1  |    90 |
| ENG1  | 영어1   | 10102 | ENG1  |   100 |
| KOR1  | 국어1   | 10103 | KOR1  |    70 |
| KOR1  | 국어1   | 10104 | KOR1  |    80 |
| KOR1  | 국어1   | 10105 | KOR1  |    50 |
| KOR1  | 국어1   | 10106 | KOR1  |    60 |
| ENG1  | 영어1   | 10103 | ENG1  |    90 |
| ENG1  | 영어1   | 10104 | ENG1  |    70 |
| ENG1  | 영어1   | 10105 | ENG1  |    60 |
| ENG1  | 영어1   | 10106 | ENG1  |    80 |
| MAT1  | 수학1   | 10103 | MAT1  |    70 |
| MAT1  | 수학1   | 10104 | MAT1  |    70 |
| MAT1  | 수학1   | 10105 | MAT1  |    80 |
| MAT1  | 수학1   | 10106 | MAT1  |    60 |
| PHY1  | 물리    | NULL  | NULL  |  NULL |
+-------+---------+-------+-------+-------+
19 rows in set (0.00 sec)

//count(*) 는 레코드의 갯수를 센다. 

//count(score) 은 해당 필드의 null 이 아닌 데이터의 갯수를 센다

mysql> SELECT subjectt.subid, count(score) FROM subjectt LEFT OUTER JOIN scoret ON subjectt.subid = scoret.subid GROUP BY subjectt.subid;
+-------+--------------+
| subid | count(score) |
+-------+--------------+
| ENG1  |            6 |
| KOR1  |            6 |
| MAT1  |            6 |
| PHY1  |            0 |
+-------+--------------+
4 rows in set (0.00 sec)

11. CONSTRAINT - 물리적인 제약 조건을 필드에 걸어준다 

-> 제약 조건 : CHECK, UNIQUE, PRIMARY KEY, FOREIGN KEY 4가지를 주로 쓴다 .

 

-> score 값을 (0 - 100) 사이의 값만 허용해야한다

mysql>ALTER TABLE scoret ADD CONSTRAINT CHECK_scoret_score CHECK (score >= 0 AND score <= 100);
mysql>insert into scoret valus ('10101', 'PHY1', 80);
ERROR 1264 (22003): Out of range value for column 'score' at row 1

 

지울떄는

mysql>ALTER TABLE scoret DROP CONSTRAINT CHECH_scoret_score;

 

-CHECK CONSTRAINT 는 WHERE 절의 조건을 이용하여 제약을 걸 수 있다. 

(IN, NOT IN, = != ... 을 사용할 수 있다

mysql> ALTER TABLE subjectt ADD CONSTRAINT PK_subjectt_subid
    -> PRIMARY KEY(subid);
Query OK, 0 rows affected (0.03 sec)
Records: 0  Duplicates: 0  Warnings: 0

mysql> INSERT INTO subjectt VALUES('KOR1','국어');
ERROR 1062 (23000): Duplicate entry 'KOR1' for key 'PRIMARY'

-참조 무결성 : PK 쪽에서 쓰여진 데이터만 FK 쪽에서 쓰여질 수 있다

  • 회원 가입 해야 글 쓴다
  • 회원 등록 해야 예약한다
  • 등록된 아이템만 대여 가능하다 ...

#PRIMARY (subjectt) 쓰인적 있기 때문에 -> FOREIGN KEY부분에서 잘 쓸 수 있음

mysql> ALTER TABLE scoret ADD CONSTRAINT FX_scoret_subid
    -> FOREIGN KEY(subid) REFERENCES subjectt(subid);
Query OK, 20 rows affected (0.05 sec)
Records: 20  Duplicates: 0  Warnings: 0

mysql> INSERT INTO scoret VALUES ('10101', 'XXXX', 50);
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint fails (`study`.`scoret`, CONSTRAINT `FX_scoret_subid` FOREIGN KEY (`subId`) REFERENCES `subjectt` (`subId`))

 

12. UNIQUE CONSTRAINT  : NULL 허용하는데 중복은 안된다 -> 테이블 분리할 때 사용

다대다로 만들고 -> UNIQUE 걸어서 -> 일대일처럼 동작

 

mysql> create table study05t(
    -> id int not null
    -> );
Query OK, 0 rows affected (0.02 sec)
mysql> ALTER TABLE study05t ADD CONSTRAINT UQ_study05t_id UNIQUE(id);
Query OK, 0 rows affected (0.03 sec)
Records: 0  Duplicates: 0  Warnings: 0

#일대일 상황에서 테이블 분리하는 방법 

-일단 다대다로 생각하고 테이블을 생성한다

-pk 중 하나에 unique constraint를 건다

-> 다대다 => 일대일로 바뀐다 .

 

#constraint 지우는 법

mysql> ALTER TABLE study05t DROP INDEX UQ_study05t_id;
Query OK, 1 row affected (0.04 sec)
Records: 1  Duplicates: 0  Warnings: 0

문제

짜장면집 결제 DB

중요한 핵심

반응형

'Language Study > Java' 카테고리의 다른 글

제주에서 자바_Week3_1  (0) 2019.07.29
제주에서 자바_Week2_3  (0) 2019.07.25
제주에서 자바_Week2_1  (0) 2019.07.22
제주에서 자바_Week1  (0) 2019.07.20
4. 클래스  (0) 2019.05.29
반응형
# https://coding-factory.tistory.com/ 에서 그림 인용 

Day 1

1. 입력스트립(Input Stream) & 출력 스트림(Output Stream) 

- 자바 데이터는 스트림(Stream) 통해 입출력.

-스트림 ; 단일방향으로 연속적으로 흘러가는 것 

    => 순서대로 읽고, 순서대로 내보냄 / byte 단위로 전송

-프로그램 기준 데이터가 들어오면 입력 스트림 , 데이터가 나가면 출력 스트림

프로그램 기준 스트림

-Java.io 패키지 : 파일 시스템의 정보를 얻기 위한 file 클래스와 데이터 입출력하기 위한 다양한 입출력 스트림 클래스 제공

 Java.io 패키지의 주요 클래스

설명 

 File

 파일 시스템의 파일 정보를 얻기 위한 클래스 

 Console 

 콘솔로부터 문자를 입출력하기 위한 클래스 

 InputStream / OutputStream

 바이트 단위 입출력을 위한 최상위 입출력 스트림 클래스 

 FileInputStream / FileOuputStream

 바이트 단위 입출력을 위한 하위 스트림 클래스

 DataInputStream / DataOutputStream

 ObjectInputStream / ObjectOutputStream

 PrintStream

 BufferedInputStream / BufferedOutputStream

 Reader / Writer

 문자 단위 입출력을 위한 최상위 입출력 스트림 클래스

 FileReader / FileWriter

 문자 단위 입출력을 위한 하위 스트림 클래스

 InputStreamReader / OutputStreamWriter

 PrintWriter

 BufferedReader / BufferedWriter

 

  • 바이트 단위 입출력 스트림 : 그림, 멀티미디어, 문자 등 모든 종류의 데이터들 주고 받음
  • 문자 단위 입출력 스트림 : 오로지 문자만 주고 받을 수 있게 함

-inputStream : 바이트 기반 입력 스트림의 최상위 클래스(추상 클래스)

  • 모든 바이트 기반 입력 스트림은 이 클래스를 상속받아 만들어짐
  • FileInputStream
  • BufferedInputStream
  • DataInputStream

 메서드

설명 

 read()

입력 스트림으로부터 1바이트를 읽고 읽은 바이트를 리턴합니다. 

 read(byte[ ] b)

 입력 스트림으로부터 읽은 바이트들을 매개값으로 주어진 바이트 배열b에 저장하고 실제로 읽은 바이트 수를 리턴합니다.

 read(byte[] b, int off, int len)

입력 스트림으로부터 len개의 바이트만큼 읽고 매개값으로 주어진 바이트 배열 b[off]부터 len개까지 저장합니다. 그리고 실제로 읽은 바이트 수인 len개를 리턴합니다. 만약 len개를 모두 읽지 못하면 실제로 읽은 바이트 수를 리턴합니다. 

 close()

사용한 시스템 자원을 반납하고 입력스트림을 닫습니다. 

 

-OutputStream : 바이트 기반 출력 스트림의 최상위 클래스(추상 클래스) / 모든 바이트 기반 출력 스트림 클래스는 이 클래스를 상속받아 만들어짐

  • FileOutputStream : 파일에 저장하는 방법 제공
  • PrintStream
  • BufferedOutputStream
  • DataOutputStream

 메서드

설명 

 write(int b)

 출력 스트림으로부터 1바이트를 보냅니다.(b의 끝 1바이트) 

 write(byte[ ] b)

 출력 스트림으로부터 주어진 바이트 배열 b의 모든 바이트를 보냅니다.

 write(byte[ ] b, int off, int len)

 출력 스트림으로 주어진 바이트 배열 b[off]부터 len개까지의 바이트를 보냅니다. 

 flush() 

 버퍼에 잔류하는 모든 바이트를 출력합니다. 

 close()

 사용한 시스템 자원을 반납하고 출력 스트림을 닫습니다. 
package Lecture.Week2;

import java.io.*;

public class Test04 {
    public static void main(String[] args) throws IOException {
        InputStream in = new FileInputStream("a.dat" );
        OutputStream out = new FileOutputStream("b.dat");

        //복사 : dir *.dat 로 확인하고 type b.dat로 확인하고..
//        while(true){
//            int r = in.read();
//            if(r == -1){//더이상 읽을 것이 없을 때
//                break;
//            }
//            out.write(r);
//        }
//        out.close();
//        in.close();


        //엄청 많이 씀 -> 외우세용
        int r = 0;
        byte[] buf= new byte[1024*8];
        while(( r = in.read(buf)) != -1 ){// 더 읽을게 남아있다.
            out.write(buf, 0, r);
        }
        out.close();
        in.close();
    }
}

 

이를 데코레이터 패턴으로 이해하면 

-> out 이 가리키는 대상은
FileOutputStream("d.dat")에 저장하되
ObjectOutputStream 에서 제공하는 방법을 사용하게 된다.

ObjectOutputStream 은 writeInt writeDouble writeUTF 등을 제공
-> 전송 시에 안깨진다.
* ObjectOutputStream 은 writeInt WriteDouble writeUTF 등을 제공 -> 전송

 

*OutputStream InputStream : 전송단위 byte
* Reader Writer : 전송단위 char : 문자로 된 데이터 전송용

* char : 2바이트 , 유니코드 지원
* 유니코드 : 모든 글자를 다 포용하지 못한다
* -웬만한 건 글자는 포용한다 , 한글 영문 중국어 아랍어 일본어
* 확장 가능한 가변 길이를 가지는 문자체제 도입 UTF - 8.

*OutputStreamWriter InputStreamReader 는 char 입출력을 byte 입출력으로 전환해 줍니다
* 2byte -> 1byte로 바꿔줌*

 

 

 

 2. 자바 네트워크에 대한 이해

  • 네트워크란?
    • 다른 장치로 데이터를 이동시킬 수 있는 컴퓨터들 , 주변 장치들의 집합
    • 네트워크의 연결된 모든 장치들을 노드라고 한다
    • 복잡한 레이어의 대표적인 모델이 OSI 7계층
    • TCP / IP 모델 사용
  • IP 주소
    • 모든 호스트는 인터넷 주소(Host, IP 주소) 라 불리는 유일한 32비트 숫자로 구성된 주소 체계 이용
    • 32비트의 주소 체계를 IPv4 주소라고한다 -> 극복 IPv6
    • IP주소를 도메인이름으로 바꾸어 주는 시스템  : DNS
  • 포트 & 프로토콜
    • 포트 
      • 물리적 포트 
      • 논리적 포트
    • 프로토콜
      • 클라이언트와 서버간의 통신 규약
      • TCP / UDP
  • TCP / UDP
    • TCP / IP계층 모델은 4계층 구조(애플리케이션, 전송, 네트워크, 데이터 링크 계층)
    • 전송 계층에서 사용하는 프로토콜 TCP / UDP 
      • TCP (transmission Control Protocol) : 신뢰할 수 있는 프로토콜 / 데이터 상대 측까지 제대로 전달되었는지 확인 메시지를 주고 받음으로써 데이터의 송수신 상태를 점검
      • UDP(user datagram protocol) : 신뢰할 수 없는 프로토콜 / 데이터 보내기만 하고 제대로 전달되었는지 확인 하지 않음

3. TCP 통신 / Socket 프로그래밍

  • TCP 통신 방식 : 소켓 프로그래밍의 하나 / 스트림 통신 프로토콜 / 양쪽 소켓이 연결 상태여야만 가능 -> 연결 지향 프로토콜
    • 수신,  송신 측이 미리 연결 맺고 연결된 순서대로 데이터 교환해야함
    • Java.net 패키지에 관련 클래스들 미리 준비 해놓음
  • 소켓? 
    • 네트워크 끝 부분 / 실제 데이터가 어떻게 전송되는 지 상관하지 않고 read/write 인터페이스 제공
    • 네트워크 계층과 전송 계층이 캡슐화
    • TCP / IP 계층의 TCP를 지원하기 위해 Socket, ServerSocket 클래스 제공
    • 클라이언트 : socket 객체 생성, tcp 서버와 연결 시도
    • 서버 : SocketServer 객체 생성 , TCP 연결을 청취하여 클라이언트와 서버 연결
  • 소켓 스트림 

  • TCP 소켓은 java.net.Socket 클래스 의미
    • Socket 클래스 생성자
      • 예외 처리 2개
        • 호스트를 찾을 수 없거나, 서버의 포트가 열려있지 않는 경우 (UnknownHostException 예외) 발생
        • 네트워크 실패, 방화벽 때문에 서버 접근 할 수 없을 때 (IOException 예외) 발생
생성자 설명
Socket(Inet(Address address, int port) InetAdderss 객체와 port 이용하여 socket 객체를 생성한다
Socket(String host, int port)  host, port를 이용하여 socket객체를 생성한다.
  • Socket 클래스의 주요 메서드 
반환형 메서드 설명
void close() 소켓 객체를 닫는다
InetAddress getInetAddress() 소켓 객체를 InetAddress 객체로 반환한다
InputStream getInputStream() 소켓 객체로부터 입력할 수 있는 InputStream 객체를 반환한다
InetAddress getLocalAddress() 소켓 객체의 로컬 주소를 반환한다.
int getPort() 소켓 객체의 포트를 반환한다
boolean isClosed() 소켓 닫혀있으면 true, 아니면 false 반환
isConnected() 소켓 객체가 연결되어 있으면 true, 연결되어 있지 않으면 false를 반환
void setSoTimeout(int timeout) 소켓 객체의 시간을 밀리 세컨드로 설정
  • 소켓 이용한 입출력 스트림 생성
    • 두 개의 네트워크 사이에서 바이트 스트림 통신 제공
    • 바이트를 읽기 위한 메서드와 쓰기 위한 메서드 제공
    • 두 가지 메서드를 이용하여 클라이언트와 서버간에 통신할 수 있다.
java.io.InputStream getInputStream() throws IOException; 
java.io.OutputStream getOutputStream() throws IOException;

Socket socket = new Socket(“211.238.132.50”,4000); 
InputStream in = socket.getIputStream(); 
OutputStream os = socket.getOutputStream();
  • 소켓 정보 : 로컬 ip주소와 포트를 알 수 있는 메서드와 socket 으로 연결된 호스트의 ip 주소와 포트를 알 수 있는 메서드 제공
  • TCP Server Socket
    • 클라이언트의 TCP 연결을 받기 위해서 java.net.ServerSocket 클래스의 객체를 생성
    • ServerSocket 클래슨느 네트워크 통신을 수행하기 위해 자신을 바로 사용 X 
      -> 클라이언트의 TCP 요청에 대한 Socket 객체를 생성하는것 
    • accept() 메서드 : 클라이언트의 TCP 요청 있을 때 까지 블로킹되는 메서드
    • 클라이언트 TCP 요청 -> ACCEPT 메서드-> TCP 소켓 반환
    • 일반적으로 accept() 메서드는 무한루프 처리하게 됨
    • ServerSocket 클래스의 생성자
      • 기존의 tcp 포트 번호가 사용중이라면 IOException 발생
생성자  설명
ServerSocket(int port) port 이용하여 ServerSocket 객체 생성
  • ServerSocket 클래스 주요 메서드 
    • accept() 가 제일 중요
반환형 메서드 설명
Socket accept() 클라이언트의 소켓 객체가 생성되면 서버가 클라이언트와 통신할 수 있는 소켓 객체를 반환
void close() 서버소켓 객체 닫음
int getLocalPort() 서버소켓 객체가 청취하고 있는 포트번호 반환
getSoTimeout() 서버소켓 클래스의 accept() 메서드가 유효할 수 있는 밀리 세컨드로 반환
boolean isClosed() 서버 소켓 객체의 닫힌 상태를 반환
void setSoTimeout(int timeout) 서버 소켓 클래스의 accept() 메서드가 유효할 수 있는 시간을 밀리 세컨드로 설정
package Lecture.Week2;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
//서버

/*대기 하는 쪽 : 서버
* 찾아 가는 쪽 : 클라이언트
* 먼저 서버가 구동한다. => 포트번호로 묶고 구동해야한다.(1123)
* accept : 대기하다가 클라이언트가 찾아오면 소켓을 생성해서 리턴
* 클라이언트가 찾아가기 위해 ?ip, port번호
* 잘 찾아가면 소켓 생성
* 속 성공 시 두 소켓은 전혀 다른 것이지만 서로 통신할 수 있게 된다. */
public class Test06S {
    public  static void main(String[] args) throws Exception{
        ServerSocket svr = new ServerSocket(1123);
        System.out.println("before accept");

        Socket skt = svr.accept();
        System.out.println("after accept");

        InputStream in = new FileInputStream("a.txt");
        OutputStream out = skt.getOutputStream();

        int r = 0;
        while(( r = in.read()) != -1 ) {
            out.write(r);
            out.flush();//소켓으로 넘어가야함
        }

        out.close();
        in.close();


        System.out.println(r);
        out = new FileOutputStream("copy.txt");
        in = skt.getInputStream();
        r = 0;
        while((r = in.read())!= -1){
            out.write(r);
        }
        skt.close();

        svr.close();
    }
}

서버 & 서버 소켓 이용한 간단한 에코 프로그램

4. 예외 처리 (try - catch) : 사용자의 잘못된 조작, 개발자의 잘못된 코딩으로 인해 발생하는 프로그램 오류

 예외 구문

이유 

ArithmeticException

정수를 0으로 나눌경우 발생 

ArrayIndexOutOfBoundsExcetion

배열의 범위를 벗어난 index를 접근할 시 발생

ClassCastExcetion

변환할 수 없는 타입으로 객체를 반환 시 발생 

NullPointException 

 존재하지 않는 레퍼런스를 참조할때 발생 

IllegalArgumentException

잘못된 인자를 전달 할 때 발생 

IOException

입출력 동작 실패 또는 인터럽트 시 발생 

OutOfMemoryException 

메모리가 부족한 경우 발생  

NumberFormatException 

문자열이 나타내는 숫자와 일치하지 않는 타입의 숫자로 변환시 발생 

  • 예외 처리 코드 
try{
    //에러가 발생할 수 있는 코드
    throw new Exception(); //강제 에러 출력 
}catch (Exception e){
    //에러시 수행
     e.printStackTrace(); //오류 출력(방법은 여러가지)
     throw e; //최상위 클래스가 아니라면 무조건 던져주자
}finally{
    //무조건 수행
} 

문제

1. 점수 관리 프로그램

package HW7_프로그램만들기;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Scanner;
class Score {
    int Student_num;
    int score;
    Score(int Student_num, int score) {
        this.Student_num = Student_num;
        this.score = score;
    }
}
public class Test087 {
    static LinkedList<Score> l2 = null;
    static int Student_num = 0;
    static int score = 0;
    static Scanner scan;
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        scan = new Scanner(System.in);
        String l = null;
        while (true) {
            System.out.println("[ M E N U ]");
            System.out.println("1. 새 자료");
            System.out.println("2. 자료 입력");
            System.out.println("3. 파일로 저장");
            System.out.println("4. 파일에서 불러오기");
            System.out.print("> ");
            l = br.readLine();
            if (l.equals("1")) {
                l2 = new LinkedList<Score>();
                System.out.println("# 새롭게 리스트를 만들거나 초기화하였습니다.");
            } else if (l.equals("2")) {
                if (l2 == null) {
                    System.out.println("# 리스트 인스턴스가 없습니다. 1번을 선택하여 생성해주세요.");
                } else {
                    System.out.print("학번 : ");
                    Student_num = scan.nextInt();
                    System.out.print("점수 : ");
                    score = scan.nextInt();
                    l2.add(new Score(Student_num, score));
                    System.out.println("# 리스트에 학번이 " + Student_num + "인 학생의 점수를 추가했습니다.");
                }
            } else if (l.equals("3")) {
                BufferedWriter bw = new BufferedWriter(new FileWriter("scores.txt"));
                for (int i = 0; i < l2.size(); i++) {
                    bw.write((i + 1) + "번 째 학생 정보");
                    bw.newLine();
                    bw.write("Student_num: " + l2.get(i).Student_num);
                    bw.newLine();
                    bw.write("score: " + l2.get(i).score);
                    bw.newLine();
                    System.out.println("# 성적리스트를 파일로 저장하였습니다.");
                }
                bw.close();
            } else if (l.equals("4")) {
                l2 = new LinkedList<Score>();
                BufferedReader br2 = new BufferedReader(new FileReader("scores.txt"));
                String str = null;
                int r = 0;
                boolean flag = false;
                String[] s = null;
                int s_num = 0;
                int sc = 0;
                while ((str = br2.readLine()) != null) {
                    if (r % 3 == 1) {
                        s = str.split(": ");
                        s_num = Integer.parseInt(s[1]);
                        flag = true;
                        r++;
                        continue;
                    }
                    if (flag) {
                        flag = false;
                        s = str.split(": ");
                        sc = Integer.parseInt(s[1]);
                        l2.add(new Score(s_num, sc));
                    }
                    r++;
                }
                System.out.println("# 저장파일을 불러왔습니다.");
            } else if (l.equals("quit")) {
                System.out.println("# 프로그램을 종료합니다.");
                break;
            }
            if (l.equals("quit"))
                break;
        }
        br.close();
    }
}

2. mp3파일 소켓 저장

<Client>

package Task.Week2;

import java.io.*;
import java.net.Socket;
/*1. 서버에 접속할 소켓생성 CCC
2. 서버의 InputStream을 받아오기
- 서버의 data를 1 byte씩 받아 온다. (InputStream)
3. 저장할 파일에 연결
4. InputStream을 통해 받아온 data를 1 byte씩파일에 작성
- Data가 글자가 아닌 byte이므로 1 byte씩 저장 (FileOutputStream)
5. 연결 해제
*/

public class Client {
    public static void main(String[] args) {
        try(
                Socket skt = new Socket("127.0.0.1", 1123);
                ObjectOutputStream oos = new ObjectOutputStream(skt.getOutputStream());
                InputStream is = skt.getInputStream();
                ObjectInputStream ois = new ObjectInputStream(is);

        ){
            oos.writeUTF("music.mp3");
            oos.flush();
            int status = ois.readInt();
            System.out.println(status);
            if(status == 200){
                System.out.println("파일 받기");
                OutputStream file = new BufferedOutputStream(new FileOutputStream("music2.mp3"));
                int r = 0;
                while((r = is.read()) != -1){
                    System.out.println("파일 수신 준비");
                    file.write(r);
                }
            }else{

            }
            ;
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

<Server>

package Task.Week2;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

/*Server writeread SSSS
objectinput
1. 클라이언트에서의 접속을 받아 소켓을 생성해줄 서버소켓 생성
2. 클라이언트의 요청에 의해 소켓 생성
3. 클라이언트의 OutputStream을 받아오기
4. 음악파일에 연결
5. 음악파일을 1 byte씩 읽어 (readInt )클라이언트에 전송
- 음악파일에서 1 byte씩 가져왔으므로 Client에도 1 byte씩 보내주어야 함 (FileInputStream, OutputStream)
6. 전송이 끝나면 연결 해제
*/
public class Server {
    public static void main(String[] args) {

        System.out.println("Before accept()");
        try(
                ServerSocket svr = new ServerSocket(1123);
                Socket skt = svr.accept();
                ObjectInputStream ois = new ObjectInputStream(skt.getInputStream());
                OutputStream os = skt.getOutputStream();
                ObjectOutputStream oos = new ObjectOutputStream(os);
        ){

            System.out.println("After accept()");
            String title = ois.readUTF();
            File f = new File(title);
            boolean b = f.exists();
            System.out.println(b);
            if(b){
                oos.writeInt(200);
                oos.flush();

                InputStream file = new BufferedInputStream(new FileInputStream(title));
                int r = 0;
                while((r =file.read()) != -1){
                    System.out.println("파일 전송 준비");
                    os.write(r);
                    os.flush();
                }
                file.close();
                //파일이 길이를 리턴한다. (long 형 자료에 주의)
                System.out.println(f.length());
            }else{
                oos.writeInt(404);
                oos.flush();
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

Day 2

1. package Lecture.Week2;

public class Test11 {
public static void main(String[] args){
String l = "HelloWorld";
String t = l.substring(2,5);
String r = "HellWorld";
String t1 = l.substring(2,5);

System.out.println( r== l ); //StringPool형태로 나와서 -> false
/*""로 생성한 String은 POOl을 쓴다. 포인터가 비교 가능 , 그 외의 경우(substring) 은 pool쓴다는 보장이 없다
* 그떄는 equals로 비교한다.*/
System.out.println("llo" == t);//""로 비교하면 틀리게 나올수도 있따 -> false
System.out.println("llo".equals(t)); //true

int r2 = Integer.parseInt("100");
System.out.println( r2 == 100);//true
/*문자열을 숫자로 변환시에 : Double.parseDouble() 있음*/

String tl = "10101,100";
int idx = tl.indexOf(",");
System.out.println(tl.substring(0,idx));
System.out.println(tl.substring(idx + 1)); //아래 것보다 더 메모리 향상에 도움이 됨 . 아래는 몇개의 배열이 될 지 모르니까 / , 하나 정도 있을때 좋음

String[] ls = tl.split(",");//,가 여러 개 있는 경우 이 방법이 편함
System.out.println(ls[0]);
System.out.println(ls[1]);
}
}

/*false
false
true
true
10101
100
10101
100*/

2. 데이터베이스 (Mysql

데이터베이스를 먼저 구축 -> 안에 테이블 생성 

mysql> show databases;
mysql> create database study;
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| study              |
| test               |
+--------------------+
5 rows in set (0.00 sec)
mysql>use study; //사용하는 데이터베이스로 변경
mysql> create table study01t( //study01t 생성
    -> id int not null,              //자료형 ; int(4byte)
    -> score tinyint not null
//자료형 : tinyint(1byte)
    -> );
Query OK, 0 rows affected (0.01 sec)
mysql>drop table study01t; //테이블 지우기
mysql>insert into study01t values (10101, 100);//테이블에 값 입력
mysql>insert into study01t values(10102, 90);
mysql> select * from study01t;
+-------+-------+
| id         | score |
+-------+-------+
| 10101 |   100 |
| 10102 |    90 |
| 10103 |    80 |
+-------+-------+
3 rows in set (0.00 sec)
mysql>insert into study01t (score, id) //입력시 순서 바꾸어서 입력할 수 있다
     -> values(90, 10104);
Query OK, 1 row affected (0.00 sec)
mysql> select * from study01t; 
+-------+-------+ 
| id         | score | 
+-------+-------+ 
| 10101 |   100 | 
| 10102 |    90 | 
| 10103 |    80 | 
| 10104 |    90 | 
+-------+-------+ 
4 rows in set (0.00 sec)

-테이블에 있어야하는 개념 

  •   필드 (Field) - 컬럼
    • 자료형을 지정한다(int, tinyint)
    • 같은 자료형의 같은 의미의 값이 와야한다
  • 레코드(Record) - ROW
    • 입력의 단위 
    • 데이터들이 연관되어진 묶음

=> 이 두가지 개념이 있어야 테이블이라고 할 수 있다.

테이블 구성 요소

mysql> delete from study01t where id = 10101;  //where 조건을 만족하는 레코드를 없앤다.
Query OK, 1 row affected (0.01 sec)
mysql> select * from study01t; 
+-------+-------+ 
| id    | score | 
+-------+-------+ 
| 10102 |    90 | 
| 10103 |    80 | 
| 10104 |    90 | 
+-------+-------+ 
3 rows in set (0.00 sec)
mysql> delete from study01t where id <10104; 
Query OK, 2 rows affected (0.00 sec)
mysql> select * from study01t; 
+-------+-------+ 
| id    | score | 
+-------+-------+ 
| 10104 |    90 | 
+-------+-------+ 
1 row in set (0.00 sec)
mysql> delete from study01t;  //조건을 주지 않으면 다 지운다.
Query OK, 1 row affected (0.01 sec)
mysql> delete from study01t where 0 = 1; //모든 레코드가 만족하지 않아 지워지지 않음
mysql> delete from study01t where 1 = 1; //모든 레코드가 만족하니까 모두 지워짐
mysql> update study01t set score=90 where id = 10101; //조건만족 하는 것만 업데이트 해줌
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0
mysql> update study01t set score = score - 10 where id = 10101; //수식 연산 조건도 가능 , 기존의 값 사용 가능 
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0
mysql> update study01t set score = id - 10000 where id = 10101;  //같은 레코드의 다른 필드의 값을 가져와서도 변경 가능
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from study01t;
+-------+-------+
| id      | score |
+-------+-------+
| 10101 |   101 |
| 10102 |    90 |
| 10103 |    80 |
| 10104 |    90 |
+-------+-------+
4 rows in set (0.00 sec)
mysql> update study01t set score = id - 10000 where id != 10101;  
Query OK, 3 rows affected (0.00 sec)
Rows matched: 3  Changed: 3  Warnings: 0

mysql> select * from study01t;
+-------+-------+
| id    | score |
+-------+-------+
| 10101 |    80 |
| 10102 |   102 |
| 10103 |   103 |
| 10104 |   104 |
+-------+-------+
4 rows in set (0.00 sec)
mysql> update study01t set id = 0, score = 0 where id = 10101; //두 칼럼이 변경 시에는 "," 사용
Query OK, 1 row affected (0.01 sec)
Rows matched: 1  Changed: 1  Warnings: 0

mysql> select * from study01t;
+-------+-------+
| id    | score |
+-------+-------+
|     0 |     0 |
| 10102 |   102 |
| 10103 |   103 |
| 10104 |   104 |
+-------+-------+
4 rows in set (0.00 sec)
mysql> select score+5, id from study01t  //select는 데이터를 가공해서 보여줄 수있다.
    -> where id != 0;  
+---------+-------+
| score+5 | id    |
+---------+-------+
|     107 | 10102 |
|     108 | 10103 |
|     109 | 10104 |
+---------+-------+
3 rows in set (0.00 sec)
mysql> select score + 5 as sungjuk, id from study01t where id != 0; //컬럼 이름 바꿔서 출력 하지만 실제로 바뀐 것 아니라 보여지는 거만 바꾸어짐 
+---------+-------+
| sungjuk | id    |
+---------+-------+
|     107 | 10102 |
|     108 | 10103 |
|     109 | 10104 |
+---------+-------+
3 rows in set (0.00 sec)
mysql> select score , score as sungjuk from study01t; //하나의 칼럼을 여러번 출력해도 무방하다.
+-------+---------+
| score | sungjuk |
+-------+---------+
|     0 |       0 |
|   102 |     102 |
|   103 |     103 |
|   104 |     104 |
+-------+---------+
4 rows in set (0.00 sec)

mysql> create table study02t(
    -> id char(5) not null,
    -> name varchar(10) null
    -> );
Query OK, 0 rows affected (0.02 sec)
 insert into study02t values('a0001', 'abcd'); //문자열 : ''로 감싼다. char or varchar 자료형 
//char : 고정길이 문자열 (학번, 주민번호) / 처리속도가 훨씬 빠름
-> 'a01' 넣어도 무조건 5자리 차지 (낭비 각오) 
//varchar : 길이를 최대값까지 설정해주지만 가변적이다 //처리 속도가 조금 느림
-> 'apple'을 넣으면 5자리만 공간 사용 , (낭비 적다)
mysql> select concat(id, '*') from study02t;
//oracle  : 'a01 *'
+-----------------+
| concat(id, '*') |
+-----------------+
| a0001*          |
| a0001*          |
| a0001*          |
+-----------------+
3 rows in set (0.00 sec)
mysql> select * from Studentt where addr = '역삼동'; //역삼동에 사는 모든 학생들 검색
mysql> select * from Studentt where addr LIKE '역%'; //역으로 시작하는 문장 검색
mysql> select * from Studentt where addr LIKE '%삼동'; //삼동으로 끝나는 문장 검색
mysql> select * from studentt
    -> where substr(addr, 1,2) = '역삼';

+-------+-----------+-----------+
| stId  | name      | addr      |
+-------+-----------+-----------+
| 10101 | 홍길동    | 역삼동    |
| 10103 | 이기자    | 역삼동    |
+-------+-----------+-----------+
2 rows in set (0.00 sec)
mysql> select substr(addr, 1,2) from studentt;  //부분 문자열 추출 가능
+-------------------+
| substr(addr, 1,2) |
+-------------------+
| 역삼              |
| 개포              |
| 역삼              |
| 한남              |
| 홍제              |
| 한남              |
+-------------------+
6 rows in set (0.00 sec)
mysql> select length(addr) from studentt;  //글자 길이 .utf-8인 경우 한글은 3바이트 
+--------------+
| length(addr) |
+--------------+
|            9 |
|            9 |
|            9 |
|            9 |
|            9 |
|            9 |
+--------------+
6 rows in set (0.00 sec)

#aggregate functions : 5가지 => 딱 하나의 결과만 나옴

min / max / count / avg /  sum

mysql> select * from scoret where subid = 'KOR1';
+-------+-------+-------+
| stId  | subId | score |
+-------+-------+-------+
| 10101 | KOR1  |    60 |
| 10102 | KOR1  |    90 |
| 10103 | KOR1  |    70 |
| 10104 | KOR1  |    80 |
| 10105 | KOR1  |    50 |
| 10106 | KOR1  |    60 |
+-------+-------+-------+
6 rows in set (0.00 sec)

mysql> select min(score) from scoret where subid = 'KOR1'; //국어점수 최소값 1개
+------------+
| min(score) |
+------------+
|         50 |
+------------+
1 row in set (0.00 sec)

## studentt , subjectt , scoret 는 얽혀있다 -> 여러개의 테이블이 연관 관계를 가지고 데이터베이스를 구성한다

 

mysql> select * from scoret where subid ='KOR1'
    ->  and stid IN( select stid from studentt where addr LIKE '역삼%');
//여러개 나오는 결과를 이용할 떄 IN , NOT IN 을 사용한다
//하나의 쿼리의 결과를 이용해서 다른 쿼리를 돌릴 수 있다 : 서브쿼리: ( ) 로 묶여 있는것
+-------+-------+-------+
| stId  | subId | score |
+-------+-------+-------+
| 10101 | KOR1  |    60 |
| 10103 | KOR1  |    70 |
+-------+-------+-------+
2 rows in set (0.00 sec)
mysql> select * from scoret where subid = 'KOR1' and
    -> score <= (select avg(Score) from scoret where subid =  'KOR1');
//유일한 서브쿼리의 결과와 비교는 비교연산자를 쓴다 
//서브쿼리는 반드시 괄호로 묶어 주어야 한다.
//국어 점수가 평균(68.666)이 안되는 학생 
+-------+-------+-------+
| stId  | subId | score |
+-------+-------+-------+
| 10101 | KOR1  |    60 |
| 10105 | KOR1  |    50 |
| 10106 | KOR1  |    60 |
+-------+-------+-------+
3 rows in set (0.00 sec)
mysql> select avg(score) from scoret where subid =  'MAT1' and stid in (select stid from studentt where name like '김%');  //김씨 성을 가진 학생들의 수학 평균
+------------+
| avg(score) |
+------------+
|    70.0000 |
+------------+
1 row in set (0.00 sec)
mysql> update scoret set score = score - 5 where subid = 'ENG1' and stid in ( select * from (select stid from scoret where subid = 'ENG1' and score <= 70) AS X); // 영어 70점 이하의 점수를 받은 학생들의 성적을 -5하라

"AGGREAGATE FUNCTION 은 GROUP BY , HAVING 과 연동된다"

mysql> select stid, avg(score) from scoret group by stid; //stid에 동일한 값을 가진 레코드를 짜매어 평균낸 결과
+-------+------------+
| stid  | avg(score) |
+-------+------------+
| 10101 |    76.6667 |
| 10102 |    93.3333 |
| 10103 |    76.6667 |
| 10104 |    73.3333 |
| 10105 |    63.3333 |
| 10106 |    66.6667 |
+-------+------------+
6 rows in set (0.00 sec)

 select stid, avg(score) form scoret group by stid where avg(score) <=75; error 

-> 왜 ? where은 통계처리에 우선한다.

   해서 having은 통계처리 이후에 동작한다. 


select stid, avg(score) from scoret group by stid having avg(score) <= 75;
 "" 서브쿼리는 크게 3종류로 나뉜다 . ""
   1. where 절의 서브쿼리
   2. from 절의 서브쿼리 ( inline view )
   3. select 절의 서브쿼리 ( 엄청난 결과 / 엄청난 부담 )
   
from 절의 서브쿼리 : select 결과를 마치 table처럼 보면 된다. 

select stid, avg(score) as xx from scoret group by stid;
+-------+------+
| stid  | xx   |
+-------+------+
| 10101 |   77 |
| 10102 |   93 |
| 10103 |   77 |
| 10104 |   72 |
| 10105 |   62 |
| 10106 |   67 |
+-------+------+ 


select stid, round(avg(score), 2) as xx from scoret group by stid;
+-------+-------+
| stid  | xx    |
+-------+-------+
| 10101 | 76.67 |
| 10102 | 93.33 |
| 10103 | 76.67 |
| 10104 | 71.67 |
| 10105 | 61.67 |
| 10106 | 66.67 |
+-------+-------+
//round(): 반올림 하기

select * from ( select stid, round(avg(score), 2) as xx
from scoret group by stid) where xx <= 75;
mysql> create view score2v as
    -> select stid, round(avg(score), 2) as xx from
    -> scoret group by stid;
Query OK, 0 rows affected (0.01 sec)

mysql> select * from score2v;
+-------+-------+
| stid  | xx    |
+-------+-------+
| 10101 | 76.67 |
| 10102 | 93.33 |
| 10103 | 76.67 |
| 10104 | 73.33 |
| 10105 | 63.33 |
| 10106 | 66.67 |
+-------+-------+
6 rows in set (0.00 sec)

# 뷰는 실제로 데이터가 존재하는 테이블이 아니라 테이블 데이터를 이용해서 만들어진 하나의 결과 화면일 뿐 이다.

# 뷰를 대상으로 수정 삭제는 무의미 하다.

 

mysql> select stid, name, (select avg(score) from scoret) as avg from studentt;
+-------+-----------+---------+
| stid  | name      | avg     |
+-------+-----------+---------+
| 10101 | 홍길동    | 75.0000 |
| 10102 | 고길동    | 75.0000 |
| 10103 | 이기자    | 75.0000 |
| 10104 | 박기자    | 75.0000 |
| 10105 | 김영삼    | 75.0000 |
| 10106 | 김대중    | 75.0000 |
+-------+-----------+---------+
6 rows in set (0.00 sec)

 

mysql> select x.stid, x.name from studentt as x; //studentt 가 너무 기니까 x로 바꾸어 쓴다
mysql> select studentt.stid, studentt.name from studentt;  //테이블명.컬럼명 식 
+-------+-----------+
| stid  | name      |
+-------+-----------+
| 10101 | 홍길동    |
| 10102 | 고길동    |
| 10103 | 이기자    |
| 10104 | 박기자    |
| 10105 | 김영삼    |
| 10106 | 김대중    |
+-------+-----------+
mysql> select x.stid, x.name, (select avg(score) from scoret where stid = x.stid) as avg from studentt as x;
+-------+-----------+---------+
| stid  | name      | avg     |
+-------+-----------+---------+
| 10101 | 홍길동    | 76.6667 |
| 10102 | 고길동    | 93.3333 |
| 10103 | 이기자    | 76.6667 |
| 10104 | 박기자    | 73.3333 |
| 10105 | 김영삼    | 63.3333 |
| 10106 | 김대중    | 66.6667 |
+-------+-----------+---------+
6 rows in set (0.00 sec)
mysql> select x.stid, x.avg from(select stid, avg(score) as avg from scoret group by stid)as x;
+-------+---------+
| stid  | avg     |
+-------+---------+
| 10101 | 76.6667 |
| 10102 | 93.3333 |
| 10103 | 76.6667 |
| 10104 | 73.3333 |
| 10105 | 63.3333 |
| 10106 | 66.6667 |
+-------+---------+

 

create table temp01t as
->select stid, avg(score) as avg from 
->scoret group by stid;
+-------+---------+

| stid  | avg     |
+-------+---------+
| 10101 | 76.6667 |
| 10102 | 93.3333 |
| 10103 | 76.6667 |
| 10104 | 73.3333 |
| 10105 | 63.3333 |
| 10106 | 66.6667 |
+-------+---------+
6 rows in set (0.00 sec)
mysql> select x.stid, x.avg,(select count(*)+1 from temp01t where avg > x.avg) as rank from temp01t as x;  //등수
+-------+----------+------+
| stid  | avg      | rank |
+-------+----------+------+
| 10101 | 100.0000 |    1 |
| 10102 |  93.3333 |    2 |
| 10103 |  76.6667 |    3 |
| 10104 |  73.3333 |    4 |
| 10105 |  63.3333 |    6 |
| 10106 |  66.6667 |    5 |
+-------+----------+------+

서브쿼리가 여섯명의 등수를 구할 떄 쿼리가 6*6으로 36번이나 돌아야한다 . 만약 1000명이라면? 말이안됨

-> 임시 테이블을 만들자

mysql> select * from temp02t order by rank;
+-------+----------+------+
| stid  | avg      | rank |
+-------+----------+------+
| 10101 | 100.0000 |    1 |
| 10102 |  93.3333 |    2 |
| 10103 |  76.6667 |    3 |
| 10104 |  73.3333 |    4 |
| 10106 |  66.6667 |    5 |
| 10105 |  63.3333 |    6 |
+-------+----------+------+
6 rows in set (0.00 sec)

mysql> select * from temp02t order by rank desc;
+-------+----------+------+
| stid  | avg      | rank |
+-------+----------+------+
| 10105 |  63.3333 |    6 |
| 10106 |  66.6667 |    5 |
| 10104 |  73.3333 |    4 |
| 10103 |  76.6667 |    3 |
| 10102 |  93.3333 |    2 |
| 10101 | 100.0000 |    1 |
+-------+----------+------+
6 rows in set (0.00 sec)

-임시테이블과 뷰는 흩어진 데이터에서 자신이 원하는 데이터로 가공할 수 있는 방법 제공(비정형 데이터에서 정형화 된 데이터를 만들어 낸다)

-뷰는 오버헤드가 있지만 데이터 변경을 즉각 반영한다 / 임시테이블은 오버헤드가 적지만, 데이터의 변경을 즉각 반영 못함

-select 서브쿼리는 오버헤드가 크다 (1000명의 등수를 처리하는 결과를 1000명이 동시 열람하면 100만건의 쿼리가 동작하는 셈 -> group by 오버헤드 포함) 

-임시 테이블은 이런 부담을 극적으로 줄여준다

 

mysql> create table study3t(
    -> no int not null auto_increment primary key,
    -> theTime datetime not null
    -> );
mysql> insert into study3t values(default, now());
Query OK, 1 row affected (0.01 sec)

mysql> select * from study3t;
+----+---------------------+
| no | theTime             |
+----+---------------------+
|  1 | 2019-07-23 17:16:05 |
|  2 | 2019-07-23 17:16:16 |
+----+---------------------+
2 rows in set (0.00 sec)

now() : 현재 시간 => 입력 시 datetime 자료형 쓴다.

//datetime 자료형에 들어있는 값은 연산이 가능하다.

 

mysql> select no, date_add(theTime, INTERVAL 1 MONTH) from study3t;
+----+-------------------------------------+
| no | date_add(theTime, INTERVAL 1 MONTH) |
+----+-------------------------------------+
|  1 | 2019-08-23 17:16:05                 |
|  2 | 2019-08-23 17:16:16                 |
+----+-------------------------------------+
2 rows in set (0.00 sec)
mysql> select no, date_add(theTime, INTERVAL 4 DAY) from study3t;
+----+-----------------------------------+
| no | date_add(theTime, INTERVAL 4 DAY) |
+----+-----------------------------------+
|  1 | 2019-07-27 17:16:05               |
|  2 | 2019-07-27 17:16:16               |
+----+-----------------------------------+
2 rows in set (0.00 sec)

mysql> select no, date_add(theTime, INTERVAL 4 HOUR) from study3t;
+----+------------------------------------+
| no | date_add(theTime, INTERVAL 4 HOUR) |
+----+------------------------------------+
|  1 | 2019-07-23 21:16:05                |
|  2 | 2019-07-23 21:16:16                |
+----+------------------------------------+
2 rows in set (0.00 sec)

//날짜 데이터를 다룰 때 연산의 필요성이 없으면 char 쓴다.

mysql> create table study04t(
    -> no int not null auto_increment primary key,
    -> theTime char(19) not null
    -> );
Query OK, 0 rows affected (0.02 sec)

mysql> insert into study04t values (default, now());
Query OK, 1 row affected (0.01 sec)

mysql> select * from study04t;
+----+---------------------+
| no | theTime             |
+----+---------------------+
|  1 | 2019-07-23 17:27:03 |
+----+---------------------+
1 row in set (0.00 sec)
반응형

'Language Study > Java' 카테고리의 다른 글

제주에서 자바_Week2_3  (0) 2019.07.25
제주에서 자바_Week2_2  (0) 2019.07.24
제주에서 자바_Week1  (0) 2019.07.20
4. 클래스  (0) 2019.05.29
3. 참조 타입  (0) 2019.05.28
반응형

Day 1

1. 8가지 자료형

Byte Short Int Long Float Double
8bit 16bit 32bit 64bit 32bit 64bit

- byte , short , int, long은 정수의 값을 가져다 저장할 수 있는 자료형

- 작은 타입 => 큰 타입 (자동 변환)

- 큰 타입 => 작은 타입 (강제 변환 -> X : 에러)

- (기본) 같은 타입형 변수만 연산 가능

 

2. 변수 : 값을 저장하는 기억공간

- 자료형 : 변수 선언

- 대입 : 값을 저장

 

문제

1. 연 6.6퍼 이자율에 초기금 100만원을 100년간 묵힐 때

public class Test1{
	pulblic static void main(String[] args){
    	double money = 1000000; //초기금
        double rate = 0.066; //이자율
        for( int i = 0; i < 100; i++){
        	money += money *  rate;
        }
        
        System.out.println((int)money);
    }
}

2. 연 6.6% 이자율의 복리 (매 100만원 적금)

public class Test2{
	public static void main(String[] args){
    	int addMoney = 1000000; //매 적금
        double money = 0; // 초기금
        double rate = 0.066;
        for(int i = 0; i < 100; i++){
        	money += addMoney;
            money += money * rate;
        }
        System.out.println(money);
        long endTime = System.currentTimeMiilis();
    }
}

Day 2

※코드 잘 짜는 법 

- 잘 쪼갠다 

- 자신의 보폭을 잘 파악한다

- 반복문 정리 => 일단 늘어놓고 정리 

 

1. Java

-선언 , 대입, 연산

  • 클래스에서 변수, 함수 선언 가능
  • 클래스에서 변수, 함수 호출 연산, 초기화 등등 불가능
class Apple{
	int i ;
    i = 100; //error
    int add(int i, int j){
    	return 100;
    }
    add(); //error
}

- 참조형 변수

  • Apple t = new Apple(); => 클래스를 선언하고 new를 이용하여 instance를 가리킴
class Apple{
    int i;
    int add(int i, int j){ return 100;};
}
public class Test023 {
    public static void main(String[] args) {
        Apple t = new Apple(); //에러 x -> 참조형 변수(포인터)
        t.i = 100; // t가 가리키는 인스턴스가 가지고 있는 변수 i
        System.out.println(t.add(100,20)); //t가 가리키는 인스턴스가 가지고 있는 함수
    }
}

2. 요약

  • 클래스를 선언하여 인스턴스를 만듬 => 이 떄, new 사용
  • 클래스 내부 (멤버 함수(멤버 변수)) 
  • 클래스 - 인스턴스 - new  : 멤버 변수,  멤버 함수존재 
  • 인스턴스가 만들어지는 시점멤버변수 메모리 할당
  • 함수 호출 시점에 로컬변수가 메모리 할당
  • 참조형 변수 는 인스턴스를 가리키는 용도 / 클래스 이름으로 선언
  • 자료형 변수 는 자바의 기본 8개 자료형
  • 자료형 변수에서 대입 ( i = t ) -> t의 값을 복사해서 i에 대입
  • 참조형 변수에서 대입 ( i = t ) -> t가 가리키는 대상을 i가 가리킴
  • 생성자 함수 는 클래스의 멤버 함수  => 주로 멤버변수를 초기화 하는데 사용 (constructor)
  • 인스턴스가 생성될 때 생성자 함수가 생성됨

전반적인 설명

 

 

문제

1. 단리, 복리 가능한 C프로그래밍 (매 100만원 적금)

#include <stdio.h>
float danri(float money, int year, float rate){
    int i;
    float totalMoney, mainMoney;
    totalMoney = 0;
    mainMoney = 0;
    for (i=0; i<year; i++){
        mainMoney += money;
        totalMoney += mainMoney * rate + money;
    }
    return totalMoney;
}

float bokri(float money, int year, float rate){
    float moneyStart;
    int i;
    moneyStart = 0;
    for (i=0; i<year; i++){
        moneyStart += money;
        moneyStart += moneyStart * rate;
    }
    return moneyStart;
}

int main(){
    float (*fp)( float, int, float);
    float r;
    fp = danri;
    r = fp( 100.0, 100, 0.066);
    printf("%f\n", r);
    fp = bokri;
    r = fp( 100.0, 100, 0.066);
    printf("%f\n", r);
    return 0;
}

Day 3

1. 객체지향 3대 속성

- 상속성 : 클래스를 상속해서 클래스를 만든다

- 은닉성 : 감추고 싶은 건 감출 수 있다

- 다형성 : 하나의 심볼(이름)이 여러 실체에 매핑될 수 있다.

class A {
    int apple = 10;
}
//클래스 B는 클래스 A를 상속하여 만들었음을 명시.
// A에서 선언한 멤버변수는 멤버함수를 내려받겠다.
class B extends A{
    int add(int i, int j){return  100;}
}
public class Test27 {
    public static void main(String[] args) {
		B t = new B();
        System.out.println(t.apple);
    }
}

 

2. 클래스 : 설계도 정의해 놓은 것 

- 할 수 있는 것 : 참조형 변수 선언 / 인스턴스 생성 / 상속받아 클래스 선언

 

3. 생성자

<특징>

- return 타입 X 

- 클래스명 (매개 변수) {.....} 로 동작

- 인스턴스  생성시점 호출

- 함수 아님 .. 인스턴스 멤버 변수를 초기화 시킬 때 주로 사용

class Apple4{
    int data = 0;
    // return이 존재하지 않는 함수를 서브루틴이라 한다.
    //리턴타입을 void로 한다.
    void print(){
        System.out.println(this.data);
    }
}
public class Test28 {
    public static void main(String[] args) {
	    Apple t = new Apple();
        t.data = 10;
        t.print();
        Apple l = new Apple();
        l.data = 20;
        l.print();
    }
}

//출력 : 10 20 

this : 멤버 함수 안에서 자신이 소속된 인스턴스에 대한 포인터 

 

4.Java로 리스트 만들기

연결리스트

 

class Node{ //외워라!
    int data = 0; //  대입은 원래 불가능하나 선언과 동시에 대입은 가능함
    Node next = null; //가리키고 싶지않다.

    Node( int i , Node n){ //생성자 일반적 예시
        this.data = i;
        this.next = n;
    }
}
public class Test5 {
    public static void main(String[] args) {
        Node head = new Node(0,null);		//Step 1
        Node tail = head;

        tail.next = new Node(10, null);			//Step 2
        tail = tail.next;

        tail.next = new Node(20, null);			//Step 3
        tail = tail.next;

        for( Node t =head.next ; t !=null ; t=t.next){		//Step 4
            System.out.println(t.data);
        }
    }
}
/*
    모든 참조형 변수에는 null 이라는 값이 대입 가능 : 가리키는 인스턴스 없다.
    -어떻게 돌아가는지 상황파악을 그림으로 설명 가능할 것.
    >> 출력 : 10 20
 */

- 객체 상태 변화

Node flow

연결리스트 클래스화

class Node{
    int data = 0;
    Node next = null;
    Node( int i , Node n){
        this.data = i;
        this.next = n;
    }
}
class LinkedList {
    Node head = null;
    Node tail = null;
    public LinkedList() {
        this.head = new Node(0, null);
        this.tail = this.head;
    }
    void add(int i){
        tail.next = new Node(i, null);
        tail = tail.next;
    }
    public void print() {
        for (Node t = head.next; t !=null; t=t.next) {
            System.out.println(t.data);
        }
    }
}
public class Test29 {
    public static void main(String[] args) {
       LinkedList l = new LinkedList();  //Step 1
       l.add(10);  //Step 2
       l.add(20);  //Step 3
       l.print();

    }
}//>> 출력 : 10 20 

- 객체 상태 변화

LinkedList Flow

5. Java 상속

class A{
    A(){
        System.out.println("A constructor");
    }
}
class BB extends A{
    B() {
        System.out.println("B constructor");
    }
}
public class Test31 {
    public static void main(String[] args) {
        new B();
    }
}//>> A constructor B constructor

=> 왜? A constructor B constructor 이렇게 출력이 될까?

     >> 생성자는 상속이 되지 않고 호출 되는 것이기 때문(멤버 함수가 아니라서)

-상속관계가 존재 시 조상 클래스 , 자손 클래스 자손의 인스턴스를 생성하면 조상의 생서자가 먼저 호출, 자손의 생성자가 호출된다

>>> 이 때 인스턴스는 2번 생성되는 것 처럼 보이지만 하나가 생성되고 조상과 자손을 호출한다.

class A{
    void print(){
        System.out.println("A print");
    }
}
class B extends A{
    void print(){
        System.out.println("B print"); // method overriding
        super.print();// 부모의 함수를 호출하고 싶을때
    void print2(){
        System.out.println("B print2");
    }
}
public class Test32 {
    public static void main(String[] args) {
        B t = new B();      //자손 B호출
        t.print();
        A t2 = new A();         //조상 A 호출
        t2.print();
        A t3 = new B();        //자손 B 호출
        t3.print();
        //조상에서 선언된 멤버함수, 멤버변수만 호출 가능
        //t3.print()2;     -------> 에러남
        //B t4 = (B) new A();//에러남 캐스팅되지않음
		//t4.print();   //다운캐스팅은 일반적으로 불가
        B t4 = (B) t3;   //이 경우 다운캐스팅이됨
        t4.print();         //JVM이 무슨형인지 추리할수 있기때문
    }
}//결과값 : B print A print A print B print A print

6. Method overriding : 조상클래스에서 선언한 멤버 함수 재정의

- 각 인스턴스에서 정의된 method로 사용(변수는 오버라이딩 X) 

- Super 을 이용하여 자손 클래스에서 조상 method 이용가능

오버라이드 개념

 7. 접근 제어자 

  상속 외부 호출 내가 쓰기
Private X X O
protected O X O
public O O O

- 클래스 안의 멤버함수와 멤버 변수 앞에 붙임

- java 의 protected => 같은 패키지 내에선 접근 가능 / 다른 패키지 내에선 접근 불가

- 접근자 안적어? => friendly로 (같은 패키지로는 public / 다른 패키지는 private)

 

=> 때문에 Getter을 이용하여 자신의 값을 호출하게 만듬

class A{
    private int data =100;
	public int getData(){ return data;}
}
class B extends A{
    private int data =200;
    public int getData(){return data;}
}
public class Test{
    public void static main(String[] args){
        A t = new B();
        System.out.println(t.getData());
    }
}//결과값 : 200

-B 클래스의 getData가 호출이되서 혼란이 방지됨

-조상에서 getXXX 함수가 보이면 그런 변수가 있는줄 알고 xXX 변수는 피해간다

-이 경우 getData()로 부모클래스의 data를 부르려고 하면 getData()가 오버라이딩 되어있기 때문에 접근이 힘들어진다.

 

8. 추상클래스 : 선언되었지만 구현되어 있지 않은 메소드

abstract class A{
    public abstract void print();
}
abstract class B{}
class C extends B{}
abstract class D extends C{}
public class Test1 {
    public static void main(String[] args) {
//      A t = new A();
        A t = null;
    }
}

-abstract 메소드가 하나라도 선언되어 있으면 그 메소드 가진 클래스는 반드시 abstract 클래스로 정의

-abstract 클래스는 인스턴스를 만들 수 없다

-참조형 변수 선언이 가능하다

-상속 또한 가능하다

abstract class A{
    public abstract void print();
}
abstract class B extends A{}  //  <------- abstract class - abstract class
class C extends A{			// <------abstract 클래스가 아닌 클래스가 상속받으려면 구현해줘야 함
    @Override
    public void print() {
         System.out.println("hi");
    }
}
public class Test1 {
    public static void main(String[] args) {
        A t = new C();   // <------ 조상의 함수를 호출한 경우 , 자손의 함수가 호출, 오버라이딩 된 구현부가 호출
        t.print();
    }
}

<단리, 복리 추상 클래스로 구현>

abstract class Bank{
    public abstract double calc(double money, int years, double rate);
    public void print(){
        double r = calc(100, 100, 0.066);
        System.out.println(r);
    }
}
class BokriBank extends Bank{
    @Override
    public double calc(double money, int years, double rate) {
        return 59665.1234 * subCalc();
    }
    private int subCalc(){return 3;}
}
class DanriBank extends Bank{
    @Override
    public double calc(double money, int years, double rate) {
        return 760.0 + money();
    }
    private int money(){return 100;}
}
public class Test2 {
    public static void main(String[] args) {
        Bank bk = new BokriBank();
        bk.print();
        Bank bk2 = new DanriBank();
        bk2.print();
    }
}

9. 인터페이스 

interface ICalc{
    public void print(); //인터페이스 안에는 모두 추상자료형이여야함
}
interface IUnknown{}
class Apple{}
class Calc extends Apple implements ICalc, IUnknown{
    @Override
    public void print() {
        System.out.println("A");
    }
}

public class Test3 {
    public static void main(String[] args) {
        ICalc ic = new Calc();
        ic.print();
    }
}

-일종의 추상 클래스 => 변수 선언, 상속 당할 수 있음 => 다만, 인스턴스 생성 불가

-인터페이스 상속해서 클래스를 선언될 때는 implements 이용

-다중 상속 가능, 클래스 상속과 인터페이스 동시 상속 가능

 

문제

<인터페이스 사용한 Decorator pattern>

interface IGreet {
    public String greet();
}
class MerciGreet implements IGreet{
    @Override
    public String greet() {
        return "Merci";
    }
}
class HelloGreet implements IGreet{
    @Override
    public String greet() {
        return "hello";
    }
}
abstract class GreetDeco implements IGreet{
    protected IGreet ig = null;

    public GreetDeoo(IGreet ig) {
        this.ig = ig;
    }
}
// 자손의 생성자에서 조상의 생성자 중 매개변수 있는 생성자를 호출 원하면 supoer로 지정.
class StarDeco extends GreetDeoo{
    public StarDeco(IGreet ig) {
        super(ig);
    }
    @Override
    public String greet() {
        return "" + ig.greet() + "*";
    }
}
class SharpDeco extends GreetDeoo{
    public SharpDeco(IGreet ig) {
        super(ig);
    }
    @Override
    public String greet() {
        return "" + ig.greet() + "#";
    }
}
public class Test4 {
    public static void main(String[] args) {
        IGreet ig= new SharpDeco(new StarDeco(new HelloGreet()));
        System.out.println(ig.greet());
    }
}//hello*#

=> 추가 상식 : interface는 public 명시 안해도 컴파일시 자동으로 추가해줌


Day 4

1. 메소드 오버로딩 : 하나의 클래스 안에 이름은 같은데 매개변수 형태가 다른 함수 여러 개 공존 가능

class Temp{//하나의 클래스 안에 이름은 같은데 매개변수 형태가 다른 함수 여러 개 공존가능
	public void print(){};
    public void print(int i){
    	System.out.println(1);
    };
    
    public void print(double i){
    	System.out.println(2);
    };
	public void print(int i, int j){
        System.out.println(3);
    };
}
public class Test40 {
    public static void main(String[] args) {
        Temp t= new Temp();
        t.print();
//        float j = 3.14;     큰타입 Double(3.14) -> 작은타입 float(j)로 바로 변환 x
        float i = (float) 3.14; //방법 1  강제형변환
        float j = 3.14f; //방법2  float = float
        t.print(j);// 매개변수가 딱 맞지 않으면 가장 가깝게 자동형변환 되는것을 찾아서 호출
    }//>>결과 : 2
}

 

- 멤버 함수에는 오버라이딩 이라는 개념이 있지만, 멤버 변수에는 오버라이딩 개념이 없음

class A{
    int i = 100;
}
class B extends A{
    int i = 200;
    void print(){};
}
public class Test40 {
    public static void main(String[] args) {
        A t1 = new B();
        System.out.println(t.i);
        //t 포인터가 가리키는 인스턴스를 감싸는 B클래스 인스턴스를 t2가 가리킨다.
        B t2 = (B)t;
        t2.print();
        System.out.println(t2.i); //갑자기 i값이 변하므로 private해주는게 좋음
    }
}

##요약

  • 형변환 시 예기치 못한 변수의 변화가 생길 수 있으므로 같은 이름으로 하는 것은 금지
  • 클래스 안에 올 수 있는 것
    -변수 선언(멤버 변수) , 함수 선언(멤버 함수)
    • 실행 하면  main이 먼저 올라오고
    • static으로 선언되면 클래스가 메모리에 올라올 때 인스턴스가 생성되기 전에 메모리 할당
  • 자바 실행 환경은 클래스가 필요해지면 클래스 파일을 메모리에 올린다 -> 후에 인스턴스 생성 가능
    • static 멤버는 클래스 로딩 시에 메모리를 할당, 무조건 유일하다
    • non-static 멤버는 인스턴스가 생성 될 때 메모리를 할당받음 , 인스턴스마다 따로따로 존재
  • 인스턴스가 100번 생성되도 클래스는 설계도이니 최초에 한번만 올라옴 / 이 때 스태틱은 전역변수처럼 1개만 올라옴
class Temp{
  static int i = 100;
  static void print(){
      System.out.println(i);
  }
  void func(){
      System.out.println("hi");
  }
  static class Temp2{
      private int i = 3;
      public void getI(){
      }
      static void print(){
          System.out.println("hi");
      };
  }
}
public class Test40 {
    public static void main(String[] args) {
        int j = Temp.i;
        Temp t = new Temp();
        t.func();
        Temp.print();
        Temp.Temp2.print();
    }
}// static 멤버는 클래스명. 심볼 형태로 접근 >> 결과 : hi 100 hi

-static 멤버 함수 안에서는 non-static한 멤버 함수, 멤버 변수에 접근 할 수 없다 (메모리에 아직 안올라와 있기 때문에)

-abstract 클래스는 인스턴스를 생성할 수 없다.

 

복습

  • class
  • instance
  • 로컬변수 함수가 호출될 때 메모리할당
  • 멤버변수 클래스내에 선언된 변수 인스턴스가 생성될떄 메모리 할당(static이 아닌경우)
  • 매개변수 일종의 로컬변수로 함수호출시 생성
  • 참조형변수 인스턴스를 가리키기위한 용도 : class 이름으로 선언
  • 자료형변수 byte short int long float double boolean char
  • 생성자함수 인스턴스가 생성될떄 호출 되는 함수, 주로 멤버변수를 초기화하는데 사용
  • extends 인터페이스 외 클래스 상속 1개만가능
  • implements 인터페이스 상속
  • interface(abstract만 가지고 있는 클래스)
  • abstract class(하나의 abstract method가 있는경우 무조건)
  • abstract method(선언은 되었지만 구현은 없는경우)
  • overriding( 부모로부터 상속)
  • overloading( 같은 이름의 메소드 다른 매개변수)
  • 자료형변수_캐스팅 : 큰 형태에서 작은형태 x 작은 형태에서 큰형태 o
  • 참조형 변수_캐스팅 (큰박스가 작은박스를 감싸는 모양)
  • 자료형 변수의 대입 : 오른쪽의 값을 복사해서 왼쪽에 대입
  • 참조형 변수의 대입 : 오른쪽이 가리키는 대상이왼쪽을 가리킴
  • private : 나만쓸수있음
  • public : 나쓸수있고 참조형변수도되고 자손도가능
  • protected : 나쓸수있고 자손도가능
  • friendly(default) : 같은패키지에서는 public 다른패키지에서는 private
  • A t = new B() 조상의 참조형 변수로 자손을 만드는것은 가능하고, 조상의 함수를 호출한 경우 자손의 함수가 호출되므로 오버라이딩 된 구현부가 호출이됨

2. 자바 배열

public class Test5{
	public static void main(String[] args){
    	int[] i = new int[]{1,2,3,4}; //new 사용했으므로 자바의 배열은 인스턴스
        //int[] i = {1,2,3,4}로 축약해서 사용할 수 있다.
        for(int j : i){ //i = 참조형 변수
        	System.out.println(j);
        }
        System.out.println(i.length); //그래서 멤버 변수를 가지고 있음
    }
}//배열 : 동일한 형태의 기억장소가 연속으로 할당된 기억공간 >>>결과 : 1 2 3 4 4

for문 구현할 시에는 

for(int j = 0; j < i.length; j++){
	if(j == 2){
    	break; //break는 반복문 탈출 , continue는 이하의 코드는 수행을 건너 뛰고 반복을 계속
    }
    System.out.println(i);
}

3. Object class

-자바의 기본적으로 제공되는 클래스

-자바,lang 패키지에 소속된 클래스는 import 없이 사용 가능

public class Test048 {
    public static void main(String[] args) {
        Object t = new Temp();
        System.out.println(t.toString());// toString()은 Object에 선언되었고, 상속되었다.
        Object t2 = new Temp();
        System.out.println(t2.toString());
    }
}>>결과값 : Temp@460141958  Temp@1163157884

-조상 클래스를 지정하지 않으면 object로부터 상속받는다

-object는 모든 클래스의 조상

-object는 어떤 타입의 인스턴스도 가르킬 수 있다.

-toString()은 오브젝트.클래스에 선언되어 있다.

 

4. Getter Setter

-멤버 함수는 private 권장 / 값을 읽을 때는 getter함수 제작

-인스턴스 내 변수값 일기 전용 -> getter만 만듬

-인스턴스 내 변수값 바꾸고 싶을 때는 -> setter를 쓰는 것 

class Temp{
    private Object data = null;
    public Object getData(){
        return data;
    }
    public void setData(Object obj){
        this.data = obj;
    }
}//오브젝트 클래스 getter / setter

주의점

class Temp{
    private int data = 100;
    public int getData(){
        return data;
    }
}
class Temp2 extends Temp{
    private int data = 200;
    public int getData(){
        return data;
    }
}
public class Test048 {
    public static void main(String[] args) {
        Temp t = new Temp();
        System.out.println(t.getData());
        Temp t2 = new Temp2();
        System.out.println(t2.getData());
        Temp2 t3 = new Temp2();
        System.out.println(t3.getData());
    }
}//결과값 : 100 200 200

5. String 클래스

-StringPool : 자바에서 String클래스를 유일하게 new 없이 ""로 인스턴스 가능

public class Test048 {
    public static void main(String[] args) {
        String t = "HelloWorld";
        String t2 = "HelloWorld";
        System.out.println(t == t2);
        System.out.println(t.equals(t2));
        System.out.println(t.hashCode());
        System.out.println(t2.hashCode());
    }//>>결과값 : true true 439329280 439329280

-""를 만나면 VM은 StringPool을 뒤져서 없으면 만들고, 있으면 재활용

-HTML 내용을 String으로 만들고 재활용 하는 쪽이 메모리 관리에 유용하다

 

-String으로 캐스팅

class Temp{
    private Object data = null;
    public Object getData(){
        return data;
    }
    public void setData(Object obj){
        this.data = obj;
    }
}
class Temp2{
    private String data = null;
    public String getData(){
        return data;
    }
    public void setData(String obj){
        this.data = obj;
    }
}
public class Test048 {
    public static void main(String[] args) {
        Temp2 t2 = new Temp2();
        t2.setData("HelloWorld"); //스트링만 인스턴스로 저장 할 수 있음 (스트링은 상속불가)
        String l2 = t2.getData();  //casting 불필요

        Temp t = new Temp();
        t.setData("HelloWorld"); //모든 인스턴스로 저장할 수 있음
        String l = (String) t.getData();   //캐스팅 필요 
    }
}

6. Generic : 인스턴스 내부의 자료형을 동적으로 지정할 수 있음.

- Object + 구체적 자료형 결합

-<   > 안에 지정 가능한 타입은 참조형 변수 타입이어야 한다.(자료형 안됨)

- System.out.print로 호출하면 자동으로 toString이 호출되도록 약속되어 있다.

class Temp< T extends Object>{
    private T data = null;
    public T getData(){return data;}
    public void setData(T data){this.data = data;}
}
public class Test048 {
    public static void main(String[] args) {
        Temp<String> t = new Temp<String>();//참조형 변수만 가능, String, integer, double
        t.setData("HelloWorld");
        System.out.println(t.getData());

        Temp<Object> t2 = new Temp<Object>();
        t2.setData("HelloWorld");
        String l2 = (String) t2.getData();
        System.out.println(t2.getData());
    }
}//>> 결과값 : HelloWorld HelloWorld

-Integer : int 클래스

-Double : double 클래스 있음

public class Test054 {
    public static void main(String[] args) {
        Object ob = new Integer(100);
        Object ob2 = new Double(3.14);

        int i = ((Integer) ob).intValue();
        //왜 ? 함수 호출을(Integer)ob는 toString으로 String값이 넘어옴
        System.out.println(i);

        double j = ((Double)ob2).doubleValue();
        System.out.println(j);
    }
}

 

7. AutoBoxing 

Integer i = 100;
Object t = 200; //object 변수에서도 autoboxing 동작함 , JDK 1.5에서 추가
System.out.println(i.getClass().getName());
System.out.println(t.getClass().getName());
//결과값 : java.lang.Integer java.lang.Integer

-Integer i = 100; => Integer i = new Integer(100); 로 컴파일러가 자동으로 바꿔줌

-값을 wrapper 클래스에 대입하는 코드는 자동으로 인스턴스 생성하여 값을 감싸줌 : Auto boxing

 

8.AutoUnboxing

Integer i = 100; //Integer i = new Integer(100);로 자동 줄바꿈
int j = i;  //i.intValue();
System.out.println(j);//>> 결과 100

Object t = 200;
int k = t; //error => object타입으로 오토박싱된 인스턴스는 언박싱되지 않는다 
//t.intValue()로 호출할 수 없다 -> JDK 1.5에서 추가됨

 

#근데 공부하다 보니 캐스팅과 박싱의 차이는 뭘까가 궁금해짐

-캐스팅은 단순히 타입 a -> 타입 b 

-박싱은 원시 타입(boolean, char) -> 참조 타입(string, file)

-char 주워담아서 박싱하면 스트링 되고 , 스트링 박스를 언박싱하면 char가 된다

 

9. Command Pattern

interface ICalc{
    public int execute(int i);
}

class AddCalc implements ICalc{
    private int data;
    public AddCalc(int data) {
        this.data = data;
    }

    @Override
    public int execute(int i) {
        return i+data;
    }
}
//쓰임 당하는 입장에서 쓰는 쪽에게 어떤 의견 제시하는 통로 필요 : 어노테이션
// 이것을 체계화 한 것이 1,5 이후에 도입된 Annotation 개념이 된다.
interface PrintStarts{} //어노테이션 인터페이스의 조상뻘 개념

class MinusCalc implements ICalc, PrintStarts{
    private int data;
    public MinusCalc(int data) {
        this.data = data;
    }
    @Override
    public int execute(int i) {
        return i-data;
    }
}
public class Test054 {
    public static void main(String[] args) {
        ICalc i = new AddCalc(3);
        int r = 5;
        r = i.execute(r);
        System.out.println(r);

        ICalc[] ls = new ICalc[5];
        ls[0] = new AddCalc(2);
        ls[1] = new MinusCalc(3);
        ls[2] = new AddCalc(6);
        ls[3] = new MinusCalc(1);
        ls[4] = new AddCalc(7);

        int y = 10;
        for (int j = 0; j < ls.length; j++) {
            y = ls[j].execute(y);
            if(ls[j]instanceof PrintStarts){
                System.out.print("**");
            }
            System.out.println(y);
        }
    }
}
/*
일반적으로 자료값은 변수로, 동작은 함수로 만든다.
동작을 하나의 인스턴스로  수행하게 하는 경우가 있다.
- 이런 설계기법을 Command Pattern이라고 한다.
리스트같은데 인스턴스들을 저장하여 매크로처럼 사용 할 수 있다.
 */

10. Build

class Temp1{
    int data = 0;
    // 아래 코드의 t와 this가 가리키는 대상은 같다.
    // 따라서 t.add(10)은 10을 더한 후에 t로 바꿔 쓸 수 있다.
    // StringBuffer의 append에서 볼 수 있다.
    Temp1 add (int i){
        data += i;
        return this;
    }
}
public class Test057 {
    public static void main(String[] args) {
        Temp1 t = new Temp1();
        t.add(10).add(10).add(100);
        System.out.println(t.data);
    }
}//결과 : 120

11. String Buffer Class

public class Test057 {                                   
    public static void main(String[] args) {         
        StringBuffer sb = new StringBuffer();             
        sb.append("apple");       
        sb.append("banana");        
        String l = sb.toString();       
        System.out.println(l);                                                                       
        System.out.println("apple" + "banana");
        //코드는 컴파일러가 new StringBuffer().append("apple").append("banana").toString
        //방식으로 한줄마다 new StringBuffer가 동작하지만 위의 코드는 한번만 동작
    }                     
}//applebanana applebanana

12.String vs StringBuffer Test

public class Test057 {
    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < 100000; i++) {
            sb.append("apple");
        }//StringBuffer : 하나의 인스턴스
        long end = System.currentTimeMillis();
        System.out.println(end - start);
        start = System.currentTimeMillis();
        String st = new String("");
        for (int i = 0; i < 100000; i++) {
            st += "apple";
        }//String : 다수의 인스턴스
        end = System.currentTimeMillis();
        System.out.println(end - start);
    }
}//결과값 : 8 11645 //StringBuffer가 훨씬 좋음

-java -verbosegc 클래스 이름 통해 가비지 콜렉터 과정을 볼 수 있음

-메모리가 부족할 때 메모리를 비우고 확보하는 일 모니터링

 

13.String

-SubString();

String l = "HelloWorld";
System.out.println(l.substring(2,5)); //llo

 -indexOf(); : 만약 없는 문자열 찾을 때는 -1 리턴/ 문자열 안의 부분 문자열 위치를 리턴

String l = "HelloWorld";
System.out.println(l.indexOf("or")); //>>6

-starsWidth(); / endsWidth(); 시작이나 끝 문자열이 매개변수값과 같으면 true 아니면 false

String l = "HelloWorld";
System.out.println(l.startsWith("Hell"));
System.out.println(l.endsWith("ld")); //true true

-toCharArray(); : String을 char 배열로

String l = "HelloWorld";
char[] ch = l.toCharArray();
for (int i = 0; i < ch.length; i++) {
	System.out.println(ch[i]);
    }//결과값 : H e l l o W o r l d

문제

배열의 최대값 구하기

public class Test045 {
    public static void main(String[] args) {
        int[] i = new int[]{4,9,6,5};
        int max = i[0];
        for (int j = 1; j < i.length; j++) {
            if(max < i[j]){
                max = i[j];
            }
        }
        System.out.println(max);
    }
}//>>9

제너릭 연결리스트

package node;
class Node<T>{
    T data = null;
    Node<T> next = null;
    Node(T i, Node<T> n){
        data = i;
        next = n;
    }
}
class LinkedList<X>{
    private Node<X> head = null;
    private Node<X> tail = null;
    public LinkedList() {
        this.head = new Node<>(null, null);
        this.tail = head;
    }
    public LinkedList<X> add(X input){
        tail.next = new Node<>(input, null);
        tail = tail.next;
        return this;
    }
    public void print(){
        for(Node<X> n = head.next; n != null; n = n.next){
            System.out.println(n.data);
        }
    }
}
public class MyLinkedList {
    public static void main(String[] args) {
        LinkedList<String> ll= new LinkedList<>();
        ll.add("test").add("this").add("how");
        ll.print();
        LinkedList<Integer> l2 = new LinkedList<>();
        l2.add(3).add(2);
        l2.print();

    }
}

String의 indexOf와 동일한 동작 하게

package index;

class Finder{
    public static int indexOf(char[] operand, char[] operator) {
        int odLenth = operand.length;
        int otLenth = operator.length;
        int idx = -1;
        for (int remainder = odLenth - otLenth;  remainder >= 0; remainder--) {
            if(operand[remainder] == operator[0]){
                for(int i=1; otLenth-1 >= i; i++){
                    if(operand[remainder+i] == operator[i]){
                        if(i == otLenth-1){
                            idx = remainder;
                            break;
                        }
                    }else {
                        break;
                    }
                }
            }
        }
        return idx;
    }
}
public class MyIndexOf {
    public static void main(String[] args) {
        int idx = Finder.indexOf("Hedoerrdwld".toCharArray(), "sdadsadsadorw".toCharArray());
        System.out.println(idx); 
    }
}

Day 5

1. Casting :  instanceOf 키워드를 이용해서 알 수 있다.

-Casting Error : t가 가르키고있는 B라는 인스턴스가 존재해야만 캐스팅이 가능해짐

class A{
}
class B extends A {
    public void print() {
        System.out.println(100);
    }
}
public class Test061 {
    public static void main(String[] args) {
        A t= new A();
        if*
        B t2 = (B) t;
        t2.print();
    }
}
//결과값 : Exception in thread "main" java.lang.ClassCastException: 
javaclass.A cannot be cast to javaclass.B at javaclass.Test061.main(Test061.java:16)

-instanceof : 캐스팅 에러 미리 방지

 A t= new A();
//(B)t 이것이 가능하면 true/ 아니면 false
if (t instanceof B){
	B t2 = (B) t;
    t2.print();    
}

-boolean : 비교연산 값을 리턴 

-거의 모든 연산은 같은 자료형 끼리 가능

-double간의 연산 비교는 정확하지 않는다.

public class Test061 {
    public static void main(String[] args) {
       boolean i = true;
       boolean j = false;
        System.out.println(10 < 5);
        System.out.println(10 / 3); // 나머지를 뺀 몫이 나옴
        System.out.println(10 % 3); //나머지를 구하는 연산자
        System.out.println(10.0 / 3);
        System.out.println(3.33333333 * 3 == 10.0);
        System.out.println(3.3333333333333335 * 3== 10.0); //Double 연산은 값을 보장할 수없다. 오차발생
    }// c는 정수값 0 은 false, 0이아닌 모든 정수는 true
}// if(100)참
//결과값 : false 3 1 3.3333333333333335 false true

2.Package

-클래스의 묶음, 파인 맨 위에 지정

-한 파일안에 선언한 모든 클래스는 지정된 패키지 속함

-패키지를 지정하지 않으면 Unnamed 패키지에 소속, 사용시 제약이 많음

- javac -d . Test061.java

대상폴더아래 패키지이름으로 폴더생기고, 그 아래에 class파일이 들어간다.

package javaclass;

public class Test061 {
 public int print(){
     return 200;
 }   
 public int print2(int i ){
     return 300 * i;
 }
 public static int print3(){
     return 100;
 }// 패키지가 지정된 클래스 컴파일 : javac -d [폴더위치] Test061.java
}

3.import

-다른 패키지 클래스는 반드시 명시

-만일 그래도 못찾으면 class 를 명시해야한다. 

javac -classpath C:\A\ Test061.java

-실행 : java -classpath .;C:\A\ Test061

     -> 현재 폴더 명시해줘야함

-classpath 옵션을 안주면 -classpath . 이 자동으로 붙는다.

-Test 061A의 멤버변수가 접근되는지 살펴본다 : protected, friendly(default) -> 다른패키지에서 접근 x

-Static한건 클래스가 로딩될떄 메모리에 할당 non-Static한건 인스턴스가 생성될떄 메모리에 할당

-클래스로딩은 딱 한번만일어나므로 Static한건 딱 한개만 존재함

-Static Initializer:  클래스가 로딩되는 시점에 실행되고 클래스를 강제로 로딩하려면 Class.forName("클래스명");함수를 이용한다.

package practice;

import javaclass.Test061;

public class Test064 {
    public static void main(String[] args) {
        Test061 t = new Test061();
        t.print();
    }
}
package temp;

public class Test066A{
	//static initializer라 한다. 클래스가 로딩되는 시점에 호출됩니다.
	static{
		System.out.println("Test066A loaded");
	}
	public int print(){return 200;}
	public int print2(int i){return 300*i;}
	public static int print3(){return 100;}
} // C:\a\ 아래에 컴파일하자. javac -d c:\A\ Test066A.java
public class Test066{
	public static void main(String[] args) throws Exception{
		//클래스를 찾아내서 해당 클래스를 강제로 메모리에 로딩시킨다.
		//찾아낸 코드의 static initializer가 동작하게됨
		Class<?> cls = Class.forName("temp.Test066A");
		/* Class : 로딩된 클래스의 관리자 역할을한다.
		   cls.newInstance() : cls가 관리하는 temp.Test066A의 인스턴스를 생성한다.
		   obj.getClass().getName() : obj가 가리키는 인스턴스를 생성시킨 클래스 명 //임포트없이도 다른 패			 키지의 인스턴스를 생성 할 수 있음
		*/
		Object obj = cls.newInstance(); //new를 쓰지않고 인스턴스를 만드는방법

		System.out.println( obj.getClass().getName());
	}
}

 

import java.lang.reflect.Method;

public class Test066_2{
    public static void main(String[] args) throws Exception{
     Class<?> cls = Class.forName("temp.Test066A");
     Object obj = cls.newInstance();

     /* getMethods() : 클래스안에서 선언된 함수에 대한 포인터들을 추출한다.
     
      */
     Method[] mtds = cls.getMethods(); //함수 포인터
        for (int i = 0; i < mtds.length; i++) {
            System.out.println(mtds[i]);
        }
    }
}
/*결과값 : Test066A loaded
public int temp.Test066A.print()
public int temp.Test066A.print2(int)
public static int temp.Test066A.print3()
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()*/
package javaclass;

import java.lang.reflect.Method;

public class Test066_3 {
    public static void main(String[] args) throws Exception{
        Class<?> cls = Class.forName("temp.Test066A");
        Object obj = cls.newInstance();
// Method는 C의 함수포인터의 역할을 한다.
//        cls.getMethods()는 모든 멤버함수의 포인터를 넘긴다.
//        cls.getMethod(...) : 단하나의 멤버함수의 포인터를 넘기다.
//        ...에는 함수이름, 매개뱐수의 형태를 명시한다.
//       Method mtd = cls.getMethod("print");
        Method mtd = cls.getMethod("print2", int.class);
        System.out.println(mtd);
        Object r = mtd.invoke(obj, 20);
        System.out.println(((Integer)r).intValue());
    }
}
/*결과값 : Test066A loaded
public int temp.Test066A.print2(int)
6000*/
package javaclass;

import java.lang.reflect.Method;

public class Test066_3 {
    public static void main(String[] args) throws Exception{
        Class<?> cls = Class.forName("temp.Test066A");
//        Object obj = cls.newInstance();
// Method는 C의 함수포인터의 역할을 한다.
//        cls.getMethods()는 모든 멤버함수의 포인터를 넘긴다.
//        cls.getMethod(...) : 단하나의 멤버함수의 포인터를 넘기다.
//        ...에는 함수이름, 매개뱐수의 형태를 명시한다.
//       Method mtd = cls.getMethod("print");
        Method mtd = cls.getMethod("print3");
        System.out.println(mtd);
        Object r = mtd.invoke(cls);
        System.out.println(((Integer)r).intValue());
    }
}

/*결과값 : Test066A loaded
public static int temp.Test066A.print3()
100*/

4.annotation

  • 클래스나 method에 붙임
  • 클래스가 컴파일되거나 런될때, annotation의 유무나 annotation 설정된 값을 통하여 클래스가 좀더 다르게 실행
    • 설정파일처럼 설정하는 경우도
  • 사용자 annotation 
    • annotation 정의
    • annotation를 class에서 사용
    • annotation을 이용해 실행
package temp;

public class Test067 {
    @PrintStars
    public int print(){
        return 100;
    }
}// javac -d C:\a\ -classpath C;\A\ Test067.java  -> import할 파일 위치

-----------------------------------------------------------------------------------
package temp;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.RUNTIME)
public @interface PrintStars {
}
-----------------------------------------------------------------------------------
package javaclass;

import temp.PrintStars;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

public class Test067_2 {
    public static void main(String[] args) throws Exception {
        Class<?> cls = Class.forName("temp.Test067");
        Object obj = cls.newInstance();
        Method mtd = cls.getMethod("print");
        Annotation anot = mtd.getAnnotation(PrintStars.class);
        Object r= mtd.invoke(obj);
        if(anot.toString().equals("@temp.PrintStars()")){
            System.out.println("**");
        }
        System.out.println(((Integer)r).intValue());
        System.out.println(anot);
        System.out.println(mtd);
    }
}// javac Test067_2.java 컴파일시
//java -classpath C:\A\;. Test067_2     //내가 실행시킬 위치는 뒤  불러올거는 클래스패스 뒤, 여러개 불러올거면 ;로구분

/*결과값 : **
100
@temp.PrintStars()
public int temp.Test067.print()*/

5.java.util.*

-List

  • arraylist : 내부 배열 이용 , 속도 빠름, 중간 삭제 수정 힘듬
  • LinkedList : node 이용, 속도 느림, 중간 삭제 수정 쉬움(포인터만 바꿔주면됨)
  • list 특징 : 1. 중복 허용 2. 순서 유 3. stack, queue 유용
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
//ArrayList 속도가 빠르다. 내부적으로 배열을 사용
//배열을 사용하기때문에 속도는 빠른데, 중간중간 삭제가일어나면 비효율적이다.
//LinkedList Node를 이용하기에 단순하게 쌓는 속도는 느리다.
//중간에 추가 삭제가 빈번한 경우에는 용이하다.
// 둘 다 List를 상속한다. List를 상속받은 클래스는 특징이 존재한다.
// - 중복되는 걸 허용한다.검색시에 들어간 순서대로 나온다.(순서대로 보관한다.)->스택이나 큐 만드는데 용이하다.
public class Test068 {
    public static void main(String[] args) {
        List<String> l = new LinkedList<>();
        l.add("apple");
        l.add("banana");
        l.add("orange");
        l.add("kiwi");

        for (String t : l) {
            System.out.println(t);
        }
    }
}//결과값 : apple banana orange kiwi

-Set

  • treeset : 트리를 이용해 검색 속도가 list보다 월등
  • hastset : 해쉬 알고리즘을 이용해 기억 장소 할당
  • set 특징 : 1. 중복 허용 x 2.순서 x
package javaclass;

import java.util.Set;
import java.util.TreeSet;
// Set 인터페이스를 상속받은 것 : TreeSet, HashSet
// 공통특징 : 순서 개념이 없다. 중복을 허용하지 않는다.
// 저장할때 용이 -> 검색속도가 List보다 월등함
// TreeSet : 트리를 이용하여 보관, HashSet은 Hash알고리즘을 이용
public class Test069 {
    public static void main(String[] args) {
        Set<String> l = new TreeSet<>();
        l.add("apple");
        l.add("banana");
        l.add("orange");
        l.add("kiwi");
        l.add("apple"); //중복된값

        for (String t : l) {
            System.out.println(t);
        }
    }
//결과값 : banana orange apple kiwi

-향상된 for문의 표준 검색 방법

Iterator<String> it = l.iterator();
        while (it.hasNext()) {
            String next =  it.next();
            System.out.println(next);
        }

//iterator를 이용한 삭제
package javaclass;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
// Set 인터페이스를 상속받은 것 : TreeSet, HashSet
// 공통특징 : 순서 개념이 없다. 중복을 허용하지 않는다.
// 저장할때 용이 -> 검색속도가 List보다 월등함
// TreeSet : 트리를 이용하여 보관, HashSet은 Hash알고리즘을 이용
public class Test069 {
    public static void main(String[] args) {
        Set<String> l = new HashSet<>();
        l.add("apple");
        l.add("banana");
        l.add("orange");
        l.add("kiwi");
        l.add("apple"); //중복된값

        Iterator<String> it = l.iterator();
        while (it.hasNext()) {
            String next =  it.next();
            if(next.indexOf("an") != -1){
                it.remove();
            }
            System.out.println(next);
        }
    }
}

-Map

  • map 특징 : 1.순서 x 2.중복 x(덧 씌워짐)
package javaclass;

import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

//map도 순서개념이 없으며 반드시 key = value 형태로 저장되야함 사전과 같은 형태
//put에 함수로 저장, get 함수로 key에 해당하ㅏ는 value를 뽑아낸다.
//list, Set, Map 형태로 뭔가 저장하는 형태를 흔히 Collection이라고 한다.
public class Test070 {
    public static void main(String[] args) {
        Map<String, String> map = new Hashtable<>();
        map.put("apple", "사과");
        map.put("banana", "바나나") ;
        map.put("orange", "오렌지") ;
        map.put("kiwi", "키위") ;
        map.put("banana", "브내으너") ;

         String value = map.get("apple");
        System.out.println(value);

        Set<String> keys = map.keySet();
        Iterator<String> it = keys.iterator();
        while (it.hasNext()) {
            String next = it.next();
            String v = map.get(next);
            System.out.println(next+ ", " + v);
        }

        System.out.println(map);
    }
}/*
결과값 : 사과
banana, 브내으너
apple, 사과
orange, 오렌지
kiwi, 키위
{banana=브내으너, apple=사과, orange=오렌지, kiwi=키위}
*/

-Math.random();

package javaclass;

public class Test071 {
    public static void main(String[] args) {
        for (int i = 0; i < 20; i++) {
            double d = Math.random(); // 0부터 1까지의 소수값을 랜덤하게 출력한다.

            int a = (int) (d * 100); // 0~100까지
            System.out.println(a);
        }
    }
}

-Throw

    -각종 에러는 클래스로 구형

    -코드 수행시 에러가 발생하면 해당 예외클래스의 인스턴스를 throw해버린다

    -예외는 함수 수행 시에 발생되고, 함수에 그 사실을 명시

    -생성된 예의처리 못할 시 프로그램 종료

package javaclass;

class TempException extends RuntimeException{}
public class Test074{
    public static void main(String[] args) {
        int i = 0;
        if(i==0){
            throw new TempException();
        }
        System.out.println(0);
    }
}
package javaclass;

//연료 고갈이라는 에러를 클래스로 명시
class FuelException extends Exception{}
// Exception이 깐깐하다 : 컴파일이 안된다....
// 함수 안에서 에러가 발생 할 수 있다면 그 사실을 선언부에 명시해야 컴파일된다.
public class Test074{
    public void carDrive(int fuel) throws FuelException{ //thorws로 연료고갈이 생길수 있음을 명시
        if(fuel == 0){
            throw new FuelException();
        }
        System.out.println("gogo");
    }
    public static void main(String[] args) {
        Test074 t = new Test074();
        //throws FuelException으로 선언된 함수를 호출할 때는 반드시 에러가 발생할 수 이는 영역을 try{...}로 감싸준다.
        //try에는 반드시 1개이상의 catch가 있어야한다.
        //에러가 발생되면 에러 인스턴스를 throw한다.
        //catch(FuelException e)에 있는 e 변수가 발생된 에러 인스턴스를 가리 킬 수 있으면 catch에 딸린{...} 영역이 동작한다.
        //...에는 에러를 수습 할 수 있는 코드가 들어가는것이 바람직하다.
        //catch (Exception e)써도 됨 상속받기 떄문에 
        try {
            t.carDrive(100);
        } catch (FuelException e) {
            System.out.println("견인차를 불러라");
        }
    }
}
package javaclass;

class FuelException extends Exception{
    public void solve(){
        System.out.println("견인차를 불러라");
        //에러 처리
    }
}
public class Test074{
    public void carDrive(int fuel) throws FuelException{ 
        if(fuel == 0){
            throw new FuelException();
        }
        System.out.println("gogo");
    }
    public static void main(String[] args) {
        Test074 t = new Test074();
        try {
            t.carDrive(100);
        } catch (FuelException e) {
            e.solve();
        }
    }
}

문제

1. 복권 뽑기 1

public static int[] randomArray(int i, int max) {
        Set<Integer> si = new HashSet<>();
        while(si.size() < i){
            si.add((int)(Math.random()* max));
        }
        Object[] arr = si.toArray();
        int[] result = new int[i];
        int start = 0;
        for(Object obj : arr){
            result[start] = (int) obj;
            start++;
        }
        return result;
    }

2. 복권 뽑기2

   public static int[] randomArray2(int i, int max){
        int[] total = new int[max+1];
        int[] result = new int[i];
        for (int j = 0; j <= max; j++) {
            total[j] = 0;
        }
        int counter =0;
        while (counter < i) {
            int rand = (int) (Math.random() * max);
            if(total[rand] == 0){
                result[counter] = rand;
                counter ++;
                total[rand] = 1;
            }
        }
        return result;
    }

3.리스트 출력

    public static String collectionString(List<String> ls) {
        String result;
        if(ls.isEmpty()){
            return "[]";
        }else {
            StringBuilder sb = new StringBuilder();
            sb.append("[");
            int start= 1;
            int end = ls.size();
            for(String t : ls){
                sb.append("'");
                sb.append(t);
                sb.append("'");
                if(start == 1 && end ==1){
                    start++;
                    continue;
                }
                start++;
                if(start > end) {
                    break;
                }else {
                    sb.append(",");
                }
            }
            sb.append("]");
           result = sb.toString();
        }
        return result;
    }
}
// 2가지 이상의 다른 방법으로 구현 1가지는 collection 금지
public class Test072_HW {
    public static void main(String[] args) {

        int[] rl = HW.randomArray2(10, 100);
        for (int i = 0; i < rl.length; i++) {
        System.out.println(rl[i]);
        }

        List<String> ls = new ArrayList<>();
        ls.add("apple");
        ls.add("banana");
        ls.add("orange");
        ls.add("kiwi");
        String l = HW.collectionString(ls);
        System.out.println(l);
    }
}

첫 주 끝.. 알고리즘 꼭 다시 풀어보기 / 자동차 패키지 만들어보기 !

반응형

'Language Study > Java' 카테고리의 다른 글

제주에서 자바_Week2_2  (0) 2019.07.24
제주에서 자바_Week2_1  (0) 2019.07.22
4. 클래스  (0) 2019.05.29
3. 참조 타입  (0) 2019.05.28
2. 조건문 & 반복문  (0) 2019.05.27
반응형


자바는 객체 지향 프로그래밍 : 각각의 컴퓨터 부품을 만들고 그 부품들을 조립하여 컴퓨터를 만들 듯이 객체를 만들고 그 객체들을 

조립하여 소프트웨어를 만드는 기법이다.  


<특징>

-캡슐화 (encapsuation) : 관련된 데이터와 알고리즘(코드)이 하나의 묶음으로 정리 

-상속 : 이미 작성된 클래스(부모 클래스)를 이어 받아 새로운 클래스(자식 클래스)를 생성하며, 기존의 코드를 재사용할 수 있는 강력한 기법

-객체(Object) : 객체 지향 기술의 핵심 , 객체 안의 변수를 필드(field)라 부르고, 객체 안의 함수를 메소드(method)라 부른다

  하나의 객체는 필드와 메소드로 이루어진 SW묶음

-메세지(Message) : 객체는 메세지를 통해 다른 객체와 통신하고 상호 작용 / 매개변수(parameter)의 형태로 전달


Car.setSpeed(100);


Car : 메세지를 받는 객체

setSpeed : 매세지의 이름

(100) : 메세지의 매개변수


1.클래스(Class)

: 특정한 기능을 가진 객체를 생성하게 해주는 설계도

-클래스로 부터 만들어진 객체 : 해당 클래스의 인스턴스(instance) 


#예시

-자바에서는 일반적으로 하나의 소스 파일에는 하나의 클래스만을 담는 것이 원칙이다. 

 만일 하나의 파일에 여러 클래스가 있을 경우 클래스 중 main()이 들어있는 클래스의 이름과 소스 파일명이 같아야한다.


class Car{
    String color; //필드 정의
    int speed;
    int gear;
 
    void print(){ //메소드 정의
        System.out.println("<" + color + "," + speed + "," + gear + ">");
    }
}
 
class CarTest{
    public static void main(String[] args){
        Car myCar = new Car(); //객체 생성
 
        myCar.color = "red" ; //객체 필드 변경
        myCar.speed = 0;
        myCar.gear = 1;
 
        myCar.print(); //객체 메소드 
    }
}
cs


-클래스 구성요소

= 필드 : 객체의 데이터가 저장되는 곳, 데이터 선언 및 초기화 하는 공간(int fieldName;)

-객체의 고유 데이터, 상태 정보를 저장하는 곳

-생성자와 메소드 전체에서 사용되며 객체가 소멸되지 않는 한 객체와 함께 존재

-초기화 하지 않으면 각 자료형의 기본값으로 초기화 


<필드선언>

-생성자 선언과메소드 선언의 앞 뒤 어떤 곳에서도 필드 선언 가능

-단, 생성자와 메소드 내부에서는 선언될 수 없음(생성자, 메소드 내부의 변수 = 지역 변수)


<필드 선언>

-필드 값을 읽고 변경하는 작업

-클래스 내부에서는 단순히 필드 이름으로 읽고 변경

-클래스 외부에서는 클래스로부터 객체 생성 후 사용(일반적으로 직접 접근 못하게 캡슐화)


= 생성자 : 객체 생성 시 초기화 역할 담당, new 연산자(Car car = new Car;)

-new 연산자로 호출되는 특별한 중괄호 블록

-객체 생성 시 초기화 담당

-필드를 초기화하거나 메소드를 호출해서 객체를 사용할 준비

-클래스 이름으로 되어 있고 리턴 타입이 없음


<생성자 생성>

-생성자를 선언 안해도 기본적으로 컴파일시 디폴트 생성자가 생성됨

-생성자는 메소드와 비슷한 모양을 가지나, 리턴 타잆이 없고 클래스 이름과 동일

-클래스에 생성자가 명시적으로 선언되어 있을 경우 반드시 선언된 생성자를 호출해서 객체를 생성

-하나라도 인자값을 가진 다른 생성자를 호출할 경우 디폴트 생성자는 자동으로 생성되지 않으므로 디폴트 생성자를 호출하기 위해선 디폴트 생성자도 명시적으로 선언해줘야 함


<필드 초기화>

-필드를 선언할 때 초기값을 주면 동일한 클래스로부터 생성되는 객체들은 모두 같은 데이터를 가짐

-객체 생성 시점에 외부에서 제공되는 다양한 값들로 초기화 되어야 한다면 생성자에서 초기화 해야 함


<관례적으로 필드와 동일한 이름을 갖는 매개변수 사용>

-이 경우 필드와 매개변수 이름이 동일하므로 생성자 내부에서 해당 필드에 접근할 수 없다

-why? 동일한 이름의 매개 변수가 사용 우선순위가 높다. 따라서 this 를 사용한다.

-this는 객체 자신의 참조


<생성자 오버로딩>

-매개변수를 달리하는 생성자를 여러 개 선언하는 것

-오버로딩 시 주의점은 매개 변수의 타입과 개수 그리고 선언된 순서가 똑같을 경우 매개 변수 이름만 바꾸는 것은 오버로딩이라고 볼 수 없음


<다른 생성자 호출(this())>

-생성자 오버로딩이 많아질 경우 생성자 간의 중복된 코드 발생

-이 경우 필드 초기화한 내용은 한 생성자에만 집중적으로 작성하고 나머지 생성자는 초기화 내용을 가지고 있는 생성자를 호출하는 방법으로 개선

-생성자에서 다른 생성자 호출할 때 this() 코드 사용

-this()는 자신의 다른 생성자를 호출하는 코드, 반드시 생성자 첫줄에서만 허용


public Cat(String name, String breed){
    this.name = name;
    this.breed = breed;
}
public Cat(String name, String breed, int age){
    this(name,breed);
    this.age = age;
}
cs

= 메소드 : 객체의 동작에 해당하는 실행 블록 (void methodName(){..})


<클래스명 작성 규칙>

작성규칙

하나 이상의 문자로 이루어져야 한다

Car, SportsCar

첫 번째 글자는 숫자가 올 수 없다

Car, 3Car(x)

'$','_' 외의 특수 문자는 사용할 수 없다

$car, _Car, @Car(x), #Car(x)

자바 키워드(예약어)는 사용할 수 없다

int(x), for(x)

단일 단어 => 첫문자는 대문자 혼합 단어 => 각 단어 첫글자는 대문자


<메서드 선언>

[접근 제한자] [기타 제어자] 반환자료형 메서드명(매개변수){
    //return 리턴값;
}
cs

<메서드 선언부 = 메서드 시그너처>


<리턴 타입>

-메서드가 실행 후 리턴하는 값의 타입

-메서드 실행 후 결과를 호출한 곳에 넘겨줄 경우에는 리턴 값이 있어야 함

-리턴 값의 타입은 선언부의 반환자료형과 동일해야 함

-리턴 타입이 있다고 해서 반드시 리턴값을 변수에 저장할 필요 없음

-void 타입의 경우 리턴문 없이 사용 가능


<매개 변수의 수를 모를 경우>

-매개 변수를 배열 타입으로 선언

-… 으로 선언후 리스트 나열

public int sum(int ... args){
    return IntStream.of(args).sum();
}
cs



<메서드는 클래스 내/외부의 호출에 의해 실행>

-클래스 외부에서 호출할 경우 우선 클래스로부터 객체 생성
-클래스 참조변수 = new 클래스(매개값); * 참조변수.메서드(매개값); (리턴값 없거나, 받지 않을 경우) * 타입 변수 = 참조변수.메서드(매개값); (리턴값 받고 싶을 때)

<메서드 오버로딩>

-클래스 내에 같은 이름의 메서드를 여러 개 선언하는 것
-매개 변수의 타입, 개수, 순서 중 하나가 달라야 한다 (시그니처가 달라야 한다)


#예시

import java.util.Scanner;
 
public class InstanceMemberEx01 {
    int a, b; // 인스턴스 필드
    
    public InstanceMemberEx01(int c, int d) { // 생성자(필드 초기화)
        a = c; b = d;
    }
    
    public void add(){ // 인스턴스 메소드
        System.out.println(a+b); 
    }
    
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("2개의 정수를 입력");
        int num1 = sc.nextInt();
        int num2 = sc.nextInt();
        InstanceMemberEx01 im = new InstanceMemberEx01(num1, num2); // 인스턴스 생성 및 생성자 호출
        im.add(); // 인스턴스 메소드 호출
    }
}
 
cs


##여기 까지 요약

1. 인스턴스 멤버(메소드, 필드)는 인스턴스를 생성해야지만 사용이 가능하다.(클래스멤버와의 차이점)
2. this는 자기 자신을 의미하는 키워드이다.
3. this.은 필드와 매개변수가 동일할 때 주로 사용되며 인스턴스 멤버임을 명확하게 해준다.
4. this()는 자기 자신의 생성자를 호출할 때 사용하며 호출하는 곳의 첫 번째 문장에 작성해야 한다.


2. 정적 멤버와 static

-정적(static)멤버는 클래스에 소속된 멤버(필드, 메소드) 의미

-static이라는 키워드가 붙은 필드 or 메소드가 정적 멤버이다.


<정적 멤버 선언>

-정적 필드 선언

static 타입 필드 [=초기값]; //static int a;
cs

-정적 메소드 선언

static 리턴타입 메소드([매개변수]){...}//static void sum(){..}
cs


-static으로 생성된 필드(전역 변수)는 static이라는 메모리 영역에 저장되어 프로그램이 종료될 때 까지 메모리상 남음

=몇 개의 인스턴스를 생성하든 클래스 당 단 1개의 값 가짐


public class StaticMemberEx01{
    static int a; //정적 필드
    int b;          //인스턴스 필드
 
    StaticMemberEx01(int a, int b){
        this.a = a; //매개값 할당
        this.b = b; //매개값 할당
    }
    public String print(){
        String value = "a : " + a + ", b : " +b;
        return value;
    }
    
    public static void main(String[] args){
        StaticMemberEx01 sm = new StaticMemberEx01(1,2); 
        StaticMemberEx01 sm1 = new StaticMemberEx01(2,3);
        StaticMemberEx01 sm2 = new StaticMemberEx01(3,4);
        System.out.println(sm.print()); // a : 3, b : 2
        System.out.println(sm1.print()); // a : 3, b : 3
        System.out.println(sm2.print()); // a : 3, b : 4
    }
}
  //인스턴스를 여러 번 생성하여도 메모리에서 한 번만 공간 할당하여 메모리 아
cs


반응형

'Language Study > Java' 카테고리의 다른 글

제주에서 자바_Week2_1  (0) 2019.07.22
제주에서 자바_Week1  (0) 2019.07.20
3. 참조 타입  (0) 2019.05.28
2. 조건문 & 반복문  (0) 2019.05.27
1. 타입, 연산자  (0) 2019.05.27
반응형

1. 참조 타입(reference type)

- 종류 : 배열, 열거, 클래스, 인터페이스

- 참조 타입 변수 -> 스택 영역에 생성되어 힙 메모리 영역의 번지(주소) 값 갖음.

- 주소 통해 객체를 참조한다 


2. 참조 변수 == , != 연산

-> 힙 영역의 객체 주소 ; 주소 값을 비교하는 것이 됨 / 동일 주소 값 => 동일한 객체 참조


3. 참조 타입 변수 null

-> 힙 영역의 객체를 참조하지 않는다 

-> null 값을 가질 경우 참조할 객체가 없으므로 -> 객체는 힙 메모리 영역에 생성X / 변수만 스택에 생성되 NULL 값 가짐

-> null 값을 가진 참조 타입 변수 ==, != 연산은 기본 타입과 동일

-> 참조 타입 변수가 null 값 가진 상황에서 프로그램 실행 경우(프로그램 실행 중 참조 타입 변수가 null값 가진 경우)

=> NullPointerException 예외 발생


4. String 타입

-문자열 저장하는 참조 타입

- 문자열 리터럴이 동일한 경우 객체 공유(new 연산자로 새로운 객체 생성 X -> 대입 연산자로 같은 문자열 저장)

- String 객체의 equals() 메소드 사용해 객체 상관없이 문자열 비교 

String x; // 기본값은 null 
 
= "hello"// 선언한 x에 문자열 값을 대입, " " (쌍따옴표) 사용
 
String y = "hello"// 선언과 동시에 문자열 저장 x == y 는 true
 
String z = new String("hello"); // 새로운 객체 생성, y == z 는 false 
 
if ( y.equals(z) ) {
 System.out.println("true"); // true 출력
 }
cs


5. 배열 

- 같은 타입 데이터를 메모리상에 연속적으로 나열시키고, 각 데이터에 인덱스(index)를 부여해 놓은 자료구조

- 인덱스  :첨자값, [](대괄호) 사용

// 대괄호의 위치 차이
int[] intArray; //타입[] 변수(배열명);
int intArray[]; //타입 변수(배열명)[];
 
//null로 초기화
String[] stringArray = null;
 
//값 목록을 가진 배열 생성
String[] names = {"홍길동","전지현","지수","보람"};
int[] scores = {80909433};
 
//new 연산자로 바로 배열 객체 생성
double[] doubleArray = new double[5]; //배열의 길이 지정 [0-4]
 
//컴파일 에러 
String[] names = null;
 
//배열 변수 선언
names = new String[] {"홍길동","전지현","지수","보람"};
cs


-{ } : 주어진 값들을 가진 배열 객체를 힙 메모리 영역에 생성, 배열 객체의 번지(주소) 리턴

- 배열 변수는 리턴된 번지를 저장하여 참조

- names[0] = "홍길동"


- 배열의 값 바꾸기 

String[] names = {"홍길동""전지현","지수","보람"};
System.out.println("names[0] >" + names[0]); //홍길동
names[0= "혜원";
System.out.println("names[0] >" + names[0]); //혜원
 
//배열 값 바꾸기는 " = " 대입 연산자 
cs


-배열 길이 

-배열에 저장할 수 있는 전체 항목 수

-배열 객체의 length 필드 (field) 읽어야 한다

-필드(field) : 객체 내부의 데이터

- 배열의 마지막 요소의 인덱스 배열 길이 : -1

int[] intArray = { 100200300};
int len = intArray.length;
System.out.println("배열 intArray의 길이는 : " + len);
cs


-다차원 배열 

/*타입[][] 변수 = new 타입[][]*/
int[][] scores = new int[2][];
scores[0= new int[2]; //01
scores[1= new int[3]'    //012
cs


/*타입[][] 변수 = {{값1, 값2..}, {값1, 값2..}}*/
int[][] scores = { {9588}, {9320} };
int scores = scores[0][0]; //95
int scores = scores[1][1]; //93
cs


6.열거 타입 선언

public enum 열거타입이름//첫 문자는 대문자, 나머지는 소문자 {
    열거 상수 선언 //열거 타임의 값 사용, 관례적으로 모두 대문자 작성 / 여러 단어 구성될 경우 단어 사이 밑줄(_)
                  //열거 객체로 생성, 해당 열거 타입의 열거 상수 개수만큼 객체가 열거 타입 객체 생성
}
 
public enum Month {
    JANUARY,
    FEBRUARY,
    MARCH,
    APRIL,
    MAY,
    JUNE,
    JULY,
    ...  //Month의 경우 JANUARY부터 DECEMBER까지 12개의 열거 상수는 힙 영역에 Month 객체로 
}
cs


7. 열거 타입 변수 

//열거타입 변수 : null 값도 저장할 수 있다.
Month thisMonth;
Month birthMonth;
 
Month thisMonth = Month.JUNE;
cs

-열거 상수 Month.JUNE과 thisMonth 변수는 서로 같은 Month 객체를 참조 : true 가 된다.


Month month1 = Month.JUNE;
Month month2 = Month.MARCH;
 
//name() : 객체가 가지는 문자열 리턴
String month1 = thisMonth.name(); //month = "JUNE"
 
//ordinal() : 전체 열거 객체 중 몇 번째 열거 객체 인지 알려줌
int ordinal = thisMonth.ordinal(); // ordinal = 5
 
//compareTo() : 주어진 열거 객체 기준으로 전후 몇 번째 위치하는지 비교 
int result1 = month2.compareTo(month1); //-3(매개값이 열거객체보다 순번이 빠르다면)
int result2 = month1.compareTo(month2); //3
 
//valueOf() : 매개값으로 주어진 문자열과 동일한 문자열 가지는 열거 객체 리턴
Month thisMonth = Month.valueOf("JUNE");
 
//values() : 열거 타입의 모든 열거 객체들을 배열로 만들어 리턴
Month[] months = Months.values();
for(Month month : months){
    System.out.println(month);
}//January ... december
cs


## 각 학생들의 점수를 입력받아 최고 점수 , 평균점수 구하는 프로그램

package firstproject;
import java.util.Scanner;
 
public class HelloWorld {
    public static void main(String[] args) {
        boolean run = true;
        int studentNum = 0;
        int[] scores = null;
        Scanner scanner = new Scanner(System.in);
        
        while(run) {
            System.out.println("============");
            System.out.println("1.학생수 | 2.점수입력 | 3.점수리스트 | 4.분석 | 5.종료");
            System.out.println("============");
            System.out.println("선택>");
            
            int selectNo = scanner.nextInt();
            
            if(selectNo==1) {
                System.out.println("학생수>");
                studentNum=scanner.nextInt();
                scores = new int[studentNum];
            }
            else if(selectNo==2) {
                for(int i = 0; i <studentNum; i++) {
                    System.out.println("scores["+i+"]>");
                        int score = scanner.nextInt();
                        scores[i] = score;
                }
            }
            else if(selectNo==3) {
                for(int i =0; i<studentNum; i++) {
                    System.out.println("scores["+i+"]"+scores[i]);
                }
            }
            else if(selectNo==4) {
                int max = 0;
                int sum = 0;
                double avg = 0;
                for(int i=0;i<studentNum; i++) {
                    sum+=scores[i];
                    if(scores[i]>max)
                        max=scores[i];
                }
                avg=(double)sum/studentNum;
                System.out.println("최고 점수 :"+max);
                System.out.println("평균 점수 :"+avg);
            }
            else if(selectNo==5) {
                run = false;
                System.out.println("프로그램 종료");
            }
        }
    }
}
cs


반응형

'Language Study > Java' 카테고리의 다른 글

제주에서 자바_Week2_1  (0) 2019.07.22
제주에서 자바_Week1  (0) 2019.07.20
4. 클래스  (0) 2019.05.29
2. 조건문 & 반복문  (0) 2019.05.27
1. 타입, 연산자  (0) 2019.05.27
반응형


1. 제어문 : 프로그램의 흐름을 바꾸는 역할 


2. 조건문 : 조건에 따라 문장이 수행됨(if, switch)

   -if문

# if문

if(조건식//true, false값을 산출하는 연산식, boolean 변수) {
    실행문;
    실행문;
//조건식 true이면 블록 실행, false이면 블록 실행x
}
cs


#if - else 문

if(조건식//true, false값을 산출하는 연산식, boolean 변수) {
    실행문;
    //조건문이 true면 실행
}else{
    //조건문이 false이면 
cs


#if - else if문 : 처리할 경우의 수가 셋 이상인 경

if(조건식1){
    //조건식 1이 참일 경우 실행
}else if (조건식2){
    //조건식2가 참일 경우 실행
}else{
    //위의 어느 조건도 만족하지 못할 경우 실행
}
cs


EX)

package firstproject;
 
public class HelloWorld {
    public static void main(String[] args) {
         int score = 70;
         
         if (score >= 90) {
             System.out.println("A+");
         }else if(score >= 80) {
             System.out.println("B+");
         }else {
             System.out.println("C+");
         }
    }
}
 
cs


#중첩 if문

if(조건식1){
    //조건식1이 참일 경우 실행
    if(조건식2){
        //조건식1과 조건식2가 모두 참일 경우 실행
    }else{
        //조건식1은 참, 조건식2는 거짓일 경우 실행
    }
}else{
    //조건식1이 거짓일 경우 실행
}
cs


EX2) 중첩 if문 

package firstproject;
 
public class HelloWorld {
    public static void main(String[] args) {
         int score = (int)(Math.random()*20+ 81;
         //강제 형변환으로 random 함수 사용해 20사이의 숫자 뽑아냄
         System.out.println("점수 : " + score);
         
         String grade;
         
         if(score >= 90) {
             if(score >= 95) {
                 grade = "A+";
             }else {
                 grade = "A";
             }
         }else {
             if(score>=85) {
                 grade = "B+";
             }else {
                 grade = "B";
             }
         }
         System.out.println("학점: "+ grade );
    }
}
cs


  -switch문 : 조건식의 결과값은 반드시 정수, 문자열이여야함 -> case 값도 정수, 문자열이어야함 / case값은 중복될 수 없음

switch(조건식){
    case 값1: //조건식 결과와 값1이 같을 때 실행
    break//case 값1dl 실행될 경우 switch문을 빠져나감
    case 값2: //조건식 결과와 값2가 같을 때 실행
    break//case값2가 실행될 경우 switch문을 빠져나감
    default:
        //조건식과 일치하는 case없을 경우 실행
        //마지막에 작성되므로 break 없어도 됨
}
cs


#switch문 중첩 

switch(조건식){
    case 값1 : //조건식 결과와 값1이 같을 때 실행
        switch(조건식){
            case 값3:
            break;
            case 값4:
            break;
        }
    break//case값1이 실행될 경우 switch문을 빠져나감
 
    case 값2: //조건식 결과와 값2가 같을 때 실행
    break//case 값2가 실행될 경우 switch문을 빠져나감
 
    default:
        //조건식과 일치하는 case없을 경우 실행
        //마지막에 작성되므로 break 없어도 됨
}

cs


3. 반복문 : 특정 문장을 반복 수행

-for 문 (반복 횟수 알고 있을 때 적합)

for(초기화; 조건식; 증감식){
    // 조건이 참일 때 실행
}
//조건식의 세가지 모두 생략 가능
// 이 경우 조건식이 참으로 간주되어 무한반복, 특정조건을 만족하면 if문을 빠져나오게 해야함
cs


     #중첩 for 문

#향상된 for문

for(타입 변수명 : 배열or 컬렉션){
    //반복할 문장
}
//타입 = 배열 or 컬렉션 타입과 일치
//배열이나 컬렉션에 저장된 요소들을 읽어오는 용도로만 사용 
cs

#ex) 구구단 출력 

public class HelloWorld {
    public static void main(String[] args) {
         for(int m = 2; m <= 9; m++) {
             System.out.println("##"+m+"단##");
             for(int n =1; n<= 9; n++) {
                 System.out.println(m + " X" + n +"="+ (m*n));
             }
         }
    }
}
cs


-while문(조건식이 true이면 계속 반복)

while(조건식){
    //조건식이 true일 경우
    실행문;
    //false이면 while문 
}
cs


-do-while문(블럭{ } 을 먼저 수행한 후 조건식 평가/ 최소한 한번은 수행될 것 보장)

do{
    //조건식 결과가 참일 때 수행
}while(조건식);
cs


4.break문 

-for/ while/ do-while문 사용

-자신이 포함한 가장 가까운 반복문 벗어남

-주로 if문과 함께 사용, 특정 조건 만족 시 반복문 벗어남


5.continue문

-for/while/do-while문 사용

-만나면 반복문의 끝으로 이동하여 다음 반복으로 넘어감

-for문 : 증감식으로 이동 / do-while문 : 조건식으로 이동

-반복문 전체 벗어나는게 아니라 다음 반복 계속 수행 



#별 찍기 

public class HelloWorld {
    public static void main(String[] args) {
        for(int i=1;i<=5;i++){
            for(int j=0;j<i;j++){
                System.out.print("*");
            }
            System.out.println("");
        }
    }
}
 
>>
*
**
***
****
*****
cs


#키보드 입력 데이터로 예금, 출금, 조회, 종료 기능을 제공하는 코드 작성

package firstproject;
import java.util.Scanner;
 
public class HelloWorld {
    public static void main(String[] args) {
    boolean run = true;
    
    int balance = 0;
    
    Scanner scanner = new Scanner(System.in);
    
    while(run) {
        System.out.println("==========");
        System.out.println("1.예금| 2.출금| 3. 잔고| 4. 종료");
        System.out.println("==========");
        System.out.println("선택> ");
        
        int num = scanner.nextInt();
        
        if(num==1) {
            System.out.println("예금액> ");
            balance += scanner.nextInt();
        }
        else if(num==2) {
            System.out.println("출금액 > ");
            balance -= scanner.nextInt();
        }
        else if(num==3) {
            System.out.println("잔고> ");
            System.out.println(balance);
        }
        else if(num==4) {
            run = false;
        }
    }
    System.out.println("프로그램 종료");
}
}
cs


반응형

'Language Study > Java' 카테고리의 다른 글

제주에서 자바_Week2_1  (0) 2019.07.22
제주에서 자바_Week1  (0) 2019.07.20
4. 클래스  (0) 2019.05.29
3. 참조 타입  (0) 2019.05.28
1. 타입, 연산자  (0) 2019.05.27
반응형

1. type

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
public class javaVariableExample{
    public static void main(String[] args){
        //논리형
        boolean booleanType = true(false);
        //문자형
        char charType = 'b';
        //정수형(int, long byte(이진), short)
        byte byteType=127;
        short shortType=32743;
        int intType=21243532;
        long longType=3984029840920L;
        //실수형
        float floatType = 3.4542E42;
        double doubleType= 1.434342E;
        //자동 타입 변환(작은 크기 타입 -> 큰 크기 타입)
        intValue = byteValue;//(byte -> int)
        intValue = charValue;//(char -> int)
        //강제 타입 변환(작은 크기 타입 = (작은 크기 타입)큰 크기 타입
        byte byteValue = (byte) intValue;
    }
}
cs


2. operation (연산자)


#변수 선언 및 값 할당 : "="


#연산자 

-단항 연산자 : + ,-, ~, !(논리값 부정)


  =증감 연산자 : ++, --


- 증가 연산자(++) : 피연산자의 값을 1 증가

- 감소 연산자(--) : 피연산자의 값을 1 감소

 전위형

j = ++i;

++i;

j = i 

값이 참조되기 전에 증가시킵니다. 

 후위형

j = i++; 

j = i

i++; 

 값이 참조된 후에 증가시킵니다.



-이항 연산자 

= 산술 연산자 : +, - , *, /, %(나머지 반환)

= 시프트 연산자 : >> , <<, >>> 

-> 변수나 어떤 수의 비트를 이동시키는 연산자 

<< : 대상을 이진수로 바꾼 후 왼쪽으로 비트들을 옮김(빈 자리는 0으로 채움)

>> : 대상을 이진수로 바꾼 후 오른쪽으로 비트들을 옮김(빈 자리는 0으로 채움)

>>> : 원 데이터가 -(음수)일 경우에도 앞쪽 비트를 0의 값으로 채움(오로지 양수 값만 다룸)

= 비교 (관계 ) 연산자 : >(미만) , <(초과) , >=(이하) , <=(이상) , ==(두 피연산자 값 같음) , !=(두 피연산자 값 다름)

= 논리 연산자 : &&(두 피연산자의 값이 모두 true 인 경우 true, 하나라도 false이면 false)

   || (두 피연산자 중 하나라도 ture일 경우 true)


= 삼항 연산자 : 조건항 ? 항1: 항2 (조건항이 참 = 항1 값 반환/ 거짓 : 항2 값 반환)



3. 연산자 우선 순위 

반응형

'Language Study > Java' 카테고리의 다른 글

제주에서 자바_Week2_1  (0) 2019.07.22
제주에서 자바_Week1  (0) 2019.07.20
4. 클래스  (0) 2019.05.29
3. 참조 타입  (0) 2019.05.28
2. 조건문 & 반복문  (0) 2019.05.27

+ Recent posts