728x90

728x90
728x90

728x90

'TodayILearned 공부기록용' 카테고리의 다른 글

TIL [2023/11/2 목요일]  (0) 2023.11.03
TIL [2023/10/31 화요일]  (0) 2023.11.02
TIL [2023/10/30 월요일]  (0) 2023.10.31
728x90

728x90
728x90

백견불여일타 JSP& Servlet 책 공부를 마치고 

마지막 장에 MVC패턴에 대한 소개가 나왔다. 그 내용을 정리해보겠다~!

(jsp, servlet 공부하느라 적어놓은 것도 블로그에 올려야겠다!)

 

MVC 패턴(= model 2 방식)이란?

초창기 웹 애플리케이션을 작성하는 방식이 model1 이라고 한다. 

model1은 보여주는 화면단 프레젠테이션 로직과 비즈니스 로직단이 엉켜있는 방식이다. 

 

재사용성과 가독성을 위해 비즈니스 로직을 중심으로 하는 model 2방식이 나왔다.

 

model, view , controller 를 사용하는 패턴을 말한다. 

이 3가지 영역으로 나누고 이들의 결합도를 최소화하는 것이 MVC 패턴의 목표이다.

 

모델은 비즈니스 로직, 즉 데이터베이스와 연동하여 서비스를 동작하기 위한 로직을 말하고 

뷰는 결과를 출력하여 보여주는 화면단

컨트롤러는 모델과 뷰를 연결하고 제어하는 역할을 한다. 

이 책에서는 JSP 가 뷰 역할을 해서 화면에 결과물을 출력했고 

서블릿을 이용해 클라이언트의 요청을 받아 로직을 수행했다.

모델은 데이터베이스와 연동하는 비즈니스 로직을 통해 얻어온 데이트를 저장하는 용도로 사용한다. 

 

MVC 패턴의 동작원리는 다음과 같다. 

 

가장 중요한 것은 컨트롤러의 역할!

프로그램에서 컨트롤러는 요청에 따라 어떤 비즈니스 로직을 행해야하는지 결정해주는 역할을 한다. 

또한 모델을 통해 얻은 결과를 어떤 뷰에 보내서 처리할지도 결정한다. 

 

용어를 정리해보자면,

 

DAO란? Data access object 

데이터 접근 객체. 

즉 데이터베이스를 연결하는 역할을 한다. 

연결하고 연결을 끊고. 데이터베이스에 접속해서 처리할 작업들을 하는 객체이다. 

실습 때는 반복적으로 하는 디비연결, 연결 끊기는 별도의 DBManager 객체를 만들어 호출해 사용했다. (싱글톤으로! - 객체를 한번만 사용해서 기존에 생성된 인스턴스를 통해 연결..)

 

DAO 안에서 sql 쿼리를 날렸다.

 

DTO란? Data Transfer object

데이터 전송 객체 

 

나도 헷갈리는 것이 있는데 실습할 때는 VO 객체를 만들고 구현했기 때문에 

DTO와 VO의 구분이 가질 않았다. 책에서도 DTO라고 적고 VO로 사용한 것 같은데..

 

DTO와 VO의 특성을 알고 

어떤 걸 사용할지 고민하면 된다. (알고 보니 실습에서는 VO라고 하고 setter를 사용한 것을 보니 DTO로 쓴 듯하다.)

 

DTO 와 VO의 차이점

둘다 데이터를 다루지만 그 쓰임새가 다르다. 

 

결론적으로 보면

사용목적은 다르지만 사용하는 방식은 비슷해서 혼돈이 온다.

 

VO는 비즈니스 로직을 위한 데이터 상태를 처리하기 위해 주로 쓰여서

로직을 추가할 수 있고 getter 만 사용해 그 자체 값을 가져오고

( VO는 equals, hashcode를 재정의하여 사용해 객체의 주소값 상관없이 

내용이 같다면 동일하다고 본다. )

 

DTO는 데이터 전송에 주로 쓰이고

로직을 추가할 수 없고 setter, getter 를 쓴다는 차이가 있다.  

 

 

아래 코드를 통해 어떻게 사용하는지 살펴보자

 출처 chatgpt

 

 

VO (Value Object)는 주로 데이터의 상태를 나타내고 비즈니스 도메인의 특정 비즈니스 로직을 위해 사용됩니다. 다음은 DTO 대신 VO를 사용하는 경우의 예시와 상황입니다:

