<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>jojo_.log</title>
        <link>https://velog.io/</link>
        <description>꾸준히</description>
        <lastBuildDate>Thu, 20 Jun 2024 10:33:07 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>jojo_.log</title>
            <url>https://velog.velcdn.com/images/jojo_/profile/470ff640-6eea-4a3e-abc3-a4bf10e27d45/image.jpg</url>
            <link>https://velog.io/</link>
        </image>
        <copyright>Copyright (C) 2019. jojo_.log. All rights reserved.</copyright>
        <atom:link href="https://v2.velog.io/rss/jojo_" rel="self" type="application/rss+xml"/>
        <item>
            <title><![CDATA[[Spring] 스프링 빈(Spring Bean) 과 어노테이션]]></title>
            <link>https://velog.io/@jojo_/Spring-%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B9%88Spring-Bean-%EA%B3%BC-%EC%96%B4%EB%85%B8%ED%85%8C%EC%9D%B4%EC%85%98</link>
            <guid>https://velog.io/@jojo_/Spring-%EC%8A%A4%ED%94%84%EB%A7%81-%EB%B9%88Spring-Bean-%EA%B3%BC-%EC%96%B4%EB%85%B8%ED%85%8C%EC%9D%B4%EC%85%98</guid>
            <pubDate>Thu, 20 Jun 2024 10:33:07 GMT</pubDate>
            <description><![CDATA[<h3 id="✔️-spring-bean스프링-빈이란">✔️ Spring Bean(스프링 빈)이란?</h3>
<br>

<ul>
<li><p>Spring Bean은 Spring IoC컨테이너가 관리하는 자바 객체로, 컨테이너에 의해 생명주가기 관리되는 객체를 의미합니다.</p>
</li>
<li><p>기존 Java 에서는 Class를 생성하고 new 를 사용하여 객체를 직접 생성해 사용했는데, Spring에서는 IoC컨테이너 안에 들어있는 객체(Spring Bean)를 필요할 때마다 IoC컨테이너에서 가져와 사용합니다.</p>
</li>
<li><p>어노테이션인 @Bean 을 사용하거나, xml 설정을 통해 일반 객체를 Bean으로 등록이 가능합니다.</p>
</li>
<li><p>즉, Sping 에서 Bean은 ApplicationContext가 알고 있는 객체이며, ApplicationContext가 생성하고 직접 관리해주는 객체를 의미합니다.</p>
</li>
</ul>
<p><br><br></p>
<h3 id="✔️-spring-bean의-생명주기">✔️ Spring Bean의 생명주기</h3>
<br>

<ul>
<li><p><strong><span style="background-color: lightgreen">객체 생성 → 의존성 주입 → 초기화 → 사용 → 소멸 과정</span></strong>의 생명주기를 가지고 있습니다. </p>
</li>
<li><p>Bean은 스프링 컨테이너에 의해 생명주기를 관리합니다.</p>
</li>
<li><p>스프링 컨테이너가 초기화 될 때 먼저 빈 객체를 설정에 맞춰 의존 관계를 설정한 뒤 해당 프로세스가 완료되면 빈 객체가 지정한 메소드를 호출해서 초기화를 진행합니다.</p>
</li>
<li><p>객체를 사요해 컨테이너가 종료될 때 빈이 지정한 메소드를 호출해 소멸 단계를 거칩니다.</p>
</li>
<li><p>스프링은 InitializingBean 인터페이스와 DisposableBean을 제공하며 빈 객체의 클래스가 <strong>InitializingBean</strong> Interface 또는 <strong>DisposableBean</strong>을 구현하고 있으며 해당 인터페이스에서 정의된 메소드를 호출해 빈 객체의 초기화 또는 종료를 수행합니다.</p>
</li>
<li><p>어노테이션을 이용한 빈 초기화 방법에는 <strong>@PostConstruct</strong>와 빈 소멸에서는 <strong>@PreDestory</strong>를 사용합니다.</p>
</li>
</ul>
<br>


<h3 id="✔️-자바-어노테이션java-annotation이란">✔️ 자바 어노테이션(Java Annotation)이란?</h3>
<p>Annotation은 클래스와 메서드에 추가하여 다양한 기능을 부여하는 역할을 합니다. Annotation을 활용하여 Spring Framework는 해당 클래스가 어떤 역할인지 정하기도 하고, Bean을 주입하기도 하며, 자동으로 getter나 setter를 생성하기도 합니다. </p>
<p>특별한 의미를 부여하거나 기능을 부여하는 등 다양한 역할을 수행할 수 있습니다.</p>
<p>이러한 Annotation을 통하여 <strong><span style="background-color: lightgreen">코드량이 감소하고 유지보수하기 쉬우며, 생산성이 증가됩니다.<span></strong></p>
<p><br><br></p>
<h3 id="✔️-자바-어노테이션java-annotation을-사용하는-방법">✔️ 자바 어노테이션(Java Annotation)을 사용하는 방법</h3>
<br>

<ul>
<li><p><strong>@Component</strong> : 개발자가 생성한 Class를 Spring의 Bean으로 등록할 때 사용하는 Annotation입니다. Spring은 해당 Annotation을 보고 Spring의 Bean으로 등록합니다. 
참고로, @Component와 동일한 기능을 가지면서 좀 더 명확한 의미를 부여할 수 있는 태그들로 @Repository, @Service 등이 있습니다.</p>
</li>
<li><p><strong>@ComponentScan</strong> : Spring Framework는 @Component, @Service, @Repository, @Controller, @Configuration 중 1개라도 등록된 클래스를 찾으면, Context에 bean으로 등록합니다. @ComponentScan Annotation이 있는 클래스의 하위 Bean을 등록 될 클래스들을 스캔하여 Bean으로 등록해줍니다.</p>
</li>
<li><p><strong>@Bean</strong> : @Bean Annotation은 개발자가 제어가 불가능한 외부 라이브러리와 같은 것을들 Bean으로 만들 때 사용합니다.</p>
</li>
<li><p><strong>@Controller</strong> : 컨트롤러 클래스에 @Controller 어노테이션을 작성합니다. bean으로 등록되며 해당 클래스가 Controller로 사용됨을 Spring Framework에 알립니다.</p>
</li>
<li><p><strong>@Repository</strong> : 저장소라는 뜻으로 DAO(Database Access Object)에 부여합니다.</p>
</li>
<li><p><strong>@Service</strong> : 서비스라는 뜻으로 DAO와 컨트롤러를 연결하는 서비스에 부여합니다.</p>
</li>
<li><p><strong>@RequestMapping</strong> : @RequestMapping(value=”“)와 같은 형태로 작성하며, 요청 들어온 URI의 요청과 Annotation value 값이 일치하면 해당 클래스나 메소드가 실행됩니다. Controller 객체 안의 메서드와 클래스에 적용 가능합니다.</p>
</li>
<li><p><strong>@RequestParam</strong> : URL에 전달되는 파라미터를 메소드의 인자와 매칭시켜, 파라미터를 받아서 처리할 수 있는 Annotation입니다.</p>
</li>
<li><p><strong>@RequestBody</strong> : Body에 전달되는 데이터를 메소드의 인자와 매칭시켜, 데이터를 받아서 처리할 수 있는 Annotation입니다.</p>
</li>
<li><p><strong>@ModelAttribute</strong> : 클라이언트가 전송하는 HTTP parameter, Body 내용을 Setter 함수를 통해 1:1로 객체에 데이터를 연결(바인딩)합니다. RequestBody와 다르게 HTTP Body 내용은 multipart/form-data 형태를 요구합니다.</p>
</li>
<li><p><strong>@GetMapping</strong> : RequestMapping(Method=RequestMethod.GET)과 똑같은 역할을 하며, @RequestMapping(&quot;/ &quot;) 의 형태로 사용합니다.</p>
</li>
<li><p><strong>@PostMapping</strong> : RequestMapping(Method=RequestMethod.POST)과 똑같은 역할을 하며,  @PostMapping(&quot;/ &quot;) 의 형태로 사용합니다.</p>
</li>
</ul>
<ul>
<li><p><strong>@Value(“값”)</strong> : VO 클래스의 멤버 필드 바로 위에 붙여 사용합니다.</p>
</li>
<li><p><strong>Component(“아이디”)</strong> : 기본 아이디 외에 새로운 아이디를 지정합니다.</p>
</li>
<li><p><strong>@Scope(“prototype”)</strong> : 싱글턴 패턴을 사용하고 싶지 않을 때 지정하며, @Component 밑에 붙여 사용합니다.</p>
</li>
<li><p><strong>@Autowired</strong> : 프로젝트 내부 전체를 검색해서, 해당 타입의 인스턴스가 1개만 있는 경우 그 인스턴스를 자동으로 연결합니다.</p>
</li>
<li><p><strong>@Autowired @Qualifier(“아이디”)</strong> : 프로젝트 내 같은 타입의 인스턴스가 2개 이상 있는 경우 어떤 인스턴스를 선택해서 사용할 지 결정합니다.</p>
</li>
<li><p><strong>@Override</strong>: 이 메소드는 상위 클래스에서 오버라이딩 된 메소드라는 것을 명시적으로 보증하는 역할을 합니다. 잘못된 오버라이딩이거나 혹은 오버라이딩이 아닌데 이 어노테이션을 붙이면 컴파일 에러가 발생합니다.</p>
</li>
<li><p><strong>@Deprecated</strong>: 프로그램을 만들 때 특정 메소드(기능)에 부여하며 호환성 문제 때문에 일단 사용은 가능하도록 했지만 옛날 방식, 옛날 기술 등이라 사람들에게 점차적으로 사용하지 않도록 유도하고자 할 때 사용하는 기능입니다. 외부 라이브러리를 사용하다 보면 많이 볼 수 있습니다.</p>
</li>
<li><p><strong>@SuppressWarnings</strong>: 컴파일 경고를 무시합니다.</p>
</li>
</ul>
<p><br><br></p>
<p>[참조]
<a href="https://developer-ellen.tistory.com/198">https://developer-ellen.tistory.com/198</a>
<a href="http://yoonbumtae.com/?p=740">http://yoonbumtae.com/?p=740</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[시맨틱 태그(Semantic Tag) 란?]]></title>
            <link>https://velog.io/@jojo_/%EC%8B%9C%EB%A7%A8%ED%8B%B1-%ED%83%9C%EA%B7%B8Semantic-Tag-%EB%9E%80-i2k3egd7</link>
            <guid>https://velog.io/@jojo_/%EC%8B%9C%EB%A7%A8%ED%8B%B1-%ED%83%9C%EA%B7%B8Semantic-Tag-%EB%9E%80-i2k3egd7</guid>
            <pubDate>Fri, 07 Jun 2024 08:01:40 GMT</pubDate>
            <description><![CDATA[<h3 id="✔️-시맨틱-태그semantic-tag-란">✔️ 시맨틱 태그(Semantic Tag) 란?</h3>
<p>HTML5 에서 도입된 태그로, <strong>포함된 콘텐츠의 의미를 명확하게 전달하여 웹 브라우저와 개발자 모드에게 더 이해하기 쉽도록 하는 태그</strong></p>
<p>이러한 태그는 콘텐츠의 구조와 목적을 전달하여 접근성, 검색 엔진 최적화(SEO), 그리고 웹 페이지의 전반적인 유지 보수에 도움을 준다.</p>
<br>

<h3 id="✔️-주요-시맨틱-태그와-그-역할">✔️ 주요 시맨틱 태그와 그 역할</h3>
<ul>
<li><p>&lt; <strong>header</strong> &gt; : 문서나 섹션의 머리말을 정의함. 주로 제목, 로고, 검색창 등을 포함한다.</p>
</li>
<li><p>&lt; <strong>nav</strong> &gt; : 메뉴, 목차 등 문서끼리 연결하는 역할을 한다.</p>
</li>
<li><p>&lt; <strong>main</strong> &gt; : 문서의 중요 콘텐츠를 나타냄. 문서의 고유하고 주요한 부분을 포함.</p>
</li>
<li><p>&lt; <strong>section</strong> &gt; : 콘텐츠 내용을 묶거나 분리하는 역할을 한다.</p>
</li>
<li><p>&lt; <strong>div</strong> &gt; : 논리와 관계없이 영역을 나누는 역할을 한다.</p>
</li>
<li><p>&lt; <strong>article</strong> &gt; : 문서의 제목 및 문단 태그를 포함한 독립된 콘텐츠. 블로그 글, 뉴스 기사 등을 포함할 수 있다.</p>
</li>
<li><p>&lt; <strong>aside</strong> &gt; : 주요 콘텐츠와는 별도로, 부가적인 콘텐츠를 정의함. 좌측, 우측 또는 하단에 사이드바 영역을 표시한다.</p>
</li>
<li><p>&lt; <strong>footer</strong> &gt; : 문서나 섹션의 바닥글을 정의함. 저작권 정보, 연락처 정보 등을 포함할 수 있다.</p>
</li>
<li><p>&lt; <strong>figure</strong> &gt; : 그림, 다이어그램 등과 같은 독립적인 콘텐츠를 포함하며, 주로 &lt;<strong>figcaption</strong>&gt; 을 사용하여 설명을 추가한다.</p>
</li>
<li><p>&lt; <strong>figcaption</strong> &gt; : &lt; <strong>figure</strong> &gt; 요소의 설명을 정의함.</p>
</li>
<li><p>&lt; <strong>time</strong> &gt; : 날짜나 시간을 정의하며, 기계가 읽을 수 있는 형식으로 시간 정보를 제공한다.</p>
</li>
</ul>
<br>

<h3 id="✔️-시맨틱-태그의-span-stylecolor-blue장점span">✔️ 시맨틱 태그의 <span style="color: blue">장점</span></h3>
<ul>
<li><p><strong>접근성 향상</strong> : 스크린 리더와 같은 보조 기술이 콘텐츠의 구조와 목적을 더 잘 이해할 수 있어 접근성이 향상된다.</p>
</li>
<li><p><strong>SEO (검색 엔진 최적화)</strong> : 웹 구분화를 통해 검색엔진의 보다 빠르고 정확한 크롤링을 가능하게 하여 SEO최적화에 도움이 된다.</p>
</li>
<li><p><strong>유지 보수 용이</strong> : 코드의 구조가 명확해지므로 다른 개발자나 자신이 나중에 코드를 다시 볼 때 이해하기 쉽다.</p>
</li>
<li><p><strong>표준화된 구조</strong> : 시맨틱 태그를 사용하면 웹 페이지가 표준화된 구조를 가지게 되어 다른 개발자들이 쉽게 이해할 수 있다.</p>
</li>
<li><p><strong>향후 호환성</strong> : 웹 기술이 발전함에 따라 시맨틱 태그를 사용한 코드는 더 오랜 기간 동안 호환성을 유지 할 가능성이 크다.</p>
</li>
</ul>
<br> 

<h3 id="✔️-시맨틱-태그의-span-stylecolor-red단점span">✔️ 시맨틱 태그의 <span style="color: red">단점</span></h3>
<ul>
<li><p><strong>초기 학습 곡선</strong> : 시맨틱 태그의 목적와 사용 방법을 이애하기 위해서는 약간의 학습이 필요할 수 있다. 특히, 기존의 비시맨틱 태그를 사용하던 개발자에게는 새로운 개념일 수 있다.</p>
</li>
<li><p><strong>브라우저 호환성</strong> : 대부분의 최신 브라우저는 시맨틱 태그를 잘 지원하지만, 오래된 브라우저에서는 지원이 완벽하지 않을 수 있다. 다만, 이는 현대적인 웹 개발 환경에서는 큰 문제가 되지 않는다.</p>
</li>
<li><p><strong>추가적인 마크업</strong> : 시맨틱 태그를 사용함으로써 마크업이 약간 더 복잡해질 수 있으며, 이로 인해 초기 개발 속도가 느려질 수 있다.</p>
</li>
<li><p><strong>비호환적인 툴</strong> : 일부 오래된 개발 툴이나 라이브러리는 시맨틱 태그를 완벽히 지원하지 않을 수 있다.</p>
</li>
</ul>
<br>

<blockquote>
<p>시맨틱 태그는 접근성과 SEO를 비록한 여러 면에서 많은 이점을 제공하지만, 이를 잘 활용하기 위해서는 약간의 학습과 초기 적응이 필요할 수 있다.
이를 감안하여 사용하면, 장기적으로 더 나은 웹 페이지를 만들 수 있다.</p>
</blockquote>
]]></description>
        </item>
        <item>
            <title><![CDATA[DTO란?]]></title>
            <link>https://velog.io/@jojo_/DTO%EB%9E%80-r6hfwn8t</link>
            <guid>https://velog.io/@jojo_/DTO%EB%9E%80-r6hfwn8t</guid>
            <pubDate>Fri, 24 May 2024 14:32:14 GMT</pubDate>
            <description><![CDATA[<h3 id="✔️-dto란">✔️ DTO란?</h3>
<p>DTO(Data Transfer Object)란 계층간 데이터 교환을 위해 사용하는 객체(Java Beans)입니다.</p>
<br>

<h4 id="mvc-패턴">MVC 패턴</h4>
<p align="center">
<img src="https://velog.velcdn.com/images/jojo_/post/7268e413-0a59-4bb2-a8db-391da947de35/image.png" width="60%" height="60%">
</p>

<p>MVC패턴은 애플리케이션을 개발할 때 그 구성요소를 <strong>Model, View, Controller 등 세가지 역할로 구분하는 디자인 패턴</strong>입니다. 
비지니스 처리 로직(Model)과 UI영역(View)은 서로의 존재를 인지하지 못하고, Controller가 중간에서 Model과 View의 역할을 담당합니다.</p>
<p>Controller는 View로부터 들어온 사용자 요청을 해석하여 Model을 업데이트하거나 Model로부터 데이터를 받아 View로 전달하는 작업 등을 수행합니다. <strong>MVC패턴의 장점은 Model과 View를 분리해 서로의 의존성을 낮추고 독립적인 개발을 가능</strong>하게 하는 것입니다.</p>
<p>Controller는 View와 도메인 Model의 데이터를 주고 받을 때 별도의 DTO를 주로 사용합니다. 도메인 객체를 View에 직접 전달할 수 있지만, 민간함 도메인 비즈니스 기능이 노출될 수 있고 Model과 View 사이에 의존성이 생기기 때문입니다. 다만, 소규모 프로젝트는 DTO 사용이 불필요한 경우도 있습니다.</p>
<br>

<h3 id="✔️-사용-예시">✔️ 사용 예시</h3>
<blockquote>
<p>User.java</p>
</blockquote>
<pre><code class="language-c">public class User {

    public Long id;
    public String name;
    public String email;
    public String password; //외부에 노출되서는 안 될 정보
    public DetailInformation detailInformation; //외부에 노출되서는 안 될 정보

    //비즈니스 로직, getter, setter 등 생략
}</code></pre>
<blockquote>
<p>UserController.java</p>
</blockquote>
<pre><code class="language-c">@GetMapping
public ResponseEntity&lt;User&gt; showArticle(@PathVariable long id) {
    User user = userService.findById(id);
    return ResponseEntity.ok().body(user);
}</code></pre>
<p>이처럼 Controller가 클라이언트의 요청에 대한 응답으로 도메인 Model인 User를 넘겨주게되면 생기는 문제점은</p>
<ul>
<li><strong>도메인 Model의 모든 속성이 외부에 노출됩니다.</strong><ul>
<li>UI 화면마다 사용하는 Model의 정보는 상이하지만, Model 객체는 UI에서 사용하지 않을 불필요한 데이터까지 보유하고 있습니다.</li>
<li>비즈니스 로직 등 User의 민감한 정보가 외부에 노출되는 보안 문제와도 직결됩니다.</li>
</ul>
</li>
</ul>
<ul>
<li><p>UI 계층에서 Model의 메서드를 호출하거나 상태를 변경시킬 위험이 존재합니다.</p>
</li>
<li><p>Model과 View가 강하게 결합되어, View의 요구사항 변화가 Model에 영향을 끼치기 쉽습니다.</p>
<ul>
<li>User Entity의 속성이 변경되면, View가 전달받을 JSON 및 프론트엔드 JS 코드에도 변경을 유발하기 때문에 상호간 강하게 결합됩니다.</li>
</ul>
</li>
</ul>
<br>


<blockquote>
<p>UserDto.java</p>
</blockquote>
<pre><code class="language-c">public class UserDto {

    public final long id;
    public final String name;
    public final String email;

    //생성자 생략

    public static UserDto from(User user) {
        return new UserDto(user.getId(), user.getName(), user.getEmail());
    }
}</code></pre>
<blockquote>
<p>UserController.java</p>
</blockquote>
<pre><code class="language-c">@GetMapping
public ResponseEntity&lt;UserDto&gt; showArticle(@PathVariable long id) {
    User user = userService.findById(id);
    return ResponseEntity.ok().body(UserDto.from(user));
}</code></pre>
<p>반면 DTO를 사용하면 앞서 언급된 문제들을 해결할 수 있습니다. 도메인 Model을 캡슐화하고, UI 화면에서 사용하는 데이터만 선택적으로 보낼 수 있습니다.</p>
<p>정리하자면, DTO는 <strong>클라이언트 요청에 포함된 데이터를 담아 서버 측에 전달하고, 서버 측의 응답 데이터를 담아 클라이언트에 전달하는 계층간 전달자 역할</strong>을 합니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Spring boot] @PathVariable 란?]]></title>
            <link>https://velog.io/@jojo_/Spring-boot-PathVariable-%EB%9E%80</link>
            <guid>https://velog.io/@jojo_/Spring-boot-PathVariable-%EB%9E%80</guid>
            <pubDate>Wed, 22 May 2024 07:18:32 GMT</pubDate>
            <description><![CDATA[<h3 id="✔️-pathvariable란">✔️ @PathVariable란?</h3>
<ul>
<li>경로 변수를 표시하기 위해 <strong>메서드 매개변수</strong>에 사용된다.</li>
<li>경로 변수는 <strong>중괄호 {id}로 둘러싸인 값</strong>을 나타낸다.</li>
<li>URL 경로에서 변수 값을 추출하여 매개변수에 할당한다.</li>
<li>기본적으로 <strong>경로 변수는 반드시 값을 가져야 하며, 값이 없는 경우 404 오류가 발생</strong>한다.</li>
<li>주로 <strong>상세 조회, 수정, 삭제와 같은 작업</strong>에서 리소스 식별자로 사용된다.</li>
</ul>
<p><small>예를 들어, 아래 url 에서 강조 된 부분이 @PathVariable로 처리해 줄 수 있다.
localhost:8080/article/<strong>2</strong>
velog.io/@jojo_/<strong>25</strong>
</small></p>
<br>


<h3 id="✔️-예시-코드">✔️ 예시 코드</h3>
<pre><code class="language-c">@RequestMapping(&quot;/articles&quot;)
@Controller
public class ArticleController {

    @GetMapping(&quot;/{articleId}&quot;)
    public String article(@PathVariable Long articleId, ModelMap map) {
        map.addAttribute(&quot;article&quot;, &quot;article&quot;);
        map.addAttribute(&quot;articleComments&quot;, List.of());

        return &quot;articles/detail&quot;;
    }
}</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[API란?]]></title>
            <link>https://velog.io/@jojo_/API%EB%9E%80-li0fl1mo</link>
            <guid>https://velog.io/@jojo_/API%EB%9E%80-li0fl1mo</guid>
            <pubDate>Sat, 11 May 2024 10:31:23 GMT</pubDate>
            <description><![CDATA[<h3 id="✔️-api의-정의">✔️ API의 정의</h3>
<p>API란 &quot;Application Programming Interface&quot;의 약자로, 프로그램 또는 소프트웨어와 상호 작용하기 위한 인터페이스를 의미합니다.</p>
<p>한 단어 씩 나누어 보면,</p>
<blockquote>
<p><strong>Application</strong> : 특정한 업무를 수행하기 위해 개발된 응용 소프트웨어 <br>
<strong>Programming</strong> :컴퓨터에 부여하는 명령을 만드는 작업. 수식이나 작업을 컴퓨터에 알맞도록 정리해서 순서를 정하고 컴퓨터 특유의 명령코드로 고쳐 쓰는 작업 <br>
<strong>Interface</strong> : 사물과 사물 사이 또는 사물과 인간 사이의 경계에서, 상호 간의 소통을 위해 만들어진 물리적 매개체나 통신 규칙</p>
</blockquote>
<p>종합하자면, <strong>응용 소프트웨어를 만드는데 쓰는 매개체나 통신규칙</strong> 이라고 할 수 있습니다.</p>
<p>클라이언트와 서버 사이의 데이터 전송 통신을 위한 규칙이라고도 볼 수 있습니다.</p>
<br>

<h3 id="✔️-api의-종류">✔️ API의 종류</h3>
<ul>
<li><h4 id="라이브러리-api">라이브러리 API</h4>
프로그래밍 언어나 프레임워크에서 제공되는 함수나 클래스 등의 인터페이스를 의미합니다.</li>
</ul>
<pre><code>ex. Java 에는 JavaAPI가 있고, Python에는 Python표준 라이브러리와 외부 라이브러리들이 API를 제공함.</code></pre><ul>
<li><h4 id="웹-api">웹 API</h4>
HTTP 프로토콜을 통해 웹 서버와 통신하는 인터페이스를 의미합니다. 대부분의 경우, 클라이언트가 서버에 요청을 보내고 서버는 요청에 대한 응답을 제공합니다.</li>
</ul>
<pre><code>ex. RESTful API, SOAP API 등</code></pre><ul>
<li><h4 id="운영-체제-api">운영 체제 API</h4>
</li>
</ul>
<p>운영체제(OS)에서 제공하는 기능에 접근하기 위한 인터페이스를 의미합니다. 이를 통해 파일 시스템, 네트워크, 프로세스 관리 등의 기능에 접근할 수 있습니다.</p>
<ul>
<li><h4 id="소프트웨어-api">소프트웨어 API</h4>
</li>
</ul>
<p>다른 소프트웨어나 시스템과 상호 작용하기 위한 인터페이스를 말합니다.</p>
<pre><code>ex. 데이터페이스 시스템은 데이터를 제정, 수정, 검색하는 기능을 제공하는 API</code></pre><br>

<h3 id="✔️-api의-장점">✔️ API의 장점</h3>
<ul>
<li><h4 id="상호-운영성-및-통합">상호 운영성 및 통합</h4>
</li>
</ul>
<p>API는 서로 다른 시스템 간에 데이터 및 기능을 교환하고 통합할 수 있도록 해줍니다. 이는 서로 다른 플랫폼이나 언어를 사용하는 시스템 간에도 통신이 가능하게 해줍니다.</p>
<ul>
<li><h4 id="재사용성">재사용성</h4>
</li>
</ul>
<p>API를 사용하여 공통된 기능이나 서비스를 제공할 수 있습니다. 이는 중복을 피하고 개발 시간을 단축시키며, 코드의 일관성을 유지할 수 있게 해줍니다.</p>
<ul>
<li><h4 id="모듈화">모듈화</h4>
</li>
</ul>
<p>API는 서비스를 모듈화하여 개발할 수 있도록 도와줍니다. 각각의 모듈은 독립적으로 개발, 테스트, 배포될 수 있으며, 유지보수가 용이합니다.</p>
<ul>
<li><h4 id="확장성">확장성</h4>
</li>
</ul>
<p>API는 시스템을 쉽게 확장할 수 있도록 해줍니다. 새로운 기능이나 서비스를 추가하거나 기존의 기능을 업데이트할 때 API를 통해 상호 작용할 수 있습니다.</p>
<br>

<h3 id="✔️-api의-단점">✔️ API의 단점</h3>
<ul>
<li><h4 id="보안-문제">보안 문제</h4>
</li>
</ul>
<p>API는 외부와 상호 작용을 허용하므로 보안 문제가 발생할 수 있습니다. 적절한 보안 조치 없이는 데이터 유출이나 악의적인 공격에 노출될 수 있습니다.</p>
<ul>
<li><h4 id="호환성-문제">호환성 문제</h4>
</li>
</ul>
<p>새로운 API 버전이 출시되면 이전 버전과의 호환성을 유지해야 하며, 이를 관리하는 것은 복잡할 수 있습니다.</p>
<ul>
<li><h4 id="성능-문제">성능 문제</h4>
</li>
</ul>
<p>API 호출은 네트워크를 통해 이루어지기 때문에 시간이 소요됩니다. 과도한 API 호출이나 느린 응답 속도는 성능 문제를 야기할 수 있습니다.</p>
<ul>
<li><h4 id="의존성">의존성</h4>
</li>
</ul>
<p>외부 API에 의존하는 경우 외부 서비스의 가용성에 영향을 받을 수있습니다. 따라서 외부 서비스의 안정성과 가용성을 고려해야 합니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[JPA와 Hibernate
]]></title>
            <link>https://velog.io/@jojo_/JPA%EC%99%80-Hibernate-xor6yxei</link>
            <guid>https://velog.io/@jojo_/JPA%EC%99%80-Hibernate-xor6yxei</guid>
            <pubDate>Fri, 10 May 2024 05:44:49 GMT</pubDate>
            <description><![CDATA[<h3 id="✔️jpa란">✔️JPA란?</h3>
<p><img src="https://velog.velcdn.com/images/jojo_/post/cd585416-0276-4d10-9ec7-ee3d3f302efc/image.png" alt=""></p>
<p>자바 애플리케이션에서** 객체와 데이터베이스를 매핑하고 관리하기 위한 API**입니다.
JPA는 애플리케이션과 JDBC 사이에서 동작하며, 데이터베이스에 접근하고 SQL 쿼리를 실행할 수 있습니다.</p>
<p>객체 지향 프로그래밍과 관계형 데이터베이스 간의 불일치를 해결하기 위해 객체와 데이터베이스를 매핑하는 기능을 제공하는데, 이러한 기술을 ORM 이라고합니다.</p>
<br>

<h3 id="✔️orm이란">✔️ORM이란?</h3>
<p><strong>ORM *<em>은 *</em>Object-Relational Mapping 의 약자로, 객체와 관계형데이터베이스 간의 매핑을 자동화 하는 기술</strong>입니다. ORM은 개발자가 직접 SQL 쿼리를 작성하지 않고도 객체를 데이터베이스에 저장하고 조회할 수 있게 해줍니다. JPA는 이러한 ORM 기술의 한 종류입니다.</p>
<br>

<h3 id="✔️jpa의-구조">✔️JPA의 구조</h3>
<p><img src="https://velog.velcdn.com/images/jojo_/post/8a6026cb-fc16-44bb-b9c4-bddca6b89b47/image.png" alt=""></p>
<h4 id="hibernate">Hibernate</h4>
<p>Hibernate는 JPA 구현체의 한 종류입니다.</p>
<p>Hibernate ORM은, <strong>자바 언어를 위한 객체 관계 매핑 프레임워크로, 객체 지향 도메인 모델을 관계형 데이터베이스로 매핑하기 위한 프레임워크를 제공</strong>합니다.</p>
<p><strong>JPA는 DB와 자바 객체를 매핑하기 위한 인터페이스(API)를 제공</strong>하고, <strong>JPA 구현체(Hibernate)는 이 인터페이스를 구현</strong>한 것입니다.</p>
<p>Hibernate 이외에도 EclipseLink, DataNucleus 등이 있습니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[Log4j의 개념과 설정 방법]]></title>
            <link>https://velog.io/@jojo_/Log4j%EC%9D%98-%EA%B0%9C%EB%85%90%EA%B3%BC-%EC%84%A4%EC%A0%95-%EB%B0%A9%EB%B2%95-zp34emr8</link>
            <guid>https://velog.io/@jojo_/Log4j%EC%9D%98-%EA%B0%9C%EB%85%90%EA%B3%BC-%EC%84%A4%EC%A0%95-%EB%B0%A9%EB%B2%95-zp34emr8</guid>
            <pubDate>Wed, 27 Mar 2024 10:27:16 GMT</pubDate>
            <description><![CDATA[<h2 id="💡-log4j의-개념">💡 Log4j의 개념</h2>
<br>

<h3 id="✔️-logging-이란">✔️ Logging 이란?</h3>
<br>

<p>프로그램 개발 중이나 완료 후 발생할 수 있는 오류에 대해 <strong><span style="color: red">디버깅하거나 운영 중인 프로그램 상태를 모니터링 하기 위해 필요한 정보(로그)를 기록</span></strong>합니다. </p>
<p>다시말해 애플리케이션 실행에 대한 추적을 기록하기 위해 어딘가에 메시지 (콘솔, 파일, 데이터베이스 등)를 작성하는 것입니다.</p>
<br>

<h3 id="✔️-logging의-목적">✔️ Logging의 목적</h3>
<br>

<p>주로 디버깅이나 사용자 상호 작용 기록(발생하는 이벤트 기록)에 사용됩니다.</p>
<br>

<h3 id="✔️-java의-주요-logging-framework">✔️ Java의 주요 Logging Framework</h3>
<br>

<ul>
<li><p><strong>native java.util.logging</strong>: 별로 사용하지 않는다.</p>
</li>
<li><p><strong>Log4j</strong> : 콘솔로 출력하는 stdout 외에도 파일 출력도 제공, 2015년 개발 중단으로 레거시 시스템에서 사용</p>
</li>
<li><p><strong>Logback</strong> : Log4J 개발자가 만든 Log4J의 후속 버전, Log4j보다 향상된 성능과 필터링 옵션 제공하며 slf4j 지원, 자동 리로드 가능</p>
<ul>
<li><strong>SLF4J(Simple Logging Facade for Java)</strong>: Log4J 또는 Logback과 같은 백엔드 Logger Framework의 facade pattern</li>
</ul>
</li>
<li><p><strong>Log4j2</strong> : Logback과 동일하며 멀티 쓰레드 환경에서 비동기로거의 경우 Log4j 1.x 및 Logback
보다 처리량이 18배 더 높고 대기 시간이 짧은 장점이 있음.</p>
</li>
<li><p><strong>tinylog</strong> : 사용하기 쉽게 최적화된 Java용 최소형(75KB Jar) 프레임워크</p>
</li>
</ul>
<br>

<p><em><strong><span style="color: navy">오류를 확인하기 위한 디버거와의 비교했을 때 장점은 무엇인가?<span></strong></em></p>
<ol>
<li><p>Logging은 응용 프로그램 실행에 대한 정확한 컨텍스트(이벤트 순서)를 제공한다.</p>
<p>A. 전체적인 app의 흐름이나 타이밍 error도 확인할 수 있다.</p>
<p>B. error 종류: 논리적 에러, 타이밍 에러(multi-thread) 등</p>
</li>
<li><p>일단 코드에 삽입되면 logging output이 만들어질 때 사용자 개입이 필요 없다.</p>
</li>
<li><p>로그 출력은 나중에 살펴볼 수 있도록 영구 매체에 저장할 수 있다.</p>
<p>A. disk에 기록을 남겨 유용한 로깅 정보를 추적할 수 있다.</p>
</li>
<li><p>Logging Framework는 Debuggger보다 간단하고 배우기 쉽고 사용하기 쉽다.</p>
<br>

</li>
</ol>
<p><em><strong><span style="color: navy">그렇다면 단점은 무엇인가?<span></strong></em></p>
<ol>
<li><p>출력문이 들어가기 때문에 응용 프로그램 속도를 늦출 수 있다.</p>
</li>
<li><p>메시지 Level 설정에 유의하여 로그 관리가 필요가 하다.</p>
<br>

</li>
</ol>
<p><em><strong><span style="color: navy">System.out.println()과의 차이점은 무엇인가?<span></strong></em></p>
<ol>
<li><p>우선순위를 선택할 수 있다.</p>
</li>
<li><p>모든 모듈 또는 특정 모듈 또는 클래스에 대해 로깅할 수 있다.</p>
</li>
<li><p>매개변수화된 로그 메시지 지원으로 로그 메시지 형식을 제어할 수 있다.</p>
</li>
</ol>
<p><strong>즉 Log4j는 출력 위치를 지정하는 등의 높은 유연성을 갖는다.</strong></p>
<br>

<h3 id="✔️-log4j-정의">✔️ Log4j 정의</h3>
<p>Log4j : Log for Java</p>
<p>로그문의 출력을 다양한 대상으로 할 수 있도록 도와주는 도구(오픈소스)</p>
<p>오픈소스 링크 : <a href="https://logging.apache.org/log4j/1.2/">https://logging.apache.org/log4j/1.2/</a></p>
<br>

<h3 id="log4j-특징">Log4j 특징</h3>
<ul>
<li><p>log4j 는 속도에 최적화</p>
</li>
<li><p>log4j 는 이름있는 로그 계층에 기반</p>
</li>
<li><p>log4j 는 fail-stop 이지만 신뢰성은 없음</p>
</li>
<li><p>log4j 는 thread-safe(멀티스레드 환경에서 사용해도 안전하다:역주).</p>
</li>
<li><p>log4j 는 융통성이 풍부</p>
</li>
<li><p>설정 파일은 property 파일과 XML 형식으로 실행 중 수정 적용 가능</p>
</li>
<li><p>log4j 는 처음부터 자바의 예외를 처리하기 위해 디자인</p>
</li>
<li><p>log4j 는 출력을 파일, 콘솔, java.io.OutputStream, java.io.Writer, TCP 를 사용하는 원격서버, 원격 Unix Syslog 데몬, - 원격 JMS 구독자, 윈도우 NT EventLog 로 보낼 수 있고, 심지어는 e-mail 로 보낼 수도 있음</p>
</li>
<li><p>log4j 는 다음 6 단계의 장애레벨을 사용. &lt; TRACE(추가), DEBUG, INFO, WARN, ERROR, FATAL &gt;</p>
</li>
<li><p>로그 출력의 형식은 Layout 클래스를 확장함으로써 쉽게 바꿀 수 있음</p>
</li>
<li><p>로그가 출력될 대상과 출력 방법은 Appender 인터페이스로 할 수 있음</p>
</li>
<li><p>log4j 는 로거 하나에 다수의, 출력을 담당하는 appender 를 할당할 수 있음</p>
</li>
<li><p>log4j 는 국제화를 지원</p>
</li>
</ul>
<br>

<h3 id="✔️-log4j-구조">✔️ Log4j 구조</h3>
<table>
<thead>
<tr>
<th align="center">구조</th>
<th align="center">역할</th>
</tr>
</thead>
<tbody><tr>
<td align="center">Logger(Category)</td>
<td align="center">로깅 메세지를 Apeender에 전달<br>log4J의 심장부에 위치<br>개발자가 직접 로그 출력 여부를 런타임에 조정<br>logger는 로그레벨을 가지고 있으며, 로그의 출력 여부는 로그문의 레벨과 로거의 레벨을 가지고 결정</td>
</tr>
<tr>
<td align="center">Appender</td>
<td align="center">로그의 출력위치를 결정(파일, 콜솔, DB 등)<br>log4J API 문서의 XXXAppender로 끝나는 클래스들의 이름을 보면, 출력위치를 어느정도 짐작 가능</td>
</tr>
<tr>
<td align="center">Layout</td>
<td align="center">Appender가 어디에 출력할 것인지 결정했다면 어떤 형식으로 출력할 것인지 출력 layout을 결정</td>
</tr>
</tbody></table>
<br>

<h3 id="✔️-log4j-레벨">✔️ Log4j 레벨</h3>
<table>
<thead>
<tr>
<th align="center">레벨</th>
<th align="center">설명</th>
</tr>
</thead>
<tbody><tr>
<td align="center">FATAL</td>
<td align="center">아주 심각한 에러가 발생한 상태. 시스템적으로 심각한 문제가 발생해서 어플리케이션 작동이 불가능할 경우가 해당하는데, 일반적으로는 어플리케이션에서는 사용할 일이 없음</td>
</tr>
<tr>
<td align="center">ERROR</td>
<td align="center">요청을 처리하는 중 문제가 발생한 상태를 나타냄</td>
</tr>
<tr>
<td align="center">WARN</td>
<td align="center">처리 가능한 문제이지만, 향후 시스템 에러의 원인이 될 수 있는 경고성 메세지를 나타냄</td>
</tr>
<tr>
<td align="center">INFO</td>
<td align="center">로그인, 상태변경과 같은 정보성 메세지를 나타냄</td>
</tr>
<tr>
<td align="center">DEBUG</td>
<td align="center">개발시 디버그 용도롤 사용한 메세지를 나타냄</td>
</tr>
<tr>
<td align="center">TRACE</td>
<td align="center">log4j1.1.12에서 신규 추가된 레벨로서, DEBUG 레벨이 너무 광범위한 것을 해결하기 위해서 좀 더 상세한 상태를 나타냄</td>
</tr>
<tr>
<td align="center"></td>
<td align="center"></td>
</tr>
<tr>
<td align="center"></td>
<td align="center"></td>
</tr>
<tr>
<td align="center"></td>
<td align="center"><strong><span style="color: red">FATAL &gt; ERROR &gt; WARN &gt; INFO &gt; DEBUF &gt; TRACE<br>DEBUG 레벨로 했다면 INFO ~ FATAL까지 모두 logging 됨</span></strong></td>
</tr>
</tbody></table>
<br>

<h3 id="✔️-log4j-pattern-option">✔️ Log4j Pattern Option</h3>
<p>일반적으로 PatternLayout 을 사용하는 것이 디버깅에 가장 적합함</p>
<br>

<ul>
<li>붉은 색으로 표시된 항목은 실행속도에 영향이 있음</li>
</ul>
<table>
<thead>
<tr>
<th align="center">옵션</th>
<th align="center">설명</th>
</tr>
</thead>
<tbody><tr>
<td align="center">%p</td>
<td align="center">debug, info, warn, error, fatal 등의 priority 출력</td>
</tr>
<tr>
<td align="center">%m</td>
<td align="center">로그내용 출력</td>
</tr>
<tr>
<td align="center">%d</td>
<td align="center"><span style="color: red">로깅 이벤트가 발생한 시간을 출력<br>ex. 포멧은 %d{HH:mm:ss} 같은 형태의 SimpleDataFormat</span></td>
</tr>
<tr>
<td align="center">%t</td>
<td align="center">로그이벤트가 발생된 쓰레드의 이름 출력</td>
</tr>
<tr>
<td align="center">%F</td>
<td align="center"><span style="color: red">로깅이 발생한 프로그램 파일명 출력</span></td>
</tr>
<tr>
<td align="center">%I</td>
<td align="center"><span style="color: red">로깅이 발생한 caller의 정보 출력</span></td>
</tr>
<tr>
<td align="center">%L</td>
<td align="center"><span style="color: red">로깅이 발생한 caller의 라인수 출력</span></td>
</tr>
<tr>
<td align="center">%M</td>
<td align="center"><span style="color: red">로깅이 발생한 method 이름 출력</span></td>
</tr>
<tr>
<td align="center">%</td>
<td align="center">% 표시 출력</td>
</tr>
<tr>
<td align="center">%n</td>
<td align="center">플랫폼 종속적인 개행문자 출력</td>
</tr>
<tr>
<td align="center">%c</td>
<td align="center">카테고리 출력<br>ex. 카테고리가 a.b.c 처럼 되어있다면 %c{2}는 b.c 출력</td>
</tr>
<tr>
<td align="center">%C</td>
<td align="center"><span style="color: red">클래스명 출력<br>ex. 클래스구조가 org.apache.xyz.SomeClass 처럼 되어있다면 %C{2}는 xyz.SomeClass 출력</span></td>
</tr>
<tr>
<td align="center">%r</td>
<td align="center">어플리케이션 시작 이후 부터 로깅이 발생한 시점의 시간(milliseconds) 출력</td>
</tr>
<tr>
<td align="center">%x</td>
<td align="center">로깅이 발생한 thead와 관련된 NDC(nested diagnostic context) 출력</td>
</tr>
<tr>
<td align="center">%X</td>
<td align="center">로깅이 발생한 threan와 관련된 MDC(mapped diagnostic context) 출력</td>
</tr>
</tbody></table>
<p><br><br></p>
<h3 id="✔️-log4j-주요-클래스">✔️ Log4j 주요 클래스</h3>
<table>
<thead>
<tr>
<th align="center">클래스</th>
<th align="center">설명</th>
</tr>
</thead>
<tbody><tr>
<td align="center">ConsoleAppender</td>
<td align="center">org.apache.log4j.ConsoleAppender<br>콘솔에 로그 메시지 출력</td>
</tr>
<tr>
<td align="center">FileAppender</td>
<td align="center">org.apache.log4j.FileAppender<br>파일에 로그 메시지 기록</td>
</tr>
<tr>
<td align="center">RollingFileAppender</td>
<td align="center">org.apache.log4j.rolling.RollingFileAppender<br>파일 크기가 일정 수준 이상이 되면 기존 파일을 백업파일로 바꾸고 처음부터</td>
</tr>
<tr>
<td align="center">기록</td>
<td align="center"></td>
</tr>
<tr>
<td align="center">DailyRollingFileAppender</td>
<td align="center">org.apache.log4j.DailyRollingFileAppender<br>일정 기간 단위로 로그 파일을 생성하고 기록</td>
</tr>
<tr>
<td align="center">JDBCAppender</td>
<td align="center">org.apache.log4j.jdbc.JDBCAppender<br>DB 에 로그를 출력. 하위에 Driver, URL, User, Password, Sql 과 같은 parameter 를 정의할 수 있음</td>
</tr>
<tr>
<td align="center">SMTPAppender</td>
<td align="center">로그 메시지를 이메일로 전송</td>
</tr>
<tr>
<td align="center">NTEventAppender</td>
<td align="center">윈도우 시스템 이벤트 로그로 메시지 전송</td>
</tr>
<tr>
<td align="center"></td>
<td align="center"></td>
</tr>
</tbody></table>
<p><br><br></p>
<p>출처: <a href="https://cofs.tistory.com/354">https://cofs.tistory.com/354</a></p>
<p>  <br><br></p>
<h2 id="💡-log4j의-설정-방법">💡 Log4j의 설정 방법</h2>
  <br>

<h3 id="✔️-1-mvn-repository-검색">✔️ 1. MVN Repository 검색</h3>
  <br>

<p><a href="http://mvnrepository.com/">http://mvnrepository.com/</a> </p>
<p>MVN Repository 에서 log4jdbc 검색 → Log4Jdbc Log4j2 JDBC 선택→ 버전 맞게 복사해서 pom.xml 파일에 붙여넣기</p>
<pre><code class="language-c">&lt;!-- Logging --&gt;
&lt;!-- Log4JDBC -&gt; MVN REPOSITORY에서 가져옴! --&gt;
&lt;!-- https://mvnrepository.com/artifact/org.bgee.log4jdbc-log4j2/log4jdbc-log4j2-jdbc4.1 --&gt;        
&lt;dependency&gt;
    &lt;groupId&gt;org.bgee.log4jdbc-log4j2&lt;/groupId&gt;
    &lt;artifactId&gt;log4jdbc-log4j2-jdbc4.1&lt;/artifactId&gt;
    &lt;version&gt;1.16&lt;/version&gt;
&lt;/dependency&gt;</code></pre>
  <br>

<h3 id="✔️-2-log4jdbclog4j2properties-파일-생성-srcmainresources">✔️ 2. log4jdbc.log4j2.properties 파일 생성 (src/main/resources)</h3>
<pre><code class="language-c">log4jdbc.spylogdelegator.name=net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator</code></pre>
  <br>

<h3 id="✔️-3-log4jxml-파일-생성-srcmainresources">✔️ 3. log4j.xml 파일 생성 (src/main/resources)</h3>
<pre><code class="language-c">&lt;!-- 로깅 레벨 정리 --&gt;
&lt;!-- (ALL), DEBUG, INFO, WARN, ERROR, FATAL, (OFF) --&gt;

&lt;!-- 
    1. jdbc.connection : 열려있는 연결 수립 및 해제 이벤트를 기록, 연결문제를 찾아내느데 유용함.
    2. jdbc.sqltiming : SQL문과 해당 SQL을 실행시키는데(수행하는데) 걸린 시간 정보를 포함.
    3. jdbc.sqlonly : SQL문만 로그를 남김, PreparedStatement일 경우 ?(위치홀더)값이 완전히 보임.
    4. jdbc.audit : ResultSet을 제외한 모든 JDBC호출 정보를 로그로 남김. 로그양이 많고
                    필요하지 않으면 사용하지 않음.
    5. jdbc.resultset : ResultSet을 포함한 모든 JDBC호출 정보를 로그로 남김, 로그양이 많음.
    6. jdbc.resultsettable : SQL결과 조회된 데이터의 table을 그려줌.
 --&gt;

 &lt;logger name=&quot;jdbc.connection&quot; additivity=&quot;false&quot;&gt;
     &lt;level value=&quot;WARN&quot; /&gt;
     &lt;appender-ref ref=&quot;console&quot; /&gt;
 &lt;/logger&gt;

 &lt;logger name=&quot;jdbc.sqltiming&quot; additivity=&quot;false&quot;&gt;
     &lt;level value=&quot;WARN&quot; /&gt;
     &lt;appender-ref ref=&quot;console&quot; /&gt;
 &lt;/logger&gt;

 &lt;logger name=&quot;jdbc.sqlonly&quot; additivity=&quot;false&quot;&gt;
     &lt;level value=&quot;INFO&quot; /&gt;
     &lt;appender-ref ref=&quot;console&quot; /&gt;
 &lt;/logger&gt;

 &lt;logger name=&quot;jdbc.audit&quot; additivity=&quot;false&quot;&gt;
     &lt;level value=&quot;WARN&quot; /&gt;
     &lt;appender-ref ref=&quot;console&quot; /&gt;
 &lt;/logger&gt;

 &lt;logger name=&quot;jdbc.resultset&quot; additivity=&quot;false&quot;&gt;
     &lt;level value=&quot;WARN&quot; /&gt;
     &lt;appender-ref ref=&quot;console&quot; /&gt;
 &lt;/logger&gt;

 &lt;logger name=&quot;jdbc.resultsettable&quot; additivity=&quot;false&quot;&gt;
     &lt;level value=&quot;WARN&quot; /&gt;
     &lt;appender-ref ref=&quot;console&quot; /&gt;
 &lt;/logger&gt;</code></pre>
  <br>

<h3 id="✔️-4-root-contextxml-변경-driverclassname--url">✔️ 4. root-context.xml 변경 (driverClassName / url)</h3>
<pre><code class="language-c">    &lt;!-- Root Context: defines shared resources visible to all other web components --&gt;
    &lt;bean id=&quot;dataSource&quot; class=&quot;org.apache.commons.dbcp.BasicDataSource&quot; destroy-method=&quot;close&quot;&gt;
        &lt;property name=&quot;driverClassName&quot; value=&quot;net.sf.log4jdbc.sql.jdbcapi.DriverSpy&quot;&gt;&lt;/property&gt;
        &lt;property name=&quot;url&quot;              value=&quot;jdbc:log4jdbc:oracle:thin:@127.0.0.1:1521:XE&quot;&gt;&lt;/property&gt;
        &lt;property name=&quot;username&quot;             value=&quot;SPRING&quot;&gt;&lt;/property&gt;
        &lt;property name=&quot;password&quot;            value=&quot;SPRING&quot;&gt;&lt;/property&gt;
    &lt;/bean&gt;
&lt;/beans&gt;</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Java] 컬렉션 프레임워크(Collection Framework)]]></title>
            <link>https://velog.io/@jojo_/Java-%EC%BB%AC%EB%A0%89%EC%85%98Collection</link>
            <guid>https://velog.io/@jojo_/Java-%EC%BB%AC%EB%A0%89%EC%85%98Collection</guid>
            <pubDate>Mon, 25 Mar 2024 11:26:24 GMT</pubDate>
            <description><![CDATA[<h3 id="✔️-java-collections-framework-란">✔️ Java Collections Framework 란?</h3>
<p>Java에서 컬렉션(collection)이란 데이터의 집합, 그룹을 의미하며, JCK(Java Collection Framework)는 이러한 데이터, 자료구조인 컬렉션과 이를 구현하는 클래스를 정의하는 인터페이스를 제공합니다.</p>
<ul>
<li>Java 컬렉션 프레임워크 상속구조</li>
</ul>
<p><img src="https://velog.velcdn.com/images/jojo_/post/283dba3e-f33f-4b31-b75f-0a8d3764e2f6/image.png" alt=""></p>
<br>

<h3 id="✔️-collection-인터페이스의-특징">✔️ Collection 인터페이스의 특징</h3>
<br>

<table>
<thead>
<tr>
<th align="center">인터페이스</th>
<th align="center">구현 클래스</th>
<th align="center">특징</th>
</tr>
</thead>
<tbody><tr>
<td align="center">Set</td>
<td align="center">HashSet<br>TreeSet</td>
<td align="center">순서를 유지하지 않는 데이터의 집합으로 데이터의 중복을 허용하지 않는다.</td>
</tr>
<tr>
<td align="center">List</td>
<td align="center">LinkedList<br>Vector<br>ArraryList</td>
<td align="center">순서가 있는 데이터의 집합으로 데이터의 중복을 허용한다.</td>
</tr>
<tr>
<td align="center">Queue</td>
<td align="center">LinkedList<br>PriorityQueue</td>
<td align="center">List와 유사</td>
</tr>
<tr>
<td align="center">Map</td>
<td align="center">Hashtable<br>HashMap<br>TreeMap</td>
<td align="center">키(Key), 값(Value)의 쌍으로 이루어진 데이터의 집합으로, 순서는 유지되지 않으며 키(Key)의 중복을 허용하지 않으나, 값(Value)의 중복은 허용한다.</td>
</tr>
</tbody></table>
<br>

<h4 id="span-style--color--orange1-set-인터페이스span"><span style = "color : orange">1. Set 인터페이스</span></h4>
<p>순서를 유지하지 않는 데이터의 집합으로 데이터의 중복을 허용하지 않습니다.</p>
<ul>
<li><p><strong>HashSet</strong></p>
<ul>
<li>가장 빠른 임의 접근 속도</li>
<li>순서를 예측할 수 없음</li>
</ul>
</li>
<li><p><strong>TreeSet</strong></p>
<ul>
<li>정렬 방법을 지정할 수 있음</li>
</ul>
</li>
</ul>
<br>

<h4 id="span-style--color--orange2-list-인터페이스span"><span style = "color : orange">2. List 인터페이스</span></h4>
<p>순서가 있는 데이터의 집합으로 데이터의 중복을 허용합니다.</p>
<ul>
<li><p><strong>LinkedList</strong></p>
<ul>
<li>양방향 포인터 구조로 데이터의 삽입, 삭제가 빈번할 경우 위치 정보만 수정하면 되기에 유용하다.</li>
<li>스택, 큐, 양방향 큐 등을 만들기 위한 용도로 쓰임.</li>
</ul>
</li>
<li><p><strong>Vector</strong></p>
<ul>
<li>과거에 대용량 처리를 위해 사용했으며, 내부에서 자동으로 동기화처리가 일어나 성능이 좋지 않고 무거워서 잘 쓰이지 않음.</li>
</ul>
</li>
<li><p><strong>ArrayList</strong></p>
<ul>
<li>단방향 포인터 구조로 각 데이터에 대한 인덱스를 가지고 있어 조회 기능에 성능이 뛰어남</li>
</ul>
</li>
</ul>
<br>

<h4 id="span-style--color--orange3-map-인터페이스span"><span style = "color : orange">3. Map 인터페이스</span></h4>
<p>키(Key), 값(Value)의 쌍으로 이루어진 데이터의 집합으로, 순서는 유지되지 않으며 키(Key)dml 중복을 허용하지 않으나, 값(Value)의 중복은 허용합니다.</p>
<ul>
<li><p><strong>Hashtable</strong></p>
<ul>
<li>HashMap 보다는 느리지만 동기화를 지원함.</li>
<li>null 불가</li>
</ul>
</li>
<li><p><strong>HashMap</strong></p>
<ul>
<li>중복과 순서가 허용되지 않으며 null값이 올 수 있음.</li>
</ul>
</li>
<li><p><strong>TreeMap</strong></p>
<ul>
<li>정렬된 순서대로 키(Key)와 값(Value)을 지정하여 검색이 빠름.</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[인텔리제이에 MySQL 연결하기]]></title>
            <link>https://velog.io/@jojo_/%EC%9D%B8%ED%85%94%EB%A6%AC%EC%A0%9C%EC%9D%B4%EC%97%90-MySQL-%EC%97%B0%EA%B2%B0%ED%95%98%EA%B8%B0</link>
            <guid>https://velog.io/@jojo_/%EC%9D%B8%ED%85%94%EB%A6%AC%EC%A0%9C%EC%9D%B4%EC%97%90-MySQL-%EC%97%B0%EA%B2%B0%ED%95%98%EA%B8%B0</guid>
            <pubDate>Sat, 16 Mar 2024 02:51:09 GMT</pubDate>
            <description><![CDATA[<h3 id="✔️-인텔리제이에-database-연결">✔️ 인텔리제이에 Database 연결</h3>
<p><img src="https://velog.velcdn.com/images/jojo_/post/9754914e-50c2-4308-9803-c6fdf5ed7118/image.png" alt=""></p>
<p>우측 사이드바에 있는 Database 창을 열고 + 버튼을 클릭 후</p>
<p><img src="https://velog.velcdn.com/images/jojo_/post/86a9e5e5-da0c-492d-a001-d7561345592e/image.png" alt=""></p>
<p>MySQL 선택</p>
<p><img src="https://velog.velcdn.com/images/jojo_/post/a0d75b71-5900-4a2f-8916-37e3e115548a/image.png" alt=""></p>
<p>필요하다면 Comment 를 남기고, user 에 계정 등록고 Database 입력 후 Apply -&gt; OK 까지 진행하면 MySQL 연결 완료!</p>
<br>

<h4 id="database-계정-생성-및-권한-부여">Database 계정 생성 및 권한 부여</h4>
<pre><code class="language-c">show databases; # 데이터 베이스 조회

create database board; # board 데이터 베이스 생성

create user &#39;power&#39;@&#39;localhost&#39; identified by &#39;pass01&#39;; # 계정 생성
select user from mysql.user; # 계정 정보 조회
show grants for &#39;power&#39;@&#39;localhost&#39;; # 계정 권한 조회

grant all on board.* to &#39;power&#39;@&#39;localhost&#39; with grant option;
# 계정 권한 부여(개발 편의를 위해서 모든 권한 부여함)

flush privileges; #권한 테이블을 실제로 DB가 읽게끔 하는 명령어</code></pre>
]]></description>
        </item>
        <item>
            <title><![CDATA[유스케이스(UseCase)란?]]></title>
            <link>https://velog.io/@jojo_/%EC%9C%A0%EC%8A%A4%EC%BC%80%EC%9D%B4%EC%8A%A4UseCase%EB%9E%80</link>
            <guid>https://velog.io/@jojo_/%EC%9C%A0%EC%8A%A4%EC%BC%80%EC%9D%B4%EC%8A%A4UseCase%EB%9E%80</guid>
            <pubDate>Wed, 13 Mar 2024 12:05:07 GMT</pubDate>
            <description><![CDATA[<h3 id="✔️-유스케이스의-정의">✔️ 유스케이스의 정의</h3>
<p>요구사항을 사용자 중심으로 시나리오 분석을 통해 흐름을 나타내는 것을 말합니다.
시스템의 동작을 모형화하는 것으로, 개발자와 사용자의 상호작용을 표시하며, 목적은 시스템의 기능을 정의하는 것입니다.</p>
<br>

<h3 id="✔️-유스케이스를-사용하는-이유">✔️ 유스케이스를 사용하는 이유</h3>
<p><strong>해당 ViewModel이 어떤것을 하고자 하는지 직관적으로 파악할 수 있습니다.</strong></p>
<p>이것을 &quot;Screaming Architecture&quot; 라고 부르기도 하며, 어떠한 서비스를 제공하는지 한 눈에 알 수 있게 해주는 것입니다.
그러므로, UseCase의 이름은 직관적으로 어떤 것을 수행하는지 알 수 있게 지어야 하며, 이러한 구조는 여러명이 작업을 함께할 때 유용하게 쓰입니다.</p>
<br>

<h3 id="✔️-유스케이스-구축-시-주의사항">✔️ 유스케이스 구축 시 주의사항</h3>
<ul>
<li>시스템 내부를 모델링 하는 것이 아님</li>
<li>비기능적 요구를 찾아내는 데 효과적인 방법이 아님</li>
<li>시스템의 흐름도가 아님</li>
<li>어떻게가 아니라 &quot;무엇을&quot; 시스템이 하는가를 담아야 함</li>
</ul>
<br>

<h3 id="✔️-유스케이스-다이어그램">✔️ 유스케이스 다이어그램</h3>
<p>시스템의 기능을 나타내기 위해 <strong>사용자의 요구를 추출하고 분석하는데 사용합니다.</strong></p>
<ul>
<li>구성<ul>
<li><strong>유스케이스</strong> - 시스템 기능</li>
<li><strong>액터</strong> - 시스템과 상호작용을 하는 것(<strong>사용자이기도 하고 시스템이기도 함</strong>)</li>
</ul>
</li>
</ul>
<p><img src="https://velog.velcdn.com/images/jojo_/post/d2eb6d40-ef84-4ffa-9d35-74a48870808b/image.png" alt=""></p>
<ul>
<li>액터와 유스케이스를 정의하는 것은 <strong>시스템의 범위</strong>를 정하는 것입니다.</li>
</ul>
<br>
]]></description>
        </item>
        <item>
            <title><![CDATA[Garbage Collection의 개념]]></title>
            <link>https://velog.io/@jojo_/Garbage-Collection%EC%9D%98-%EA%B0%9C%EB%85%90</link>
            <guid>https://velog.io/@jojo_/Garbage-Collection%EC%9D%98-%EA%B0%9C%EB%85%90</guid>
            <pubDate>Tue, 12 Mar 2024 06:38:57 GMT</pubDate>
            <description><![CDATA[<h3 id="✔️-garbage-collection-이란">✔️ Garbage Collection 이란?</h3>
<p>일반적으로 프로그램이 실행될 때, 메모리는 동적으로 할당되어 사용이 되는데, 이렇게 사용된 메모리는 필요 없어지만 다시 해제되어야 합니다.</p>
<p>이러한 불필요한 메모리 영역을 자동으로 탐지하고 해제하여 프로그램이 메모리를 효율적으로 사용할 수 있도록 하는 걸 Garbage Collection 이라고 합니다.</p>
<br>

<h3 id="✔️-garbage-collection-의-장점">✔️ Garbage Collection 의 장점</h3>
<ul>
<li>메모리를 자동으로 관리하기 때문에 수동으로 관리하던 것에서 비롯된 에러를 방지할 수 있습니다.<ul>
<li>개발자의 실수로 인한 메모리 누수</li>
<li>해제된 메모리를 또 해제하는 이중 해제</li>
<li>해제된 메모리에 접근</li>
</ul>
</li>
</ul>
<br>

<h3 id="✔️-garbage-collection-의-단점">✔️ Garbage Collection 의 단점</h3>
<ul>
<li>GC의 메모리 해제 타이밍을 개발자가 정확히 알기 어렵습니다.</li>
<li>어떠한 메모리 영역이 해제의 대상이 될 지 검사하고, 실제로 해제하는 일이 모두 오버헤드입니다.</li>
</ul>
<br>


<h3 id="✔️-garbage-collection-의-한계">✔️ Garbage Collection 의 한계</h3>
<p>어떤 방식의 Garbage Collection을 사용하든 실행 시간에 작업을 하는 이상 성능 하락을 피할 수 없고, 더 이상 젒근이 불가능한 객체만 회수하기 때문에 메모리 누수는 발생할 수 있다는 한계가 있습니다.</p>
<br>


<h3 id="✔️-garbage-collection-의-실행-방식">✔️ Garbage Collection 의 실행 방식</h3>
<ul>
<li>Stop The World : GC가 실행되면 JVM이 잠시 멈추는 현상.</li>
</ul>
<p><strong>Serial GC</strong></p>
<p>Serial GC는 하나의 스레드로 GC를 실행하는 방식인데, 하나의 스레드로 GC를 실행하다 보니 Stop The World 시간이 긴 것을 알 수 있습니다. 싱글 스레드 환경 및 Heap 영역이 매우 작을 때 사용되는 방식입니다.</p>
<p><strong>Parallel GC</strong></p>
<p>Parallel GC의 기본적인 처리 과정은 Serial GC와 동일합니다.
다만, Parallel GC는 여러개의 스레드로 GC를 실행하기 때문에 앞선 Serial GC보다 Stop The World 시간이 짧아집니다. 멀티 코어 환경에서 애플리케이션 처리 속도를 향상시키기 위해 사용되며, Java 8 에서 기본적으로 쓰이는 GC 방식입니다.</p>
<p><strong>CMS GC</strong></p>
<p>CMS GC 에서 CMS는 Concurrent-Mark-Sweep의 줄임말로 Stop The World 시간을 최소화 하기 위해 고안되었습니다. 대부분의 Garbage 수집 작업을 애플리케이션 스레드와 동시에 수행하여 Stop The World 시간을 최소화 하고 있습니다. 하지만 메모리와 CPU를 많이 사용하고, Mark And Sweep 과정 이후 메모리 파편화를 해결하는 Compaction이 기본적으로 제공되지 않는다는 단점이 있습니다.</p>
<p><strong>CMS GC</strong></p>
<p>G1 GC는 전체 힙을 작은 영역으로 나누고, 각 영역에서 Garbage Collection을 수행하는데, 이 과정에서 더 이상 필요하지 않은 객체를 식별하고 메모리에서 제거합니다.
이렇게 작은 영역으로 나눠 병렬로 Garbage Collection을 실행하면 전체 프로그램에 영향을 최소화하면서도 메모리를 효율적으로 관리할 수 있고, G1 GC는 성능을 최적화하기 위해 가장 부담이 큰 영역을 먼저 처리합니다.
또, 프로그램을 중단시키지 않고도 메모리를 효율적으로 관리해서 프로그램의 안정성과 성능을 유지하며 메모리를 관리합니다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[객체지향 패러다임]]></title>
            <link>https://velog.io/@jojo_/%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5-%ED%8C%A8%EB%9F%AC%EB%8B%A4%EC%9E%84</link>
            <guid>https://velog.io/@jojo_/%EA%B0%9D%EC%B2%B4%EC%A7%80%ED%96%A5-%ED%8C%A8%EB%9F%AC%EB%8B%A4%EC%9E%84</guid>
            <pubDate>Fri, 01 Mar 2024 08:19:23 GMT</pubDate>
            <description><![CDATA[<h3 id="✔️-객체지향의-4가지-특징">✔️ 객체지향의 4가지 특징</h3>
<br>

<p><strong>1. 추상화 (Abstraction)</strong></p>
<p>추상화란 불필요한 부분을 제거함으로써 필요한 핵심만 나타낸 것입니다.
흔히 일반화, 단순화라고도 생각하고 이를 사용하는 목적은 복잡성을 낮추기 위해 사용합니다.</p>
<p><strong>2. 다형성 (Poltmorphism)</strong></p>
<p>다양한 형태를 가지는 것을 다형성이라고합니다.
하나의 타입으로 여러 종류의 타입을 가질 수 있는 것을 의미합니다</p>
<p><strong>3. 캡슐화 (Encapsulation)</strong></p>
<p>객체 내부의 세부사항을 외부로부터 감추는 것입니다.
이러한 캡슐화의 목적은 인터페이스만 공개해서 변경하기 쉬운 코드를 만들기 위함이라고 생각합니다.</p>
<p><strong>4. 상속 (Inheritance)</strong></p>
<p>객체들 간의 관계를 구축하는 방법으로, 부모로부터 상속받아 객체의 요소를 사용하는 것입니다.</p>
<br>


<h3 id="✔️-객체지향의-5가지-설계-원칙-solid">✔️ 객체지향의 5가지 설계 원칙 (SOLID)</h3>
<br>

<p><strong>1. SRP : Single Responsibility Principle (단일 책임의 원칙)</strong></p>
<p>모드 클래스는 하나의 책임만을 가지며, 클래스는 그 책임을 완전히 캡슐화해야 함을 일컫습니다.</p>
<p><strong>2. OCP : Open/Closed Principle (개방 폐쇠의 원칙)</strong></p>
<p>기존 코드를 변경하지 않으면서, 기능을 추가할 수 있도록 설계되어야 한다는 원칙입니다.</p>
<p><strong>3. LSP : Liskov&#39;s Substitution Principle (리스코프 치환의 원칙)</strong></p>
<p>상위 타입의 객체를 하위 타입의 객체로 치환해도 동작에 전혀 문제가 없어야 한다는 원칙입니다.</p>
<p><strong>4. ISP : Interface Segregation Principle (인터페이스 분리의 원칙)</strong></p>
<p>많은 원칙을 가진 인터페이스를 작은 단위로 분리시킴으로써 클라이언트에게 필요한 인터페이스들로만 구현하다록 하는 원칙입니다.</p>
<p><strong>5. DIP : Dependency Inversion Principle (의존성 역전의 원칙)</strong></p>
<p>의존관계를 맺을 때 자주 변경되는 쪽이 아니라 변경이 거의 일어나지 않는 쪽에 의존하라는 의미이며, 자기보다 변하기 쉬운 것에 의존하게 되면 변화의 영향을 많이 받기 때문에 추상화된 인터페이스나 상위 클래스를 두어서 변화의 영향을 받지 않게 하기 위한 원칙입니다.</p>
<br>


<h3 id="✔️-객체지향-패러다임">✔️ 객체지향 패러다임</h3>
<ul>
<li>적저한 객체에게 적적한 책임을 할당하여 서로 메세지를 주고 받으며 협력하도록 하는 것.</li>
<li>전점 증가하는 SW 복잡도를 낮추기 위해 객체지향 패러다임이 대두되고 있습니다.<ul>
<li>클래스가 아닌 객체에 초점을 맞추어야 합니다.</li>
<li>객체들에게 적절한 역할과 책임을 할당해야합니다.</li>
</ul>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[리팩토링의 목적]]></title>
            <link>https://velog.io/@jojo_/%EB%A6%AC%ED%8C%A9%ED%86%A0%EB%A7%81%EC%9D%98-%EB%AA%A9%EC%A0%81</link>
            <guid>https://velog.io/@jojo_/%EB%A6%AC%ED%8C%A9%ED%86%A0%EB%A7%81%EC%9D%98-%EB%AA%A9%EC%A0%81</guid>
            <pubDate>Thu, 29 Feb 2024 08:38:01 GMT</pubDate>
            <description><![CDATA[<h3 id="✔️-코드-리팩토링이란">✔️ 코드 리팩토링이란?</h3>
<ul>
<li>외부 동작을 바꾸지 않으면서 내부 구조를 개선하는 방법입니다.</li>
<li>코드가 작성된 후 디자인을 개선하는 작업니다.</li>
<li>가독성을 높이고 유지보수를 편하게 합니다.</li>
<li>버그를 없애거나 새로운 기능을 추가하지는 않습니다.</li>
</ul>
<p>쉽게 말하자면, 현재 코드의 동작은 그대로 유지하면서 더 이해하기 쉽고 확장하기 쉽게끔 재구성하는 것입니다.</p>
<br>

<h3 id="✔️-리팩토링의-목적">✔️ 리팩토링의 목적</h3>
<ul>
<li>중복을 제거함으로써 각각의 작업에 대한 코드가 오직 한 곳에만 있게 합니다.</li>
<li>수정 용이성을 향상시킵니다.</li>
<li>소프트웨어를 보다 이해하기 쉽고, 수정하기 쉽도록 만듭니다.</li>
<li>버그를 찾는데 도움이 됩니다.</li>
<li>프로그램 개발 속도가 향상됩니다.</li>
</ul>
<br>

<h3 id="✔️-리팩토링의-사용-시기">✔️ 리팩토링의 사용 시기</h3>
<p><strong>1. The Rule Of Three : 유사한 내용이 세번 이상 반복될 때</strong></p>
<ul>
<li>똑같거니 비슷한 내용이 세 번 이상 작성되어 있으면 상황에 고려하여 리팩토링을 결정합니다.</li>
</ul>
<p><strong>2. 새로운 기능을 추가할 때</strong></p>
<ul>
<li>지금 작성된 설계, 소스코드에서 새로운 기능을 추가하기 어려워 보이면, 리팩토링을 해야합니다. 이러한 경우 유지보수성이 떨어지며, 가독성 역시 좋지 않을 수 있습니다.</li>
</ul>
<p><strong>3. 코드리뷰를 할 때</strong></p>
<ul>
<li>협업하는 동료들과 함께하는 코드리뷰는 코드의 질을 높일 수 있습니다. 너무 많은 인원이 함께하는 경우엔 비효율적이므로 소수 인원으로 진행하는 걸 권장합니다.
다만, 설계 단계에서는 많은 인원이 참여해도 효과적일 수 있습니다.</li>
</ul>
<br>

<h3 id="✔️-리팩토링을-하지-않아야-할-때">✔️ 리팩토링을 하지 않아야 할 때</h3>
<ul>
<li>현재 코드가 작동하지 않는다면 리팩토링이 아니라 코드를 새로 작성해야 합니다. 리팩토링을 하기 전에 코드가 제대로 작동하는지 확인해야합니다.</li>
</ul>
<br>

<h3 id="✔️-리팩토링의-절차">✔️ 리팩토링의 절차</h3>
<p><img src="https://velog.velcdn.com/images/jojo_/post/2b172868-73e2-44ed-a5d6-766ba68253cc/image.png" alt=""></p>
<ul>
<li>소규모 변경 후 동작여부를 테스트하고 작동할 경우 다음단계, 그렇지 않을 경우 undo 후 리팩토링을 진행해야합니다.</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[JUnit으로 비밀번호 유효성 검증하기]]></title>
            <link>https://velog.io/@jojo_/JUnit%EC%9C%BC%EB%A1%9C-%EB%B9%84%EB%B0%80%EB%B2%88%ED%98%B8-%EC%9C%A0%ED%9A%A8%EC%84%B1-%EA%B2%80%EC%A6%9D</link>
            <guid>https://velog.io/@jojo_/JUnit%EC%9C%BC%EB%A1%9C-%EB%B9%84%EB%B0%80%EB%B2%88%ED%98%B8-%EC%9C%A0%ED%9A%A8%EC%84%B1-%EA%B2%80%EC%A6%9D</guid>
            <pubDate>Wed, 28 Feb 2024 16:13:04 GMT</pubDate>
            <description><![CDATA[<blockquote>
<h3 id="목표">목표</h3>
</blockquote>
<ol>
<li>요구사항에 맞춰 유효성 검증</li>
<li>검증 후 코드 리팩터링</li>
<li>테스트 코드 작성하는 이유 생각하기</li>
</ol>
<h4 id="요구사항">요구사항</h4>
<ul>
<li>비밀번호는 최소 8자 이상 12자 이하여야 한다.</li>
<li>비밀번호가 8자 미만 또는 12자 초과인 경우 IllegalArgumentException 예외를 발생시킨다.</li>
</ul>
<hr>
<h4 id="✔️-테스트-코드">✔️ 테스트 코드</h4>
<pre><code class="language-c">public class PasswordValidatorTest {

    @DisplayName(&quot;비밀번호가 최소 8자 이상, 12자 이하면 예외가 발생하지 않는다.&quot;)
    @Test
    void validatePasswordTest() {

        // PasswordValidator 클래스를 src -&gt; main 폴더에 동일하게 생성
        // PasswordValidator 에 validate 메서드 작성
        assertThatCode(() -&gt; PasswordValidator.validate(&quot;serverwizard&quot;))
                .doesNotThrowAnyException();
    }

    @DisplayName(&quot;비밀번호가 8자 미만 또는 12자 초과하는 경우 IllegalArgumentException 예외가 발생한다.&quot;)
    @ParameterizedTest
    @ValueSource(strings = {&quot;aabbcce&quot;, &quot;aabbccddeeffg&quot;}) // 경계값에서 오류여부 확인을 위해 작성
    void validatePasswordTest2(String password) {

        assertThatCode(() -&gt; PasswordValidator.validate(password))
                .isInstanceOf(IllegalArgumentException.class)
                .hasMessage(&quot;비밀번호는 최소 8자 이상 12자 이하여야 한다.&quot;);
    }
}</code></pre>
<h4 id="✔️-프로덕션-코드">✔️ 프로덕션 코드</h4>
<pre><code class="language-c">public class PasswordValidator {

    public static final String WRONG_PASSWORD_LENGTH_EXCEPTION_MESSAGE = &quot;비밀번호는 최소 8자 이상 12자 이하여야 한다.&quot;;

    public static void validate(String password) {

        // if(password.length() &lt; 8 || password.length() &gt; 12) {
        // 위 코드를 아래코드와 같이 리팩토링을 함.
        // 테스트 코드이기 때문에 리팩토링이 자유로움.
        int length = password.length();
        if(length &lt; 8 || length &gt; 12) {
            throw new IllegalArgumentException(WRONG_PASSWORD_LENGTH_EXCEPTION_MESSAGE);
        }
    }
}</code></pre>
<h4 id="✔️-결과">✔️ 결과</h4>
<p><img src="https://velog.velcdn.com/images/jojo_/post/644eccc3-d7c6-4656-a8b3-7127725c3807/image.png" alt=""></p>
<hr>
<p><strong>장점</strong>
<small></p>
<ol>
<li>테스트 코드이기 때문에 여러번 수정하는 게 부담스럽지 않아서 더 좋은 코드를 작성하기 위해 계속 고민하게 되었습니다.</li>
<li>작성한 코드를 검증하는 과정을 거치기 때문에 버그를 방지할 수 있습니다.</li>
<li>그 과정에서 작성한 코드의 품질이 향상된다는 생각이 들었고, 자연스럽게 리팩터링을 하게 되어서 이런 장점이 있기 때문에 테스트 코드를 작성한다고 느꼈습니다!</small>

</li>
</ol>
<p><strong>단점</strong>
<small></p>
<ol>
<li>테스트 코드로 검증하는 과정을 거쳤기 때문에 개발 시간이 길어졌습니다.</li>
<li>회사에서 테스트 코드를 작성한다고 생각한다면 개발 기간이 늘어나기 때문에 발생하는 비용이 늘어날 수 있겠다는 생각이 들었습니다.</small></li>
</ol>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Doker] 도커와 도커 컴포즈]]></title>
            <link>https://velog.io/@jojo_/Doker-%EB%8F%84%EC%BB%A4%EC%99%80-%EB%8F%84%EC%BB%A4-%EC%BB%B4%ED%8F%AC%EC%A6%88</link>
            <guid>https://velog.io/@jojo_/Doker-%EB%8F%84%EC%BB%A4%EC%99%80-%EB%8F%84%EC%BB%A4-%EC%BB%B4%ED%8F%AC%EC%A6%88</guid>
            <pubDate>Fri, 01 Dec 2023 06:41:33 GMT</pubDate>
            <description><![CDATA[<h2 id="도커와-도커-컴포즈란">도커와 도커 컴포즈란?</h2>
<ul>
<li><strong>도커(Doker)</strong> : 도커는 컨테이너 기술을 사용하여 애플리케이션을 패키징하고 배포하기 위한 플랫폼이다. 도커 컨테이너는 애플리케이션과 모든 종속성을 포함하며, 어디서든 실행 가능하다.<br></li>
<li><strong>도커 컴포즈(Doker Compose)</strong> : 도커 컴포즈는 멀티 컨테이너 애플리케이션을 정의하고 관리하기 위한 도구로, 여러 도커 컨테이너를 하나의 애플리케이션 스택으로 정의하고 실행할 수 있다.<br>
## 도커와 도커 컴포즈의 주요 개념</li>
<li><strong>도커 이미지(Doker Image)</strong> : 도커 이미지는 애플리케이션과 그 종속성을 패키징한 가상 이미지로, 이미지는 컨테이너의 기반이 된다.<br></li>
<li><strong>도커 컨테이너(Doker Contatiner)</strong> : 도커 컨테이너는 도커 이미지의 실행 가능한 인스턴스이다.<br></li>
<li><strong>도커 컴포즈 파일(Doker Compose File)</strong> : 도커 컴포즈 파일은 멀티 컨테이너 애플리케이션을 정의하고 구성하는 YAML 파일이다.
  <strong><small>* 단일 컨테이너 vs 멀티 컨테이너 : </small></strong>
  <strong><small>- 도커 : ** Doker는 주로 단일 컨테이너를 빌드하고 실행하는 데 사용된다. 예를 들어, 웹서버, 데이터베이스 서버 및 애플리케이션 서버와 같이 독립적인 서비스를 단일 컨테이너로 빌드하는데 유용하다.</small>
  **<small>- 도커 컴포즈 : Doker Compose는 여러 컨테이너로 구성된 애플리케이션을 정의하고 실행하는데 사용된다. 예를 들어, 웹 애플리케이션과 그에 연결된 데이터베이스, 캐시 서버 등 여러 컨테이너로 구성된 애플리케이션 스택을 정의하는데 유용하다.</strong></small></li>
</ul>
<br>

<h2 id="주요-차이점-비교">주요 차이점 비교</h2>
<h3 id="배포-대상">배포 대상</h3>
<ul>
<li>*<em>도커 : *</em> 개별 컨테이너의 배포와 관리에 주로 사용 됨.</li>
<li>*<em>도커 컴포즈 : *</em> 멀티 컨테이너 애플리케이션 스택을 정의하고 관리하는데 사용 됨.<br>
### 컨테이너 관리</li>
<li>*<em>도커 : *</em> 개별 컨테이너를 개발자가 직접 다룸.</li>
<li>*<em>도커 컴포즈 : *</em> 여러 컨테이너 간의 관계와 설정을 정의하여 스택을 관리함.<br>
### 사용 편의성</li>
<li>*<em>도커 : *</em> 단일 컨테이너를 관리하기에 간단함.</li>
<li>*<em>도커 컴포즈 : *</em> 복잡한 멀티-컨테이너 애플리케이션을 관리하기 용이함.</li>
</ul>
<br>

<hr>
<p>정리하자면, Docker는 개별 컨테이너를 관리하는데 사용되고, Doker Compose는 멀티 컨테이너 애플리케이션 스택을 정의하고 실행하기 위한 도구이다.</p>
<p>둘 다 Doker 기술을 기반으로 하며, 프로젝트 규모와 요구 사항에 따라 적절한 도구를 선택해야 한다.</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[JDK란 무엇인가?]]></title>
            <link>https://velog.io/@jojo_/JDK%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80</link>
            <guid>https://velog.io/@jojo_/JDK%EB%9E%80-%EB%AC%B4%EC%97%87%EC%9D%B8%EA%B0%80</guid>
            <pubDate>Thu, 30 Nov 2023 08:22:06 GMT</pubDate>
            <description><![CDATA[<h2 id="jdk--자바-개발-키트java-development-kit-jdk">JDK : 자바 개발 키트(Java Development Kit, JDK)</h2>
<p>자바 플랫폼의 등장 이래로 가장 많이 사용되는 소프트웨어 개발 키트(SDK).
즉, JDK란 자바로 소프트웨어를 개발할 수 있도록 기능을 제공하는 개발 키트라고 볼 수 있다.</p>
<br>

<h2 id="jdk의-구성">JDK의 구성</h2>
<p>JDK는 크게 6가지 파일로 구성되어 있으며, 파일 위치는 다음과 같다.</p>
<ul>
<li><strong>실행 파일(bin/)</strong> : 자바의 실행 환경 (Java Runtime Environment, JRE)을 구현한 것으로, JRE는 자바 가상머신, 클래스 라이브러리, 자바 언어로 작성된 프로그램 작동에 필요한 파일을 포함하고 있으며, 같은 위치에 프로그램 개발에 필요한 모든 툴과 유틸리티도 포함되어 있다. <br></li>
<li><strong>구성 파일(conf/)</strong> : 사용자 구성 옵션을 포함하고 있는 파일들로써, JDK 접근 권한 설정, 보안 알고리즘 변경, 자바 암호화 확장 정책 등을 설정할 수 있다.<br></li>
<li><strong>C헤더 파일(include/)</strong> : 자바 가상머신 디버거인터페이스와 자바네이티브인터페이스의 네이티브 코드를 작성하는데 사용되는 C헤더 파일<br></li>
<li><strong>자바 모듈 (jmods/)</strong> : jlink를 이용하여 사용자 지정 런타임을 만드는데 사용되는 모듈<br></li>
<li><strong>저작권 및 라이선스 (legal/ )</strong> : 각 모듈에 대한 라이선스와 저작권에 대한 내용, 제삼자 제공 포함<br></li>
<li><strong>추가 라이브러리 (lib/ )</strong> : JDK에 필요한 추가 클라스 라이브러리와 지원 파일 (외부 사용을 목적으로 하지 않음)</li>
</ul>
<hr>
<p>JDK의 핵심을 이루는 개발 툴들은 굉장히 많은데, 내가 많이 들어본 것들만 정리해보았다.</p>
<ul>
<li><strong>appletviewer</strong> - 웹브라우저 없이 자바 애플릿을 실행하고 디버깅하기 위한 툴<br></li>
<li>*<em>apt *</em> : 애너테이션 처리 툴<br></li>
<li><strong>idlj</strong> :  IDL을 자바로 컴파일 해주는 툴. 주어진 자바 IDL 파일에 대한 자바 바인딩을 만들어 준다.<br></li>
<li>*<em>java *</em> : 자바 응용 프로그램 로더. javac 컴파일러가 만든 클래스 파일을 해석 및 실행한다. 현재는 하나의 런처가 개발 및 배포에 동일하게 사용된다. 예전에 사용되던 배포용 런처 jre는 더이상 Sun JDK에서는 제공되지 않고, 이 로더로 대체되었다.<br></li>
<li><strong>javac</strong> : 자바 컴파일러. 자바 소스 파일을 바이트코드로 변환해준다.<br></li>
<li><strong>javadoc</strong> : 소스 코드 주석으로부터 자동으로 문서를 생성해주는 툴<br></li>
<li><strong>jar</strong> : 서로 관련있는 클래스 라이브러리들과 리소스들을 하나의 JAR 파일로 묶어주는 툴. Jar 파일을 관리하는데도 사용된다.<br></li>
<li><strong>jdb</strong> : 자바 디버깅 툴<br>

</li>
</ul>
<h2 id="jdk-종류">JDK 종류</h2>
<ul>
<li><strong>Oracle JDK</strong> : Oracle에서 제공하는 JDK. 구독을 통해 유료 라이센스를 구매할 수 있다. <br></li>
<li><strong>Open JDK</strong> : 무료 JDK. 하지만 OpenJDK를 직접 사용하는것 보다는, OpenJDK 기반으로 빌드된 JDK 사용을 추천한다.<br></li>
<li><strong>Azul Zulu</strong> : 인지도가 높은 JDK 중 하나이며, Mac 등에서 사용할 수 있는 바이너리를 제공하는 것이 특징이다.<br></li>
<li><strong>Amazon Corretto</strong> : AWS에서 제공하는 JDK. AWS에서 쉽게 사용 가능하며, AWS 환경이 아니더라도 사용할 수 있다.<br></li>
<li><strong>Temurin</strong> : Eclipse에서 제공하는 JDK. Eclipse를 사용한다면 Temurin 설치를 추천한다.</li>
</ul>
<p><br><br>
[출처]
<a href="https://ko.wikipedia.org/wiki/%EC%9E%90%EB%B0%94_%EA%B0%9C%EB%B0%9C_%ED%82%A4%ED%8A%B8">https://ko.wikipedia.org/wiki/%EC%9E%90%EB%B0%94_%EA%B0%9C%EB%B0%9C_%ED%82%A4%ED%8A%B8</a> - 위키백과</p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JAVA] this 와 this()]]></title>
            <link>https://velog.io/@jojo_/JAVA-this-%EC%99%80-this</link>
            <guid>https://velog.io/@jojo_/JAVA-this-%EC%99%80-this</guid>
            <pubDate>Tue, 29 Aug 2023 10:42:38 GMT</pubDate>
            <description><![CDATA[<h2 id="💡-java-this-키워드">💡 Java this 키워드</h2>
<br>

<h3 id="✔️-this-키워드의-개념">✔️ this 키워드의 개념</h3>
<p>this는 객체 자신을 가르키는 레퍼런스 변수로, 자신의 객체에 접근할 때 사용됩니다.</p>
<br>

<h3 id="✔️-this-키워드의-역할">✔️ this 키워드의 역할</h3>
<ol>
<li><p>자기 자신의 메모리를 가르킵니다.</p>
</li>
<li><p>생성자에서 다른 생성자를 호출할 경우 사용합니다.</p>
</li>
<li><p>인스턴스 자신의 주소를 반환할 때 사용합니다.</p>
</li>
</ol>
<br>

<p><strong><span style="color: navy"> 1-1. 자기 자신의 메모리를 가르킵니다.</span></strong></p>
<pre><code class="language-c">public class Member {
    // 필드
    private String memberId;

    // getter, setter
    public String getMemberId() {
        return memberId;    // 자신의 주소를 반환한다.
    }

    public void setMemberId(String memberId) {
        this.memberId = memberId;    // 필드값을 가르킨다.
    }
}</code></pre>
<p><strong><span style="background-color: yellow"> 이때, this 키워드를 사용하지 않으면 매개변수 이름과 대입하는 이름이 똑같기 때문에 구분할 수 없어서 에러가 발생합니다.</span></strong></p>
<br>

<p><strong><span style="color: navy"> 2-1. 생성자에서 다른 생성자를 호출할 경우 사용합니다.</span></strong></p>
<pre><code class="language-c">public class Member {

    String memberId;
    String memberName;

    public Member() {
        this(&quot;user01&quot;, &quot;김이름&quot;);    // 하단 생성자 호출
    }

    public Member(String memberId, String memberName) {
        this.memberId = memberId;
        this.memberName = memberName;
    }
</code></pre>
<br>

<p><strong><span style="color: navy"> 3-1. 인스턴스 자신의 주소를 반환할 때 사용합니다.</span></strong></p>
<pre><code class="language-c">public class Member {

    private String memberId;
    private String membername;

    public Member(String memberId, String memberName) {
        this.memberId = memberId;
        this.memberName = memberName;
    }

    public Member getMember() {
        return this;
    }
}</code></pre>
<p>Member 클래스에서 반환 타입을 Member로 설정한 getMember 메소드에서 반환 시 this를 반환합니다.</p>
<br>

<h2 id="💡-java-this">💡 Java this()</h2>
<br>

<h3 id="✔️-this의-개념">✔️ this()의 개념</h3>
<p>같은 클래스에서 생성자가 다른 생성자를 호출할 때 사용합니다.</p>
<br>

<h3 id="✔️-this의-특징">✔️ this()의 특징</h3>
<ul>
<li><p>주로 코드의 중복을 줄일 목적으로 사용됩니다.</p>
</li>
<li><p>this()는 <strong><span style="background-color: yellow">생성자 코드에서만 사용</span></strong>할 수 있습니다.</p>
</li>
<li><p>this()는 생성자 코드안에서 사용될 때 <strong><span style="background-color: yellow">첫번째 문장으로 다른 코드보다 가장 윗줄에 위치</span></strong>해야합니다.</p>
</li>
</ul>
]]></description>
        </item>
        <item>
            <title><![CDATA[[Spring] Spring 이란?]]></title>
            <link>https://velog.io/@jojo_/Spring-Spring-%EC%9D%B4%EB%9E%80</link>
            <guid>https://velog.io/@jojo_/Spring-Spring-%EC%9D%B4%EB%9E%80</guid>
            <pubDate>Mon, 14 Aug 2023 11:43:43 GMT</pubDate>
            <description><![CDATA[<h2 id="💡-spring-이란">💡 Spring 이란?</h2>
<br>

<p>스프링(Spring)은 JAVA 언어를 기반으로 사용하며, JAVA 기술들을 더 쉽게 사용할 수 있게 해주는 오픈소스 프레임워크(Framework) 입니다.</p>
<p>대한민국 공공기관의 웹 서비스 개발 시 사용을 권장하고 있는 정자정부 표준 프레임 워크 반 기술로서 쓰이고 있습니다.</p>
<br>

<p><strong>- 공식 사이트</strong> : <a href="https://spring.io/">https://spring.io/</a></p>
<br>

<h3 id="✔️-spring의-특징">✔️ Spring의 특징</h3>
<br>

<p><strong>1. 컨테이너 역할</strong></p>
<p>각각의 객체 생성, 소멸과 같은 라이프 사이클을 관리하며 스프링으로부터 필요한 객체를 얻어올 수 있습니다.
<br></p>
<p><strong>2. 제어 역행(IOC : Inversion of Control)</strong></p>
<p>프로그램을 구동하는데 필요한 객체에 대한 생성, 변경 등의 관리를 프로그램을 <strong>개발하는 사람이 아닌 프로그램을 구동하는 컨테이너에서 직접 관리</strong>하는 것을 말합니다.
<br></p>
<p><strong>3. 의존성 주입(DI : Dependency Injection)</strong></p>
<p><strong>IoC 구현의 핵심 기술</strong>로, 사용하는 객체를 직접 생성하여 만드는 것이 아니라 컨테이너가 빈의 설정 정보를 읽어와 자동으로 해당 객체에 연결하는 것을 말합니다.</p>
<p>이렇게 의존성을 주입 받게 되면 이후 해당 객체를 수정해야 할 상황이 발생했을 때 소스 코드의 수정을 최소화 할 수 있습니다.
<br></p>
<p><strong>4. 관점지향 프로그래밍(AOP : Aspect-Oriented Programming)</strong></p>
<p>트랜잭션이나 로깅, 보안과 같이 여러 모듈에서 공통적으로 사용하는 기능의 경우 해당 기능을 분리하여 관리할 수 있습니다.
<br></p>
<p>*<em>5. MVC 패턴  *</em></p>
<p>웹 프로그래밍 개발 시 거의 표준적인 방식인 &quot;Spring MVC&quot;라 불리는 모델-뷰-컨트롤러 패턴을 이용한다.
<br></p>
<p><strong>6. POJO 방식의 프레임워크</strong></p>
<p>Plain Old Java Object 방식의 프레임워크로, 단순히 평범한 자바 빈즈(Javabeans) 객체를 의미합니다.
<br></p>
<p><strong>7. 높은 확장성</strong></p>
<p>스프링 프레임워크에 통합하기 위해 간단하게 기존 라이브러리를 감싸는 정도로 스프링에서 사용이 가능하기 때문에 수많은 라이브러리가 이미 스프링에서 지원되고 있고 스프링에서 사용되는 라이브러리를 별도로 분리하기도 용이합니다.
<br><br><br></p>
<h3 id="✔️-스프링-모듈">✔️ 스프링 모듈</h3>
<br>

<h4 id="1-spring-core">1. Spring Core</h4>
<ul>
<li><p>Spring 프레임워크의 근간이 되는요소. IoC(또는 DI) 기능을 지원하는 영역을 담당합니다.</p>
</li>
<li><p>BeanFactory를 기반으로 Bean 클래스들을 제어할 수 있는 기능을 지원합니다.</p>
</li>
</ul>
<br>

<h4 id="2-spring-context">2. Spring Context</h4>
<ul>
<li>Spring Core 바로 위에 있으면서 Spring Core에서 지원하는 기능외에 추가적인 기능들과 좀 더 쉬운 개발이 가능하도록 지원합니다.</li>
</ul>
<ul>
<li>또한 JNDI, EJB등을 위한 Adaptor들을 포함합니다.</li>
</ul>
<br>

<h4 id="3-spring-dao">3. Spring DAO</h4>
<ul>
<li>지금까지 우리들이 일반적으로 많이 사용해왔던 JDBC 기반하의 DAO개발을 좀 더 쉽고, 일관된 방법으로 개발하는 것이 가능하도록 지원합니다.</li>
<li>Spring DAO를 이용할 경우 지금까지 개발하던 DAO보다 적은 코드와 쉬운 방법으로 DAO를 개발하는 것이 가능합니다.</li>
</ul>
<br>

<h4 id="4-spring-orm">4. Spring ORM</h4>
<ul>
<li><p>Object Relation Mapping 프레임워크인 Hibernate, IBatis, JDO와의 결합을 지원하기 위한 기능합니다.</p>
</li>
<li><p>Spring ORM을 이용할 경우 Hibernate, IBatis, JDO 프레임워크와 쉽게 통합하는 것이 가능합니다.</p>
</li>
</ul>
<br>

<h4 id="5-spring-aop">5. Spring AOP</h4>
<ul>
<li>Spring 프레임워크에 Aspect Oriented Programming을 지원하는 기능이다. 이 기능은 AOP Alliance 기반하에서 개발합니다.</li>
</ul>
<br>

<h4 id="6-spring-web">6. Spring Web</h4>
<ul>
<li><p>Web Application 개발에 필요한 Web Application Context와 Multipart Request등의 기능을 지원합니다.</p>
</li>
<li><p>BeanFactory를 기반으로 Bean 클래스들을 제어할 수 있는 기능을 지원</p>
</li>
</ul>
<br>

<h4 id="7-spring-web-mvc">7. Spring Web MVC</h4>
<ul>
<li><p>Spring 프레임워크에서 독립적으로 Web UI Layer에 Model-View-Controller를 지원하기 위한 기능합니다.</p>
</li>
<li><p>지금까지 Struts, Webwork가 담당했던 기능들을 Spring Web MVC를 이용하여 대체하는 것이 가능하며, 또한 Velocity, Excel, PDF와 같은 다양한 UI 기술들을 사용하기 위한 API를 제공합니다.</p>
</li>
</ul>
<p><br><br><br></p>
<p>[출처]
<a href="https://goddaehee.tistory.com/156">https://goddaehee.tistory.com/156</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[JSP] JSTL & EL의 개념과 사용 방법]]></title>
            <link>https://velog.io/@jojo_/JSP-JSTL-EL%EC%9D%98-%EA%B0%9C%EB%85%90%EA%B3%BC-%EC%82%AC%EC%9A%A9-%EB%B0%A9%EB%B2%95</link>
            <guid>https://velog.io/@jojo_/JSP-JSTL-EL%EC%9D%98-%EA%B0%9C%EB%85%90%EA%B3%BC-%EC%82%AC%EC%9A%A9-%EB%B0%A9%EB%B2%95</guid>
            <pubDate>Tue, 08 Aug 2023 02:39:39 GMT</pubDate>
            <description><![CDATA[<h2 id="💡-jstl">💡 JSTL</h2>
<br>

<p>JSTL은 JSP 표준라이브러리(JSP Standard Tag Library)의 약어이다. 자주 사용될 수 있는 커스텀 태그들을 모아서 표준으로 모아놓은 태그 라이브러리다.</p>
<br>

<h3 id="✔️-jstl의-종류">✔️ JSTL의 종류</h3>
<br>

<table>
<thead>
<tr>
<th align="center">라이브러리명</th>
<th align="center">접두어</th>
<th align="center">주요 기능</th>
<th align="center">URL</th>
</tr>
</thead>
<tbody><tr>
<td align="center">코어</td>
<td align="center">c</td>
<td align="center">변수 지원, 제어문, 페이지 관련 처리</td>
<td align="center"><a href="http://java.sun.com/jsp/jstl/core">http://java.sun.com/jsp/jstl/core</a></td>
</tr>
<tr>
<td align="center">함수</td>
<td align="center">fn</td>
<td align="center">collection 처리, String 처리</td>
<td align="center"><a href="http://java.sun.com/jsp/jstl/fuctions">http://java.sun.com/jsp/jstl/fuctions</a></td>
</tr>
<tr>
<td align="center">포매팅</td>
<td align="center">fmt</td>
<td align="center">포맷 처리, 국제화 지원</td>
<td align="center"><a href="http://java.sun.com/jsp/jstl/fmt">http://java.sun.com/jsp/jstl/fmt</a></td>
</tr>
<tr>
<td align="center">데이터베이스</td>
<td align="center">sql</td>
<td align="center">DB관련 CRUD 처리</td>
<td align="center"><a href="http://java.sun.com/jsp/jstl/sql">http://java.sun.com/jsp/jstl/sql</a></td>
</tr>
<tr>
<td align="center">XML</td>
<td align="center">x</td>
<td align="center">XML관련 처리</td>
<td align="center"><a href="http://java.sun.com/jsp/jstl/xml">http://java.sun.com/jsp/jstl/xml</a></td>
</tr>
</tbody></table>
<p><br><br></p>
<h3 id="✔️-jstl-사용-방법">✔️ JSTL 사용 방법</h3>
<p>JSTL은 라이브러리이기 때문에 사용하기전에 core를 header에 추가해주어야 한다.</p>
<br>

<p><strong>- header에 추가</strong></p>
<pre><code class="language-c">&lt;% @taglib uri=&quot;http://java.sun.com/jstl/core&quot; prefix=&quot;c&quot; %&gt;</code></pre>
<br>

<p><strong>- 사용법</strong></p>
<pre><code class="language-c">&lt;c:if test=&quot;&quot;&gt;&lt;/c:if&gt;
&lt;c:forEach items=&quot;&quot;&gt;&lt;/c:forEach&gt;</code></pre>
<br>


<h3 id="✔️-jstl-주요-core-태그">✔️ JSTL 주요 Core 태그</h3>
<h4 id="cset">&lt;c:set&gt;</h4>
<p>변수 선언 태그로, 변수를 다룰 때 사용한다.
이 태그로 생성한 변수는 JSP의 로컬 변수가 아니라 Servlet 보관소에 저장된다.
scope이 기본값은 page이기 때문에 생략하더라도 JSPContext에 저장된다.</p>
<pre><code class="language-c">&lt;c:set var=&quot;변수명&quot; value=&quot;값&quot; scope=&quot;page(기본값)|request|session|application&quot; /&gt;
&lt;c:set var=&quot;변수명&quot; scope=&quot;page(기본값)|request|session|application&quot;&gt;값&lt;/c:set&gt;</code></pre>
<br>

<h4 id="cremove">&lt;c:remove&gt;</h4>
<p>변수 제거 태그</p>
<pre><code class="language-c">&lt;c:remove var=&quot;변수명&quot; scope=&quot;page(기본값) | request | session | application&quot; /&gt;
</code></pre>
<br>

<p><strong>- ex</strong></p>
<pre><code class="language-c">&lt;% pageContext.setAttribute(&quot;fruit1&quot;, &quot;사과&quot;); %&gt;
과일1: ${fruit1}&lt;br&gt;

&lt;c:remove var=&quot;fruit1&quot; /&gt;
과일1: ${fruit1}&lt;br&gt;

// 과일 1 : 사과
// 과일 1 : 
</code></pre>
<br>

<h4 id="cout">&lt;c:out&gt;</h4>
<p>출력문을 만드는 태그.
value 값이 null이면 기본값이 출력되고 기본값이 없으면 빈 문자열이 출력된다.</p>
<pre><code class="language-c">&lt;c:out value=&quot;출력값&quot; default=&quot;기본값&quot; /&gt;
&lt;c:out value=&quot;출력값&quot;&gt;기본값&lt;/c:out&gt;
</code></pre>
<br>

<p><strong>- ex</strong></p>
<pre><code class="language-c">&lt;c:out value=&quot;${null}&quot; default=&quot;기본이지&quot; /&gt;
&lt;c:out value=&quot;출력값&quot;/&gt;
&lt;c:out value=&quot;${null}&quot;&gt;Hello!&lt;/c:out&gt;
&lt;c:out value=&quot;Hi!&quot;&gt;Hello!&lt;/c:out&gt;

// 기본이지
// Hello!
// Hi!
</code></pre>
<br>

<h4 id="cif">&lt;c:if&gt;</h4>
<p>test 안에 있는 내용이 true인지 false인지에 따라 내용의 출력 여부가 정해진다.</p>
<pre><code class="language-c">&lt;c:if test=&quot;true|false&quot; var=&quot;변수명&quot; scope=&quot;page(기본값) | request | session | application&quot;&gt;
&lt;/c:if&gt;</code></pre>
<br>

<h4 id="--ex">- ex</h4>
<pre><code class="language-c">&lt;c:if test=&quot;${1 &gt; 2}&quot; var=&quot;result1&quot;&gt;
    1은 2보다 크다.
&lt;/c:if&gt;
첫 번째 결과: ${result1}

&lt;c:if test=&quot;${2 &gt; 1}&quot; var=&quot;result2&quot;&gt;
    2는 1보다 크다.
&lt;/c:if&gt;
두 번째 결과: ${result2}

// 첫 번째 결과 : false
// 2는 1보다 크다.
// 두 번째 결과 : true</code></pre>
<br>

<h4 id="cforeach">&lt;c:forEach&gt;</h4>
<p>반복 기능을 사용할 수 있도록 해주는 태그이다.</p>
<p><strong>- ex</strong></p>
<pre><code class="language-c">(items 지정하여 반복 / 배열)

&lt;% pageContext.setAttribute(&quot;fruits&quot;, new String[]{&quot;사과&quot;, &quot;딸기&quot;, &quot;수박&quot;}); %&gt;

&lt;ul&gt;
    &lt;c:forTokens var=&quot;fruit&quot; items=&quot;${fruits}&quot;&gt;
        &lt;li&gt;${fruit}&lt;/li&gt;
    &lt;/c:forTokens&gt;
&lt;/ul&gt;

// 사과
// 딸기
// 수박</code></pre>
<pre><code class="language-c">(items 지정하여 반복 / 콤마로 연결된 문자)

&lt;% pageContext.setAttribute(&quot;fruits&quot;, &quot;사과, 딸기, 수박&quot;); %&gt;

&lt;ul&gt;
    &lt;c:forTokens var=&quot;fruit&quot; items=&quot;${fruits}&quot;&gt;
        &lt;li&gt;${fruit}&lt;/li&gt;
    &lt;/c:forTokens&gt;
&lt;/ul&gt;

// 사과
// 딸기
// 수박</code></pre>
<pre><code class="language-c">&lt;ul&gt;
    &lt;c:forTokens var=&quot;count&quot; begin=&quot;1&quot; end=&quot;5&quot;&gt;
        &lt;li&gt;${count}&lt;/li&gt;
    &lt;/c:forTokens&gt;
&lt;/ul&gt;

// 1
// 2
// 3
// 4
// 5</code></pre>
<p><br><br></p>
<h2 id="💡-el">💡 EL</h2>
<br>

<h3 id="✔️-el이란">✔️ EL이란?</h3>
<p>EL 이란 데이터를 표현하기 위한 언어입니다.</p>
<p>즉, 다양한 위치에 있는 데이터에 접근하기 위한 언어로 JSP의 기본 문법을 보완하는 역할을 합니다.</p>
<p>JSP에서 자바 코드를 대신하여 다른 표현식을 사용함으로서 간단한 방법으로 값을 코딩을 할 수 있게 해줍니다.</p>
<br>

<h3 id="✔️-el의-사용-방법">✔️ EL의 사용 방법</h3>
<p>EL을 사용하기 위해서는 아래와 같이 $ 기호 뒤에 중괄호 { }를 붙이고 그 안에 표현식을 넣으면 됩니다.</p>
<pre><code class="language-c">${&#39;EL입니다&#39;} =&gt; &quot;EL입니다&quot; 출력

${ 5*2 } =&gt; 10 출력</code></pre>
<br>

<h3 id="✔️-el의-내장-객체">✔️ EL의 내장 객체</h3>
<br>


<table>
<thead>
<tr>
<th align="center">객체명</th>
<th align="center">설명</th>
</tr>
</thead>
<tbody><tr>
<td align="center">${pageScope}</td>
<td align="center">page Scope에 접근하기 위한 객체</td>
</tr>
<tr>
<td align="center">${reqeustScope}</td>
<td align="center">request Scope에 접근하기 위한 객체</td>
</tr>
<tr>
<td align="center">${sessionScope}</td>
<td align="center">session Scope에 접근하기 위한 객체</td>
</tr>
<tr>
<td align="center">${applicationScope}</td>
<td align="center">application Scope에 접근하기 위한 객체</td>
</tr>
<tr>
<td align="center">${param}</td>
<td align="center">파라미터 값을 가져오기 위한 객체</td>
</tr>
<tr>
<td align="center">${header}</td>
<td align="center">헤더 값을 가져오기 위한 객체</td>
</tr>
<tr>
<td align="center">${cookie}</td>
<td align="center">쿠키 값을 가져오기 위한 객체</td>
</tr>
<tr>
<td align="center">${initParam}</td>
<td align="center">JSP 초기 파라미터를 가져오기 위한 객체</td>
</tr>
</tbody></table>
<br>

<h3 id="✔️-el에서-사용-가능한-연산자">✔️ EL에서 사용 가능한 연산자</h3>
<p>일부 연산자는 영어 알파벳으로 된 연산자를 추가적으로 지원하는데, 이는 HTML 태그나 JSP 내 자바코드들을 쓸 때 사용하는 %, &lt;&gt; 등의 기호와 구분하기 위해 씁니다.</p>
<p><img src="https://velog.velcdn.com/images/jojo_/post/766e5257-1d59-4a32-8cf0-38a2ad2c8717/image.png" alt=""></p>
<p><br><br></p>
<p>[출처]
<a href="https://sjh836.tistory.com/136">https://sjh836.tistory.com/136</a>
<a href="https://velog.io/@nemo/JSTL">https://velog.io/@nemo/JSTL</a>
<a href="https://daesuni.github.io/jstl/">https://daesuni.github.io/jstl/</a>
<a href="https://sjh836.tistory.com/136">https://sjh836.tistory.com/136</a>
<a href="https://sgcomputer.tistory.com/243">https://sgcomputer.tistory.com/243</a></p>
]]></description>
        </item>
        <item>
            <title><![CDATA[[SQL] Oracle(오라클) 조회 순번 매기는 방법 (feat. ROWNUM, ROW_NUMBER() )
]]></title>
            <link>https://velog.io/@jojo_/SQL-Oracle%EC%98%A4%EB%9D%BC%ED%81%B4-%EC%A1%B0%ED%9A%8C-%EC%88%9C%EB%B2%88-%EB%A7%A4%EA%B8%B0%EB%8A%94-%EB%B0%A9%EB%B2%95-feat.-ROWNUM-ROWNUMBER</link>
            <guid>https://velog.io/@jojo_/SQL-Oracle%EC%98%A4%EB%9D%BC%ED%81%B4-%EC%A1%B0%ED%9A%8C-%EC%88%9C%EB%B2%88-%EB%A7%A4%EA%B8%B0%EB%8A%94-%EB%B0%A9%EB%B2%95-feat.-ROWNUM-ROWNUMBER</guid>
            <pubDate>Wed, 02 Aug 2023 09:27:07 GMT</pubDate>
            <description><![CDATA[<h2 id="💡-rownum-키워드-이용하는-방법">💡 ROWNUM 키워드 이용하는 방법</h2>
<br>

<ul>
<li>조회된 순서대로 순번을 매깁니다.</li>
</ul>
<pre><code class="language-c">SELECT ROWNUM
        , a.*
    FROM EMP A</code></pre>
<br>

<ul>
<li>ORDER BY를 사용하면 순번이 뒤섞이므로 정렬된 서브쿼리 결과에 ROWNUM 을 매겨야 합니다.</li>
</ul>
<pre><code class="language-c">SELECT ROWNUM
        , x.*
    FROM ( SELECT a.* FROM EMP A ORDER BY A.ENAME) x</code></pre>
<p><br><br></p>
<h2 id="💡-rownum-키워드-이용하는-방법-1">💡 ROWNUM 키워드 이용하는 방법</h2>
<br>

<ul>
<li>ORDER BY 된 결과에 순번을 매길때에는 ROWNUM 보다 ROW_NUMBER() 함수가 더 편합니다.</li>
</ul>
<pre><code class="language-c">SELECT ROW_NUMBER() OVER(ORDER BY A.JOB, A.ENAME) ROW_NUM
        , a.*
    FROM EMP A ORDER BY A.JOB, A.ENAEM</code></pre>
<br>

<ul>
<li>그룹별(PARTITION)로 순번을 따로 부여할 수 있습니다.</li>
</ul>
<pre><code class="language-c">SELECT ROW_NUMBER() OVER(PARTITION BY A.JOB, ORDER BY A.JOB, A.ENAME) ROW_NUM
        , a.*
    FROM EMP A ORDER BY A.JOB, A.ENAEM</code></pre>
<br>

<hr>
<br>

<h3 id="✅-rownum-예제">✅ ROWNUM 예제</h3>
<br>

<p>** 예제 1.**</p>
<pre><code class="language-c">SELECT ROWNUM
        , a.*
    FROM EMP A</code></pre>
<p><img src="https://velog.velcdn.com/images/jojo_/post/8ece2cd1-b2ef-4dba-b077-653eef94ea65/image.png" alt=""></p>
<br>

<p>** 예제 2.**</p>
<pre><code class="language-c">SELECT ROWNUM
        , x.*
    FROM ( SELECT a.* FROM EMP A ORDER BY A.ENAME) x</code></pre>
<p><img src="https://velog.velcdn.com/images/jojo_/post/3c127d56-e512-43d9-b6f1-116104d73c4d/image.png" alt=""></p>
<p><br><br></p>
<h3 id="✅-rownum-예제-1">✅ ROWNUM 예제</h3>
<br>

<p>** 예제 1.**</p>
<pre><code class="language-c">SELECT ROW_NUMBER() OVER(ORDER BY A.JOB, A.ENAME) ROW_NUM
        , a.*
    FROM EMP A ORDER BY A.JOB, A.ENAEM</code></pre>
<p><img src="https://velog.velcdn.com/images/jojo_/post/54586adf-7293-4f3c-a919-348d91f41185/image.png" alt=""></p>
<br>

<p>** 예제 1.**</p>
<pre><code class="language-c">SELECT ROW_NUMBER() OVER(PARTITION BY A.JOB, ORDER BY A.JOB, A.ENAME) ROW_NUM
        , a.*
    FROM EMP A ORDER BY A.JOB, A.ENAEM</code></pre>
<p><img src="https://velog.velcdn.com/images/jojo_/post/be2749fc-afb8-43c5-97bc-be9cdc4b4f32/image.png" alt=""></p>
]]></description>
        </item>
    </channel>
</rss>