1. 도메인 모델 내부에서 사용하는 데이터: VO는 도메인 모델의 일부로 사용되며, 도메인 모델 내부에서 데이터를 표현하고 비즈니스 로직을 수행하는 데 사용됩니다. 예를 들어, 주문, 제품, 고객, 계좌 등과 같은 비즈니스 엔터티의 상태를 나타내기 위해 VO를 사용할 수 있습니다. 

   public class OrderVO {
       private int orderId;
       private List<ProductVO> products;
       private CustomerVO customer;
   
       // 비즈니스 로직을 포함할 수 있음
       public void calculateTotalPrice() {
           // 제품 가격을 합산하고 총 가격을 계산
       }
   }

2. 데이터 검증 및 유효성 검사:VO는 데이터의 유효성을 검사하고 특정 규칙에 따른 검증을 수행하기 위해 사용될 수 있습니다. VO 객체는 데이터의 일관성을 보장하고 비즈니스 로직에 따라 데이터를 처리하는 데 유용합니다.

 

   public class ProductVO {
       private int productId;
       private String name;
       private double price;
   
       public void validate() {
           // 제품 데이터의 유효성을 검사하고 오류를 처리
       }
   }



3. 비즈니스 룰 적용: VO는 비즈니스 룰 및 규칙을 적용하는 데 사용될 수 있습니다. 예를 들어, 할인, 부가세 계산, 주문 처리 등과 같은 비즈니스 규칙을 VO 내에서 구현할 수 있습니다.

 

   public class OrderVO {
       private int orderId;
       private List<ProductVO> products;
       private CustomerVO customer;
   
       public void applyDiscount() {
           // 할인 규칙을 적용하여 주문 가격을 조정
       }
   }



VO는 주로 비즈니스 도메인에서 데이터의 상태와 관련된 작업을 수행하기 위해 사용됩니다. 이러한 작업은 DTO보다 비즈니스 로직과 데이터 처리에 더 중점을 둔 작업이며, VO는 이를 효율적으로 처리할 수 있는 도구로 사용됩니다.

 

 

DTO (Data Transfer Object)는 주로 데이터 전송과 다른 레이어 간의 데이터 교환을 위해 사용됩니다. 다음은 DTO를 사용하는 몇 가지 주요 상황과 예시입니다:

1. 데이터베이스와 비즈니스 레이어 간 데이터 전송:데이터베이스에서 데이터를 검색하고, 이 데이터를 비즈니스 레이어로 가져올 때 DTO를 사용합니다. DTO는 데이터베이스 스키마와 비즈니스 모델 간의 데이터 구조 차이를 처리하고 데이터를 전달하는 역할을 합니다.

   예시:

   public class ProductDTO {
       private int productId;
       private String name;
       private double price;

       // Getter 및 Setter 메서드
   }



2. 서로 다른 시스템 간 데이터 교환: 웹 서비스나 REST API를 통해 다른 시스템으로 데이터를 전송할 때 DTO를 사용합니다. 이렇게 다른 시스템 간의 통신에서는 데이터를 구조화하고 표준 형식으로 전송하기 위한 목적으로 DTO를 활용합니다.

   예시:

   public class OrderRequestDTO {
       private List<ProductDTO> products;
       private CustomerDTO customer;

       // Getter 및 Setter 메서드
   }



3. 뷰 레이어와 비즈니스 레이어 간 데이터 전송: 웹 애플리케이션에서 사용자 인터페이스와 비즈니스 레이어 사이에서 데이터를 전달할 때 DTO를 사용합니다. DTO는 뷰에서 필요한 데이터를 비즈니스 레이어로 전달하고 그 반대로 비즈니스 로직의 결과를 뷰로 반환하기 위해 사용됩니다.

   예시:

   public class OrderFormDTO {
       private String customerName;
       private List<ProductDTO> selectedProducts;

       // Getter 및 Setter 메서드
   }



4. 데이터 필터링: 뷰에서 데이터베이스로 데이터를 요청할 때, DTO를 사용하여 필요한 필드만 선택적으로 전달하는 방식으로 데이터 필터링을 수행할 수 있습니다.

   예시:
 

   public class ProductRequestDTO {
       private boolean includePrice;
       private boolean includeDescription;

       // Getter 및 Setter 메서드
   }



DTO는 주로 데이터의 전송과 데이터 구조 변환을 간소화하고 효과적으로 관리하기 위해 사용됩니다. 데이터를 읽기, 쓰기, 전송하기 위한 간편한 방법을 제공하며, 데이터의 형식이나 구조가 서로 다른 레이어 간에 호환성을 유지하는 데 도움을 줍니다.

 

 

이 둘을 어떻게 사용할지 더 물어봤다. 



여기서는 간단한 예를 통해 설명하겠습니다:

1. DTO를 사용한 접근:

   - `ProductDTO`를 사용하여 데이터베이스에서 제품 정보를 가져옵니다.
   - `OrderVO`에서 이러한 `ProductDTO`를 사용하여 제품 가격을 가져와서 총 가격을 계산합니다.

   public class OrderVO {
       private List<ProductDTO> products;

       public void calculateTotalPrice() {
           double total = 0;
           for (ProductDTO productDTO : products) {
               // ProductDTO에서 제품 가격을 가져와서 합산
               total += productDTO.getPrice();
           }
           // 총 가격을 설정
           // total 값을 다른 VO 속성에 저장
       }
   }



2. DTO를 사용하지 않는 직접적인 접근:

   - `OrderVO`에서 데이터베이스에 직접 연결하여 제품 정보를 가져와 가격을 계산합니다.

 

   public class OrderVO {
       private List<ProductVO> products;

       public void calculateTotalPrice() {
           double total = 0;
           for (ProductVO productVO : products) {
               // 데이터베이스에 연결하여 제품 가격을 가져와서 합산
               // total 값을 다른 VO 속성에 저장
           }
       }
   }


- DTO (Data Transfer Object): 데이터를 전달하고 다른 레이어 간의 데이터 교환을 목적으로 사용됩니다. 주로 데이터를 구조화하고 전달하기 위한 객체입니다.

- DAO (Data Access Object): 데이터베이스와 상호 작용하여 데이터를 검색, 추가, 수정, 삭제하는 역할을 합니다. 데이터베이스 액세스와 데이터 관리를 위한 객체입니다.

- VO (Value Object):주로 비즈니스 도메인의 상태를 나타내며, 불변하고 비즈니스 로직을 수행하기 위한 객체입니다.

일반적으로 DTO는 DAO에서 데이터베이스에서 가져온 데이터를 비즈니스 레이어로 전달할 때 사용됩니다. 이후 비즈니스 로직은 VO나 다른 비즈니스 객체에서 처리됩니다. VO와 DTO는 각각의 역할과 목적을 갖고 있으며, 이러한 분리된 역할은 코드의 가독성, 유지보수성, 테스트 용이성을 개선하는 데 도움을 줍니다.

 

 

 

 

 

 

 

https://velog.io/@gillog/Entity-DTO-VO-%EB%B0%94%EB%A1%9C-%EC%95%8C%EA%B8%B0

728x90
728x90

자바 프로젝트를 데이터베이스에 연결하기 위해서는 다음과 같은 단계를 거친다. 

1. JDBC 드라이버 로드  (JDBC java Database Connectivity 자바와 디비 연결을 돕는 api들을 제공해준다)

2. 데이터베이스와 연결

3. SQL문 실행

4. 데이터베이스와 연결 끊음

 

나는 1번부터 막혔다! (이클립스에서 인텔리제이로 넘어오면서 책에 예시가 없어서 다 찾아봐야했다)

maven이나 gradle을 써서 사용하는 드라이버 설정을 해줘야하나 싶었지만 역시나 해결이 안됨.

 

마리아 디비 드라이버 다운 

https://mariadb.com/downloads/connectors/connectors-data-access/java8-connector

+ java 눌러서 다운받은 드라이버넣어줬는데도

Class.forName("org.mariadb.jdbc.Driver");

부터 통과가 안됐다! 드라이버를 못가져오는거같은데...

 

 

해결방법

 

이 블로그를 보고 도움 받았다!

"WEB-INF/lib 안에 mariadb-java-client-2.6.2.jar을 빌드 해주야 해결이 된다" !

https://jung-story.tistory.com/108

 

Avaliable Elements 안에 TEST 안에 있는 

maraidb 파일을 클릭해서 왼쪽 lib 안에 집어넣는다.

 

드라이버 연결 DBManager

 

package util;

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

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;

public class DBManager {
    public static Connection getConnection(){


        Connection con = null;

        String server = "서버주소(나는 localhost)";
        String database = "데이터베이스 이름";
        String user_name = "유저네임";
        String password = "비밀번호";

        try {
            Class.forName("org.mariadb.jdbc.Driver");
            System.out.println("드라이브로드 성공");

        } catch (ClassNotFoundException e) {
            System.err.println(" 드라이버 로딩 오류 : " + e.getMessage());
            e.printStackTrace();
        }

        try {
            con = DriverManager.getConnection("jdbc:mariadb://" +
                    server + "/" +
                    database +
                    "?useSSL=false", user_name, password); // SSL 실행 확인
            System.out.println("연결 성공");
        } catch(Exception e) {
            System.err.println("에러 내용 :" + e.getMessage());
            e.printStackTrace();
        }

        System.out.println("con리턴" +con);
        return con;



    }
    //select 수행한 후 리소스 해제를 위한 메소드
    public static void close(Connection conn, Statement stmt, ResultSet rs){
        try{
            rs.close();
            stmt.close();
            conn.close();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    //insert, update, delete 작업을 수행한 후 리소스 해제를 위한 메소드
    public static void close(Connection conn, Statement stmt){
        try{
            stmt.close();
            conn.close();
        } catch (Exception e){
            e.printStackTrace();
        }
    }
}

 

ProductDAO

에서 getInstance를 통해 연결!

package com.saeyan.dao;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

import util.DBManager;

import com.saeyan.dto.ProductVO;

public class ProductDAO {
    private ProductDAO(){

    }
    private static ProductDAO instance = new ProductDAO();
    public static ProductDAO getInstance(){
        return instance;
    }

    //c Read u d
    public  List<ProductVO> selectAllProducts(){
        //최근 등록한 상품 먼저 출력하기
        String sql= "select * from product order by code desc";
        List<ProductVO> list = new ArrayList<>();
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;

        try{
            conn = DBManager.getConnection();
            pstmt = conn.prepareStatement(sql);
            rs = pstmt.executeQuery();


            while (rs.next()){
                ProductVO pVo = new ProductVO();
                pVo.setCode(rs.getInt("code"));
                pVo.setName(rs.getString("name"));
                pVo.setPrice(rs.getInt("price"));
                pVo.setPictureUrl(rs.getString("pictureurl"));
                pVo.setDescription(rs.getString("description"));

                list.add(pVo); //앗 얘를 빼먹었었네!
            }


        } catch(Exception e){
            System.out.println("값 못가져옴:"+e.getMessage());


        } finally {
            DBManager.close(conn, pstmt, rs);
        }
        return list;
    }

}
728x90
728x90

모던자바인액션을 읽으며

순차 스트림, 병렬 스트림을 배우면서 

"무엇보다 컴퓨터의 멀티 코어를 활용해서 파이프라인 연산을 실행할 수 있다는 점이 중요한 특징이다."

"따라서 병렬 스트림을 이용하면 멀티코어 프로세서가 각각의 청크를 처리하도록 할당할 수 있다."

라는 말이 멈칫했다. "멀티코어"를 사용한 적이 있었나..? 

 

스레드풀 배우면서 자바는 멀티스레드를 쓰는 구나~ 이해하고 넘어가서 

멀티 코어가 자꾸 등장해서 혼란스러웠다

 

나의 혼란의 원인은 병렬처리의 중복된 용어 사용이었다. chatgpt와 질의응답을 한 내용으로 정리해본다. 

(멀티 스레드: 스레드가 여러개 , 멀티 코어: 코어가 여러개 (cpu))

 

 

 

싱글 코어에서 멀티 스레드로 처리되는 경우는 결국 스레드가 순차적으로 실행되는거야?

 

싱글 코어에서 멀티 스레드를 사용하는 경우, 스레드는 하나의 코어에서 실행됩니다. 이렇게 되면 스레드들은 시분할 방식으로 번갈아가며 실행되기 때문에 동시에 여러 스레드가 병렬적으로 실행되는 것처럼 보일 수 있지만, 사실은 순차적으로 실행됩니다. 이것을 "멀티 스레딩"이라고 합니다.

싱글 코어에서 멀티 스레딩을 사용하면 스레드 간에 시간을 나눠 가지며 작업을 처리하기 때문에 병렬 처리를 하는 것보다는 성능 향상이 제한적일 수 있습니다. 진정한 병렬 처리를 위해서는 멀티 코어 CPU가 필요하며, 각각의 코어에서 별도의 스레드를 동시에 실행할 수 있어야 합니다.

 

그렇다면 스레드풀은 싱글코어에서도 가능하고 멀티코어에도 가능한 멀티 스레드를 만드는 기능인거야?

 

네, 스레드 풀은 싱글 코어 및 멀티 코어 환경에서 모두 사용할 수 있는 멀티 스레딩을 구현하는 데 도움을 주는 기능입니다. 스레드 풀은 스레드를 효율적으로 관리하고 재사용하는 데 도움을 줍니다.

스레드 풀은 스레드를 미리 생성하고 풀에 보관해두고, 작업이 필요할 때 이 풀에서 스레드를 가져와 작업을 실행하고 다시 풀에 반환하는 방식으로 동작합니다. 이렇게 하면 스레드를 반복적으로 생성하고 제거하는 오버헤드를 피하고, 스레드의 재사용을 통해 성능을 향상시킬 수 있습니다.

따라서 싱글 코어 또는 멀티 코어 시스템에서 스레드 풀을 사용하여 멀티 스레딩을 구현할 수 있으며, 이를 통해 작업을 병렬로 처리할 수 있습니다.

 

(오버헤드: 추가 처리 작업에 드는 비용)

 

병렬로 처리한다는 말이 싱글코어와 멀티코어 모두에서 쓸 수 있는 말이야?

 

"병렬로 처리한다"는 말은 원칙적으로 싱글 코어와 멀티 코어 모두에서 사용할 수 있는 말입니다. 그러나 실행 환경에 따라 실제로 얼마나 효과적으로 병렬로 처리되는지는 다를 수 있습니다.

  • 싱글 코어: 싱글 코어에서 병렬 처리라고 말하더라도, 이것은 스레드가 시분할 방식으로 번갈아가며 실행되는 것을 의미합니다. 따라서 실제로는 동시에 여러 작업을 처리하는 것이 아니라 스레드 간에 작업을 번갈아가며 처리합니다. 이로 인해 싱글 코어에서는 병렬 처리의 이점을 크게 누리기 어렵습니다.
  • 멀티 코어: 멀티 코어 CPU에서 병렬 처리는 실제로 여러 코어에서 병렬로 실행되는 작업을 의미합니다. 각 코어는 독립적으로 작업을 처리하므로 실제로 병렬 처리의 이점을 제대로 누릴 수 있습니다. 멀티 스레딩 및 멀티 프로세싱 기술을 사용하여 멀티 코어 시스템에서 병렬 처리를 구현할 수 있습니다.

따라서 "병렬로 처리한다"는 말 자체는 두 환경에서 모두 사용할 수 있지만, 싱글 코어에서는 실제로 병렬 처리의 성능 향상을 기대하기 어렵습니다. 멀티 코어 시스템에서 이 말이 더 효과적으로 적용됩니다.

 

멀티 프로세서와 멀티 코어는 같은 말이야 다른 말이야?

 

멀티 프로세서와 멀티 코어는 비슷한 개념이지만 약간의 차이가 있습니다.

1. 멀티 프로세서(Multi-Processor):
   - 멀티 프로세서는 여러 개의 독립적인 중앙 처리 장치(CPU) 또는 프로세서를 포함하는 컴퓨터 시스템을 나타냅니다. 각 프로세서는 별도의 작업을 처리하며, 이들은 주로 병렬 컴퓨팅 및 서버 환경에서 사용됩니다.
   - 멀티 프로세서 시스템은 여러 개의 물리적 CPU 칩 또는 소켓을 가질 수 있으며, 각각의 CPU는 독립적인 처리 유닛을 가집니다.

2. 멀티 코어(Multi-Core):
   - 멀티 코어는 하나의 CPU 칩 내에 여러 개의 실행 코어(중앙 처리 장치 코어)가 내장된 프로세서를 나타냅니다. 이러한 코어들은 하나의 CPU 칩 내에서 서로 공유된 리소스를 사용하며, 병렬로 여러 작업을 처리할 수 있습니다.
   - 멀티 코어 프로세서는 물리적 CPU 칩 하나에 여러 개의 논리적 코어를 가지고 있으며, 이러한 코어들은 주로 개인용 컴퓨터 및 노트북과 같은 일반적인 컴퓨터 시스템에서 사용됩니다.

요약하면, 멀티 프로세서는 여러 개의 독립적인 CPU를 가진 전체 시스템을 나타내는 것이고, 멀티 코어는 하나의 CPU 칩 내에 여러 개의 코어가 있는 프로세서를 나타냅니다. 둘 다 병렬 처리를 가능하게 하며 성능을 향상시키지만, 멀티 코어는 일반적으로 개인용 컴퓨터 및 모바일 기기에서 더 일반적으로 사용됩니다.

728x90

+ Recent posts