\ Something New :: Something New
728x90
반응형

ORM(Object-Relational Mapping)은 객체와 데이터베이스 간의 관계를 매핑하여, 데이터베이스 작업을 객체 지향적인 방식으로 다룰 수 있게 해주는 기술입니다. JPA와 같은 ORM 프레임워크는 SQL을 자동으로 생성하고, 직접 SQL을 작성하지 않아도 데이터를 쉽게 저장, 조회, 업데이트, 삭제할 수 있게 해줍니다. 이를 MyBatis와 비교하여 설명하겠습니다.

1. ORM의 SQL 자동 생성 예시 (JPA)

JPA와 같은 ORM 프레임워크는 엔티티 클래스와 데이터베이스 테이블 간의 매핑을 설정하고, 이를 통해 SQL을 자동으로 생성합니다. 예를 들어, User라는 엔티티가 있다고 가정해보겠습니다.

예시: JPA를 사용한 코드

 
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity  // 이 클래스는 데이터베이스 테이블과 매핑됨
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;
    private String email;

    // Getters and Setters
}

JPA를 사용한 데이터 저장, 조회 코드

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.transaction.Transactional;

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    @Transactional
    public void saveUser(String name, String email) {
        User user = new User();
        user.setName(name);
        user.setEmail(email);
        userRepository.save(user);  // SQL 없이 저장 가능
    }

    public User findUser(Long id) {
        return userRepository.findById(id).orElse(null);  // SQL 없이 조회 가능
    }
}

JPA에서 자동 생성되는 SQL

JPA는 userRepository.save(user)를 호출하면 내부적으로 다음과 같은 INSERT SQL을 자동으로 생성하여 실행합니다:

INSERT INTO User (name, email) VALUES ('Alice', 'alice@example.com');

userRepository.findById(id)를 호출할 경우, 다음과 같은 SELECT SQL을 자동으로 생성하여 실행합니다:

SELECT * FROM User WHERE id = 1;

이처럼 JPA에서는 엔티티 객체와 매핑 정보만 설정해주면 데이터베이스와의 통신을 위한 SQL을 자동으로 생성해주므로, 개발자는 SQL을 직접 작성할 필요가 줄어듭니다.

2. MyBatis의 SQL 작성 방식

MyBatis는 ORM과 달리 SQL을 자동으로 생성하지 않으며, SQL을 XML이나 어노테이션을 통해 수동으로 작성해야 합니다. 그러나 SQL을 커스터마이징하기 쉽고, 데이터베이스 스키마에 의존적인 작업에 적합합니다.

예시: MyBatis를 사용한 SQL 매핑

먼저, User 클래스와 매핑되는 SQL 쿼리를 XML 파일에 작성합니다.

<!-- UserMapper.xml -->
<mapper namespace="com.example.UserMapper">

    <insert id="saveUser">
        INSERT INTO User (name, email) VALUES (#{name}, #{email})
    </insert>

    <select id="findUser" parameterType="Long" resultType="User">
        SELECT * FROM User WHERE id = #{id}
    </select>

</mapper>
 

MyBatis를 사용한 데이터 저장, 조회 코드

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserService {

    @Autowired
    private UserMapper userMapper;

    public void saveUser(String name, String email) {
        userMapper.saveUser(name, email);  // SQL을 직접 작성
    }

    public User findUser(Long id) {
        return userMapper.findUser(id);  // SQL을 직접 작성
    }
}

설명

  • MyBatis는 UserMapper.xml 파일에 SQL을 직접 작성하여 사용합니다. #{} 구문을 사용해 파라미터를 바인딩하며, SQL이 고정적이기 때문에, 복잡한 쿼리에서도 제어하기가 용이합니다.
  • saveUser와 findUser 메서드를 호출할 때 수동으로 작성한 SQL을 실행합니다. 따라서 SQL 최적화를 세밀하게 할 수 있지만, SQL 작성에 많은 노력이 필요할 수 있습니다.

3. ORM (JPA)와 MyBatis 비교 요약

특성JPA (ORM)MyBatis

SQL 작성 여부 SQL 자동 생성 SQL을 직접 작성
객체 매핑 방식 엔티티 클래스와 테이블 간 매핑 설정 XML 또는 어노테이션으로 SQL 매핑
개발 속도 간단한 CRUD의 경우 빠름 SQL 작성에 시간이 걸릴 수 있음
유연성 복잡한 쿼리 작성에 불리 복잡한 SQL 작성에 유리
성능 최적화 기본 설정으로도 사용 가능, 필요시 커스터마이징 가능 쿼리 튜닝이 자유로움
  • JPA는 간단한 CRUD 작업에서 SQL을 자동으로 생성해 주기 때문에, 데이터베이스와의 통신 작업을 단순화할 수 있습니다. 하지만 복잡한 쿼리나 데이터베이스에 의존적인 작업에서는 불편할 수 있습니다.
  • MyBatis는 SQL 작성이 필수이므로 데이터베이스와의 세부적인 커스터마이징과 튜닝이 가능하며, 데이터베이스 종속적 작업에 더 적합합니다.

결론

JPA는 SQL 자동 생성을 통해 빠른 개발을 도와주며, 객체와 관계형 데이터베이스 간의 매핑을 간소화하는 데 유리합니다. 반면, MyBatis는 SQL을 수동 작성하여 보다 세밀하게 데이터베이스 작업을 제어할 수 있는 유연성을 제공합니다.

728x90

'JAVA Spring FRAMEWORK' 카테고리의 다른 글

[JAVA]RESTful API 서버란  (6) 2024.11.13
[JAVA]JDBC란?  (0) 2024.11.13
[SQL]Inner Join vs Outer Join  (1) 2024.08.31
디자인 패턴이란?  (0) 2024.06.24
[Spring Boot ] Spring Initializr 로 시작하기  (0) 2023.03.14
728x90
반응형



1. RESTful API 서버

  • 스프링이 단순히 백엔드 API만 제공하고, 프론트엔드는 React, Vue, Angular와 같은 클라이언트 사이드 프레임워크/라이브러리로 처리하는 경우입니다. 이 경우, 템플릿 엔진은 사용되지 않습니다.
  • 서버는 JSON 형식의 데이터를 클라이언트에 반환하고, 클라이언트에서는 이 데이터를 받아 화면을 렌더링합니다.
  • Controller에서 @ResponseBody나 @RestController를 사용하여 데이터를 반환합니다.

예시:

@RestController
public class MyController {
    @GetMapping("/api/message")
    public String getMessage() {
        return "Hello from API!";
    }
}
 
 

2. 클라이언트 사이드 렌더링(CSR)

  • 클라이언트 측에서 React, Vue, Angular 등과 같은 프레임워크를 사용해 렌더링을 처리하는 경우입니다. 서버는 주로 API만 제공하고, HTML, CSS, JavaScript 파일을 클라이언트에게 전달합니다.
  • 이러한 방식에서는 서버가 템플릿을 렌더링하는 대신, 클라이언트에서 모든 렌더링을 맡고, 서버는 필요한 데이터를 API 형식으로 제공합니다.

3. 스프링 부트에서 템플릿 엔진 없이 사용할 수 있는 경우

  • 스프링 부트에서 템플릿 엔진 없이 서버를 구성하려면, spring-boot-starter-web만 포함하고, 뷰 템플릿 관련 의존성을 추가하지 않으면 됩니다.
  • 클라이언트에서 HTML 파일을 직접 처리하거나, API 응답으로만 데이터를 제공할 때 템플릿 엔진을 사용할 필요가 없습니다.

4. Static HTML 파일을 사용하는 경우

  • 서버에서 동적으로 렌더링하는 대신, 정적 HTML 파일을 직접 클라이언트에게 제공할 수 있습니다. 이때는 서버가 HTML 파일을 렌더링하지 않고, 미리 준비된 HTML 파일을 클라이언트에 그대로 전달합니다.
  • 예를 들어, src/main/resources/static/ 폴더에 정적 파일을 두고, 해당 파일들을 클라이언트에 제공하는 방식입니다.
 
@Controller
public class MyController {
    @GetMapping("/home")
    public String home() {
        return "redirect:/index.html";  // static/index.html을 반환
    }
}

결론:

템플릿 엔진을 사용하지 않는 경우, 서버는 주로 API를 제공하고, 프론트엔드에서 클라이언트 사이드 렌더링을 처리합니다. 또는 정적 파일을 직접 제공하는 방식으로 동작합니다. 이런 방식은 보통 RESTful API 서버나 SPA (Single Page Application) 구조에서 많이 사용됩니다.

SSR (Server-Side Rendering) vs CSR (Client-Side Rendering): 차이점과 특징

웹 개발에서 페이지 렌더링 방식은 두 가지 주요 방법인 SSR(서버 사이드 렌더링)과 CSR(클라이언트 사이드 렌더링)으로 나눌 수 있습니다. 이 두 가지 방식은 페이지가 어떻게 렌더링되는지에 따라 성능, SEO(검색 엔진 최적화), 사용자 경험 등에 큰 차이를 만들어냅니다. 이번 블로그에서는 SSR과 CSR의 차이점과 각각의 장단점, 그리고 어떤 경우에 각각을 사용하는지에 대해 자세히 알아보겠습니다.


SSR (Server-Side Rendering)

SSR은 서버에서 HTML을 렌더링하여 클라이언트(브라우저)로 전달하는 방식입니다. 이 방식에서는 서버가 클라이언트의 요청에 맞는 HTML 파일을 생성한 후, 클라이언트에 전달하여 페이지를 완성하는 방식입니다.

SSR의 특징

  1. 서버에서 렌더링: 클라이언트가 요청하면 서버에서 HTML을 렌더링하여 완성된 페이지를 클라이언트에 전송합니다.
  2. 빠른 첫 화면 로딩: 페이지가 서버에서 렌더링되어 클라이언트로 전달되므로, 클라이언트는 HTML을 빠르게 받을 수 있습니다. 결과적으로 첫 번째 페이지 로딩이 빠르게 이루어집니다.
  3. SEO에 유리: 검색 엔진 크롤러는 서버에서 생성된 HTML을 바로 인식할 수 있기 때문에, 검색 엔진 최적화(SEO)에서 유리한 점이 있습니다.
  4. 서버 부하 증가: 서버에서 매 요청마다 HTML을 렌더링해야 하므로, 서버 부하가 증가할 수 있습니다. 특히 트래픽이 많은 사이트에서는 서버 성능이 중요한 요소가 됩니다.

SSR의 장점

  • SEO 최적화: 서버에서 HTML이 완성되어 클라이언트에 전달되므로, 검색 엔진 크롤러가 페이지 내용을 쉽게 인식할 수 있어 SEO에 유리합니다.
  • 빠른 첫 페이지 로딩: 페이지가 서버에서 렌더링되므로, 사용자는 첫 화면을 빠르게 볼 수 있습니다.

SSR의 단점

  • 서버 부하: 매 요청마다 서버가 페이지를 렌더링해야 하므로, 서버에 많은 부하를 주게 됩니다.
  • 느린 상호작용: 페이지가 렌더링된 후의 상호작용은 클라이언트에서 처리되기 때문에, 전체적인 인터랙티브 성능은 CSR보다는 떨어질 수 있습니다.

SSR의 예시

  • Next.js: React 기반의 SSR 프레임워크로, 페이지를 서버에서 렌더링하고 클라이언트로 전달합니다.
  • Nuxt.js: Vue.js 기반의 SSR 프레임워크입니다.
  • JSP, Thymeleaf: 전통적인 서버 사이드 렌더링 방식에서 사용하는 템플릿 엔진입니다.

CSR (Client-Side Rendering)

CSR은 클라이언트 측에서 자바스크립트를 실행하여 HTML을 동적으로 렌더링하는 방식입니다. 첫 번째로 서버에서 빈 HTML 파일을 전송하고, 클라이언트에서 자바스크립트가 실행되어 동적으로 페이지를 완성합니다.

CSR의 특징

  1. 클라이언트에서 렌더링: 첫 페이지 로딩 시 빈 HTML과 함께 자바스크립트 파일을 전송하고, 클라이언트에서 자바스크립트가 HTML을 동적으로 렌더링합니다.
  2. 빠른 페이지 전환: 초기 로딩 후, 페이지 간 전환이 서버 요청 없이 클라이언트에서 이루어지기 때문에 페이지 전환이 빠르고 부드럽습니다.
  3. SEO에 불리할 수 있음: 클라이언트에서 자바스크립트를 실행하여 렌더링하기 때문에, 검색 엔진 크롤러가 자바스크립트로 렌더링된 내용을 인식하기 어렵습니다. 이에 따라 SEO에 불리할 수 있습니다.
  4. 초기 로딩 속도 느림: 서버에서 자바스크립트 파일을 다운로드한 후 실행해야 하므로, 초기 로딩 속도가 상대적으로 느릴 수 있습니다.

CSR의 장점

  • 빠른 페이지 전환: 페이지가 클라이언트에서 렌더링되므로, 페이지 간 전환이 빠르고, 사용자 경험이 향상됩니다.
  • 서버 부하 감소: 서버는 데이터만 제공하고, 페이지 렌더링은 클라이언트에서 처리하므로 서버의 부하가 적습니다.

CSR의 단점

  • SEO 최적화 문제: 검색 엔진 크롤러가 자바스크립트로 렌더링된 페이지를 제대로 인식하지 못할 수 있습니다. 이를 해결하려면 서버 측에서 prerendering이나 SSR을 사용해야 합니다.
  • 초기 로딩 속도: 자바스크립트와 관련된 파일을 처음에 모두 로드해야 하므로, 초기 페이지 로딩이 상대적으로 느릴 수 있습니다.

CSR의 예시

  • React: 리액트는 CSR 기반으로 동작하며, React Router를 사용하여 클라이언트 측에서 페이지 이동을 처리합니다.
  • Vue.js, Angular: CSR을 지원하는 다른 프레임워크들입니다.
  • Single Page Application (SPA): 모든 페이지는 하나의 HTML 페이지에서 동적으로 로드됩니다.

SSR vs CSR: 무엇이 다른가?

1. 렌더링 위치

  • SSR: 서버에서 HTML을 렌더링하여 클라이언트로 전달.
  • CSR: 클라이언트에서 자바스크립트 실행을 통해 HTML을 동적으로 렌더링.

2. 초기 페이지 로딩

  • SSR: 서버에서 렌더링된 페이지가 빠르게 로드됨.
  • CSR: 클라이언트에서 자바스크립트를 다운로드하고 실행한 후 페이지가 로드되므로 초기 로딩 속도가 느릴 수 있음.

3. SEO

  • SSR: 서버에서 렌더링된 HTML이 검색 엔진에 최적화되어 SEO에 유리.
  • CSR: 클라이언트에서 렌더링하므로 SEO 최적화에 불리함.

4. 서버 부하

  • SSR: 요청마다 서버에서 페이지를 렌더링해야 하므로 서버 부하가 크다.
  • CSR: 서버는 API만 제공하고, 클라이언트에서 렌더링을 처리하므로 서버 부하가 적다.

5. 사용자 경험

  • SSR: 첫 화면 로딩은 빠르지만, 페이지 간 전환이 느릴 수 있음.
  • CSR: 첫 화면 로딩은 느릴 수 있지만, 페이지 전환이 매우 빠르고 부드럽다.

어떤 경우에 SSR 또는 CSR을 사용해야 할까?

  • SEO가 중요한 사이트: 검색 엔진 최적화가 중요한 블로그, 뉴스 사이트, 쇼핑몰 등에서는 SSR을 사용하는 것이 좋습니다. SEO가 잘 지원되므로 검색 엔진에 페이지가 잘 인덱싱됩니다.
  • 빠른 페이지 전환이 중요한 사이트: 사용자 경험을 중시하는 서비스(예: 소셜 네트워크 서비스, 대시보드 등)에서는 CSR을 사용하여 빠른 페이지 전환과 부드러운 사용자 경험을 제공하는 것이 좋습니다.
  • 복합적인 요구사항: SSRCSR을 혼합한 하이브리드 방식도 가능합니다. 예를 들어, Next.js(React 기반)와 같은 프레임워크는 SSR과 CSR을 함께 사용할 수 있어, SEO와 사용자 경험을 모두 최적화할 수 있습니다.

결론

SSR과 CSR은 각각 장단점이 있으며, 어떤 방식을 선택할지는 웹 애플리케이션의 목적과 요구 사항에 따라 다릅니다. SEO와 빠른 첫 페이지 로딩을 중요시하는 경우 SSR을, 빠른 페이지 전환과 클라이언트 측에서의 동적 렌더링을 중요시하는 경우 CSR을 선택하면 좋습니다. 또한, 두 가지 방식을 결합한 하이브리드 방식도 최근에는 많이 사용되고 있습니다.
 

SEO란

SEO(Search Engine Optimization)는 검색 엔진 최적화로, 웹사이트가 검색 엔진 결과에서 상위에 표시되도록 콘텐츠와 구조를 조정하는 작업입니다. SEO는 검색 엔진에서 사이트가 잘 노출될 수 있게 하는 기술로, 사용자 유입에 중요한 요소입니다. SSR이 SEO에 유리한 이유는 서버에서 완성된 HTML을 제공하기 때문에 검색 엔진이 콘텐츠를 쉽게 크롤링할 수 있기 때문입니다. CSR은 JavaScript로 콘텐츠를 동적으로 생성하기 때문에 검색 엔진이 콘텐츠를 인식하는 데 제한이 있을 수 있지만, Google과 같은 최신 검색 엔진은 CSR 페이지도 어느 정도 크롤링할 수 있습니다.

 

SSR과 RESTful API의 차이

SSR(Server-Side Rendering)과 RESTful API는 개념과 역할이 다릅니다.

  • SSR은 서버에서 HTML을 만들어 클라이언트에 전달하는 렌더링 방식입니다. 사용자가 페이지에 접근할 때마다 서버에서 새로 HTML을 생성해 제공하는 것이 기본이므로, 렌더링 중심입니다.
  • RESTful API는 서버와 클라이언트 간 데이터 통신 방식을 정의한 아키텍처입니다. SSR처럼 HTML을 생성해주는 것이 아니라, JSON과 같은 형식의 데이터만 반환하여 클라이언트가 필요한 데이터를 받아 사용할 수 있게 합니다. RESTful API는 주로 **CSR(Client-Side Rendering)**과 함께 사용되며, CSR에서는 서버로부터 데이터만 받아 클라이언트에서 렌더링하는 방식입니다.

SSR과 RESTful API의 관계

SSR도 RESTful API와 같이 데이터를 받아와 렌더링할 수 있습니다. 즉, SSR에서도 필요에 따라 RESTful API를 호출해 데이터만 받아와 페이지를 생성한 후, 클라이언트에 완성된 HTML로 반환하는 방식이 가능합니다.




 

728x90

'JAVA Spring FRAMEWORK' 카테고리의 다른 글

[JAVA]ORM이란? JPA vs Mybatis 뭐가 다를까?  (1) 2024.11.18
[JAVA]JDBC란?  (0) 2024.11.13
[SQL]Inner Join vs Outer Join  (1) 2024.08.31
디자인 패턴이란?  (0) 2024.06.24
[Spring Boot ] Spring Initializr 로 시작하기  (0) 2023.03.14
728x90
반응형

*JDBC (Java Database Connectivity)**는 자바에서 데이터베이스와 연결하여 SQL 쿼리를 실행하고 데이터를 처리하는 기본적인 API입니다. JDBC데이터베이스와의 연결을 위한 표준 인터페이스를 제공하지만, 데이터베이스 작업을 더 쉽게 하려면 JDBC 기반의 라이브러리나 프레임워크를 사용하게 됩니다.

MyBatis 외에도 JDBC를 사용할 수 있는 여러 가지 프레임워크와 라이브러리가 존재합니다. 여기 몇 가지 대표적인 JDBC 관련 라이브러리를 소개합니다:

1. JPA (Java Persistence API)

  • JPAORM(Object-Relational Mapping) 표준 API로, 자바 객체와 관계형 데이터베이스 간의 매핑을 제공합니다. JPAJDBC를 기반으로 하고 있지만, SQL 쿼리를 자동으로 생성하거나 자바 객체와 데이터베이스의 테이블 간의 매핑을 자동으로 처리해줍니다.
  • JPAHibernateEclipseLink와 같은 구현체들이 존재합니다.

JPA의 특징:

  • 객체지향적: 데이터베이스와 자바 객체 간의 매핑을 자동으로 처리하여 SQL을 작성할 필요가 없습니다.
  • 표준화된 인터페이스: JPA는 표준화된 API를 제공하므로, 구현체를 바꾸는 것에 대한 유연성이 있습니다.

사용 예시:

 
@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    
    // getters and setters
}

2. Spring JDBC Template

  • Spring JDBC TemplateSpring Framework에서 제공하는 JDBC를 사용하기 위한 라이브러리로, JDBC 코드의 반복적인 부분을 간소화하고 예외 처리자원 관리를 자동으로 처리합니다.
  • JdbcTemplate을 사용하면 JDBC 코드의 복잡성을 줄이고, SQL 실행 및 결과 처리를 간단하게 할 수 있습니다.

Spring JDBC Template의 특징:

  • 간소화된 JDBC 코드: JdbcTemplate이 SQL 실행 및 리소스 관리(연결, 닫기 등)를 자동으로 처리해줍니다.
  • 예외 처리: SQL 예외를 Spring의 DataAccessException으로 변환하여 일관된 방식으로 예외를 처리할 수 있습니다.

사용 예시:

 
@Autowired
private JdbcTemplate jdbcTemplate;

public User getUserById(Long id) {
    String sql = "SELECT * FROM users WHERE id = ?";
    return jdbcTemplate.queryForObject(sql, new Object[]{id}, new BeanPropertyRowMapper<>(User.class));
}

3. Hibernate

  • HibernateJPA의 구현체이자, 객체-관계 매핑(ORM) 프레임워크입니다. JPA와 유사하게 데이터베이스와 자바 객체 간의 매핑을 자동으로 처리하고, SQL을 자동으로 생성하여 데이터베이스와 상호작용합니다.
  • HibernateJDBC를 직접 사용하여 SQL을 실행하지만, SQL을 개발자가 직접 작성할 필요 없이 자동화된 방식으로 처리합니다.

Hibernate의 특징:

  • 자동 매핑: 데이터베이스의 테이블과 자바 객체 간의 자동 매핑
  • SQL 생성: SQL을 자동으로 생성해주므로 개발자는 대부분의 작업을 객체 지향적으로 처리할 수 있습니다.
  • 쿼리 언어(HQL): **Hibernate Query Language (HQL)**을 사용하여 데이터베이스를 조회할 수 있습니다.

사용 예시:

 
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
User user = session.get(User.class, 1);
tx.commit();
session.close();

4. JDBC의 기본 활용 (직접 사용)

  • JDBC는 기본적으로 SQL 연결, 실행, 결과 처리를 위한 API로, 데이터를 처리할 때 자바 코드로 직접 SQL 쿼리를 작성하고 실행합니다.
  • JDBC를 직접 사용하는 경우, Connection, Statement, ResultSet 객체를 사용하여 SQL 쿼리 실행 및 결과 반환을 수동으로 처리합니다.

JDBC의 기본 예시:

public User getUserById(Long id) {
    String sql = "SELECT * FROM users WHERE id = ?";
    try (Connection connection = DriverManager.getConnection(DB_URL, USER, PASS);
         PreparedStatement ps = connection.prepareStatement(sql)) {
        ps.setLong(1, id);
        try (ResultSet rs = ps.executeQuery()) {
            if (rs.next()) {
                return new User(rs.getLong("id"), rs.getString("name"));
            }
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }
    return null;
}
 

5. Spring Data JPA

  • Spring Data JPASpring Framework에서 JPA를 더욱 쉽게 사용할 수 있도록 도와주는 라이브러리입니다. 기본적인 CRUD 작업을 자동으로 처리할 수 있도록 해주며, JpaRepository를 사용하여 간단하게 데이터베이스 연동을 처리할 수 있습니다.

Spring Data JPA의 특징:

  • 간단한 설정: 기본적인 CRUD 메소드가 자동으로 생성됩니다.
  • JPA 기반: JPA를 쉽게 사용할 수 있도록 지원하며, Hibernate를 JPA 구현체로 사용합니다.

사용 예시:

public interface UserRepository extends JpaRepository<User, Long> {
    User findByName(String name);
}

6. jOOQ (Java Object Oriented Querying)

  • jOOQSQL을 객체 지향적으로 작성할 수 있게 해주는 라이브러리입니다. SQL 쿼리를 자바 코드로 작성하고, 데이터베이스와 상호작용할 수 있는 타입 안전성을 제공합니다. JPA와는 다르게 자유로운 SQL 작성을 지원합니다.
  • jOOQSQL을 직접 작성하면서도 타입 안전성을 제공하는 특성이 있습니다.

jOOQ의 특징:

  • SQL에 대한 자유로운 접근: SQL을 직접 작성하면서도 자바 코드에서 타입 안전성을 제공.
  • 타입 안전: SQL을 자바 코드로 작성해도 컴파일 시점에 오류를 잡을 수 있습니다.

사용 예시:

public interface UserRepository extends JpaRepository<User, Long> {
    User findByName(String name);
}

결론

  • MyBatis 외에도 JPA, Spring JDBC Template, Hibernate, Spring Data JPA, jOOQ 등 다양한 JDBC 기반의 라이브러리 및 프레임워크들이 존재합니다. 이들은 SQL 처리, ORM을 포함한 여러 기능을 제공하며, JDBC의 복잡성을 줄이고 편리한 데이터베이스 연동을 가능하게 합니다.
  • JDBC를 사용할 때는 라이브러리나 프레임워크를 선택하는 것이 중요한데, 복잡한 쿼리가 필요하면 MyBatisjOOQ를, 간단한 CRUD 작업Spring JDBC Template이나 Spring Data JPA를 사용하는 것이 적합할 수 있습니다.

 

 

 

728x90
728x90
반응형

1. 자주 쓰이는 SQL 함수

  • 집계 함수
    • COUNT(): 행 개수 계산. COUNT(*), COUNT(column)
    • SUM(): 합계 계산
    • AVG(): 평균 계산
    • MIN(), MAX(): 최소값 및 최대값 찾기
  • 문자열 함수
    • CONCAT(): 문자열 결합
    • SUBSTRING(): 문자열 추출
    • LENGTH(): 문자열 길이
    • UPPER(), LOWER(): 대소문자 변환
  • 날짜 함수
    • NOW(): 현재 날짜와 시간
    • DATE(): 날짜만 추출
    • YEAR(), MONTH(), DAY(): 년, 월, 일 추출
    • DATEDIFF(): 두 날짜 간의 차이 계산
  • 조건 함수
    • CASE WHEN THEN ELSE END: 조건에 따라 값을 반환
    • COALESCE(): NULL 처리 (대체값 반환)
  • row_number() over (...)
    • row_number()는 SQL 윈도우 함수로, 결과 집합의 각 행에 대해 일련번호를 부여합니다. over 절을 통해 어떤 기준으로 일련번호를 매길지 정할 수 있습니다. 예를 들어, over (ORDER BY column_name)처럼 특정 열을 기준으로 정렬하면서 순번을 부여할 수 있습니다.
    • 페이징 처리나 특정 순번을 기준으로 데이터 필터링이 필요할 때 유용하게 쓰입니다.

2. SQL 작성 요령

  • 명확하고 직관적인 쿼리 작성
    • 컬럼명, 테이블명 등은 의미를 알 수 있도록 작성하세요. 별칭(AS)을 활용해 가독성을 높이세요.
  • 필요한 컬럼만 선택
    • SELECT *는 가급적 피하고 필요한 컬럼만 지정해 성능을 높이세요.
  • 조건절에 인덱스 컬럼 사용
    • WHERE 절에서 인덱스가 설정된 컬럼을 조건으로 걸어 쿼리 성능을 향상시키세요.
  • JOIN 최적화
    • 테이블 간 JOIN 시, 결합 기준이 되는 키들이 인덱싱되었는지 확인하세요.
  • 복잡한 쿼리는 서브쿼리 또는 뷰로 분리
    • 복잡한 쿼리는 서브쿼리나 뷰로 나눠서 작성하여 가독성을 높이세요.
728x90
728x90
반응형

 

11월 첫째 주 주말~ 

가을 하늘은 완벽했고

난 혼자서 홍대까지 공연을 보러 나갔다

내년에 딸기탕후루가 돌아올 때까지 왕가탕후루가 망하지 않길 기다리며 탕후루를 사 먹었다

(샤인머스켓이 젤 맛있었음)

 

홍대에서 베이글집에 갔는데 뉴욕베이글 어쩌고,, 맛은 쏘쏘 했다

 

 

한국에 온 지 얼마 안 되었지만 되게 좋은 분의 친구가 생겼는데

그분이 밴드에서 베이스를 하신다는 얘기를 듣고 너무너무 신기했다.

예체능이란 분야는 직접적으로 아는 사람이 없어서 더 멋있게 느껴졌다.

가끔 홍대에서 공연을 하니까 보러 오라고 하셨는데

이번에 단독공연을 한다는 소식을 듣고

공연을 보러 가게 되었다. 

유튜브로 음악을 들어보았는데 밴드는 콤아겐즈라는 6인조 밴드였고 장르는 레게였다.

작은 공연장에 사람들이 어느 정도 찼고 공연장의 불은 꺼지고 조명이 밴드를 비추었다.

무대에 있는 모습이 너무 멋있어 보였고

밴드의 악기 소리 하나하나가 귀에 머물렀다 가는 기분이었다.

공연의 테마는 건강

 

728x90
728x90
반응형

컴퓨터를 하루종일 쓰는 직업을 갖고 있다면 손목 통증이 없기 쉽지 않은데

사실 정형외과에서 물리치료를 받는 것은 큰 의미가 없을 정도로 근육이나 뼈에 이상이 없기 때문입니다.

특정한 움직임에 신경에 통증이 오는 건데 별거 아닌 것 같아도 너무 거슬리기 때문에 

무엇보다 좋은 건 평소에 스트레칭을 자주 무리하지 않고 해 주면서 가능하면

어깨, 팔꿈치, 손목 라인을 신경 쓴 바른 자세로 업무를 하는 것이 좋습니다만,,, 항상 젤 쉬운 게 안되죠,,

실천할 수 있는 몇 가지 방법을 공유해 드리겠습니다.

첫 번째, 일단 버티컬 마우스로 바꾸는 것! 입니다.

버티컬 마우스는 기존의 마우스와 달리 손목을 자연스러운 위치로 유지할 수 있게 해주는 디자인입니다. 다음은 버티컬 마우스를 사용하는 인체공학적 이유입니다:

  1. 손목 압박 감소:
    • 손목을 비틀지 않고도 자연스러운 수직 자세를 유지해 손목의 정중신경에 가해지는 압박을 줄입니다.
    • 손목터널 증후군의 주요 원인이 되는 손목 과도한 회전과 비틀림을 방지합니다.
  2. 팔꿈치와 어깨의 부담 완화:
    • 손목을 덜 사용해 팔꿈치와 어깨까지 이어지는 근육과 신경을 보호해 주는 효과가 있습니다.
    • 컴퓨터 사용 시 손목과 팔꿈치, 어깨의 정렬을 개선해 자세가 좋아집니다.
  3. 손가락과 손의 피로도 감소:
    • 일반 마우스보다 그립감이 편안하여 장시간 사용 시 피로도를 줄여줍니다.

 

저의 첫 버티컬 마우스 로지컬 MX Vertical

Mx Vertical은 손에 비해 살짝 사이즈가 큰 편이고 아무래도 몇 년 쓰다 보니 엄지 닿는 곳의 고무 부분이 다소 해졌지만 아주 잘 사용했습니다. 무선이고 C타입으로 충전가능합니다.

로지텍 버티컬 인체공학 무선 블루투스 마우스 LIFT VERTICAL MR0094

MR0094는 MX Vertical보단 다소 작은 사이즈로 AA배터리 하나(2년 사용가능)가 들어갑니다.

귀엽고 앙증맞으면 작은 거에 비해서는 무게감이 있고 흰색이라 다소 때가 잘 묻을 수 있지만 사용에는 문제가 없습니다.

혹시 손목받침대를 사용하지 않으셨다면 어깨 팔꿈치 손목까지의 높이에도 문제가 있을 수 있으니

마우스 손목 받침대도 사용하는 것이 좋습니다

두 번째 운동 시에 손목 사용 주의

헬스나 요가 등 운동을 하고 계실 경우에 엎드려뻗친 자세나 요가에서 다운독 자세를 자주 하고 계신다면

적어도 통증이 나아질 때까지는 자제하는 것이 좋습니다. 가능하면 플랭크자세로 대체,,,

통증이 있다면 손목에는 무리가 될 수 있는 자세

등운동으로 랫풀다운을 하시는 분이라면 가능하다면 맥그립으로 변경해 사용하시는 걸 추천드립니다

랫풀다운 맥그립

 

세 번째, 자이로스코프를 이용한 손목 운동

손목으로 인해 여러 운동을 자제하게 되면서 아 그럼 손목을 강화하고 싶다ㅠㅠ이런 생각이 들었는데요

자이로스코프는 회전 운동을 통해 손목을 강화할 수 있는 기구로, 손목의 근력과 유연성을 높여줍니다.

다음은 자이로스코프를 활용한 손목 운동법입니다:

  1. 자이로스코프 기구 잡기:
    • 자이로스코프 기구를 손에 쥐고 손목을 회전시키며 회전하는 자이로스코프의 균형을 유지하는 운동입니다.
    • 자이로스코프의 회전 속도를 유지하려면 일정한 힘을 손목에 가해야 하기 때문에 손목 근육이 강화됩니다.
  2. 규칙적인 반복 운동:
    • 자이로스코프 운동을 하루 5분씩 꾸준히 하면 손목의 지구력과 근력이 증가합니다.
    • 부드러운 회전 운동이기 때문에 손목터널 증후군의 예방 및 증상 완화에 도움이 됩니다.

 

손목운동기구 자이로

 

네 번째,  손목 보호대 착용 및 파스

일상에서는 손목을 고정해 주는 손목 보호대를 해놓는다면 자연스럽게 손목사용 자제가 되고 

사용하지 않는 만큼 빠른 시간 이내에 좋아지고 온/냉찜질로 마사지를 하는 것도 도움이 됩니다.

파스를 붙이는 것도 좋은데 손목에 붙일 때 주의 해야 할 점이 있습니다.

손목에 붙일 때는 손바닥의 아래쪽에 붙이시는 게 좋습니다. 손등에 붙이지 말 것!

(파스 올바르게 붙이는 방법 검색ㄱㄱ)

 

다섯 번째, (한의원 가시는 걸 꺼려하지 않으신다면) 침술 치료 및 EMS 치료기기 사용

저는 아프기 시작했을 때 

정형외과에서 물리치료도 받고, 한의원에서 침술치료도 받았습니다만

지속적으로 방문하기 조금 힘든 상황이었어서  ems저주파 치료기기를 사용하게 되었습니다.

ems저주파 치료기기는 친구한테 목통증에 좋다고 받은 치료기기인데 손목에 쓰니 은근히 좋다고 느껴서 추천드립니다.

제가 갖고 있는 것과 같은 브랜드는 아닌데 이런 종류를 많이 팔더라고요

약간의 진동 같은 저주파로 신경을 자극해서 일종의 물리치료효과를 주는 것 같아요

저 은색 부분에 손목을 올려놓는 식으로 했던 것 같아요ㅋㅋㅋ

 

위 다섯까지 방법들은 다 제가 경험하고,,, 사용해 본 방법인데요,,

저는 요가를 하고 있었던 터라 요가를 플랭크자세로 한다든지 가능한 손목사용을 자제했고

지금까지 사무직으로 일하고 있지만 더 이상의 통증이 없는 상태로 많이 나아졌습니다.

결국 손목사용자제가 가장 중요한 것 같아요. 그게 힘드니 여러 도움을 받는게 효과가 좋구요

꾸준히 실천하며 손목에 무리가 가지 않도록 관리하면 증상 완화에 큰 도움이 될 수 있습니다.

다만, 증상이 심해지거나 지속될 경우 전문가의 진단과 치료를 받는 것이 좋습니다.

사무직 직장인 여러분 손목통증의 거슬림으로부터 해방되길 바라며~~

728x90
728x90
반응형
 

리액트에서 자주 사용되는 주요 훅들은 useState, useEffect, useContext, useReducer, useRef가 있습니다. 각각의 훅과 사용 예시를 함께 정리해 보겠습니다.


1. useState

컴포넌트에서 상태를 관리하는 가장 기본적인 훅입니다.

  • 사용법: [상태, 상태변경함수] = useState(초기값)
 
import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0); // count 상태 변수와 상태 변경 함수 setCount 설정

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount(count + 1)}>Increase</button>
    </div>
  );
}

이 훅은 간단한 숫자, 문자열, 배열 등 다 ㅈ양한 데이터 유형을 상태로 관리할 수 있습니다.


2. useEffect

컴포넌트의 생명주기 동안 특정 작업을 수행할 수 있는 훅입니다. componentDidMount, componentDidUpdate, componentWillUnmount의 역할을 대체합니다.

  • 사용법: useEffect(콜백 함수, [의존성 배열])
 
 
import React, { useState, useEffect } from 'react';

function Timer() {
  const [time, setTime] = useState(0);

  useEffect(() => {
    const interval = setInterval(() => {
      setTime(prevTime => prevTime + 1);
    }, 1000);

    return () => clearInterval(interval); // 컴포넌트가 언마운트될 때 타이머 정리
  }, []); // 빈 배열은 마운트 시 한 번만 실행

  return <div>Timer: {time} seconds</div>;
}

useEffect는 데이터 가져오기, 타이머 설정, 이벤트 리스너 등록 및 해제 같은 작업에 유용합니다.


3. useContext

컴포넌트 트리에서 데이터를 전역으로 관리하고 공유할 때 사용하는 훅입니다. Context API와 함께 사용하며, props를 여러 단계에 걸쳐 전달하지 않고도 데이터를 자식 컴포넌트에 전달할 수 있습니다.

  • 사용법: const contextValue = useContext(Context)
 
import React, { useContext } from 'react';

const ThemeContext = React.createContext('light'); // 초기값 설정

function ThemedButton() {
  const theme = useContext(ThemeContext); // ThemeContext 값을 가져옴
  return <button className={theme}>Themed Button</button>;
}

function App() {
  return (
    <ThemeContext.Provider value="dark">
      <ThemedButton />
    </ThemeContext.Provider>
  );
}

useContext는 전역적으로 관리되는 데이터를 쉽게 사용하게 해 주어 테마나 사용자 정보 관리에 유용합니다.


4. useReducer

useState보다 복잡한 상태 로직이 필요할 때 사용하는 훅입니다. 주로 상태와 액션을 분리하여 Redux와 유사한 패턴으로 상태를 관리할 수 있습니다.

  • 사용법: [상태, dispatch] = useReducer(리듀서 함수, 초기 상태)
 
import React, { useReducer } from 'react';

function reducer(state, action) {
  switch (action.type) {
    case 'increment':
      return { count: state.count + 1 };
    case 'decrement':
      return { count: state.count - 1 };
    default:
      return state;
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, { count: 0 });

  return (
    <div>
      <p>Count: {state.count}</p>
      <button onClick={() => dispatch({ type: 'increment' })}>+</button>
      <button onClick={() => dispatch({ type: 'decrement' })}>-</button>
    </div>
  );
}

useReducer는 복잡한 상태와 여러 상태 변경 작업을 관리할 때 유용합니다.


5. useRef

특정 DOM 요소에 접근하거나 컴포넌트가 리렌더링될 때 유지해야 하는 값에 접근할 수 있습니다. useRef로 생성된 객체는 컴포넌트가 리렌더링되어도 값이 유지됩니다.

  • 사용법: const refContainer = useRef(초기값)
 
 
 
import React, { useRef } from 'react';

function FocusInput() {
  const inputRef = useRef(null);

  const focusInput = () => {
    if (inputRef.current) {
      inputRef.current.focus();
    }
  };

  return (
    <div>
      <input ref={inputRef} type="text" />
      <button onClick={focusInput}>Focus the input</button>
    </div>
  );
}

useRef는 DOM 조작이 필요한 경우나 이전 상태를 유지하고 싶은 경우에 유용합니다.


이 외에도 리액트에서는 useMemouseCallback 훅도 자주 사용됩니다.

이 훅들은 성능 최적화를 위해 특정 값이나 함수를 메모이제이션할 때 사용합니다.

 

728x90
728x90
반응형


10월초에 청주로 여행을 다녀왔어요.
당일치기 여행이었지만 맛있는 음식도 먹고, 아름다운 풍경도 보고, 상당산성 역사도 느낄 수 있는 청주 여행!

청주 맛집 금용 돌짜장


첫 목적지는 유명하다는 '금용' 중국집으로
11시반 오픈인데 10시쯤도착해버린ㅎㅎ
예상치못한 오픈런을 해버렸음
청주 특별 메뉴인 돌짜장을 먹었는데
보통 쟁반짜장을 돌판에 올려 주는데, 이 덕분에 음식이 식지 않고 계속 따뜻하게 먹을 수 있었음~~
해산물의 맛도 잘 어우러지고 누룽지도 올라가있구 세트에 밥이 같이 나와서 짜장밥도 굿

불고기 짬뽕도 먹어봤는데, 이것도 강추
(계란후라이와 오뎅이 무료제공됩니닷)

가을 정취 가득한 추정리 메밀밭

배부르게 먹고 나서 추정리 메밀밭으로 이동ㄱㄱ
차로 40분정도 걸립니당
산속에 있어서 주차장에서 조금(15~20분) 걸어야 했지만,
들판에 자연스럽게 펼쳐진 꽃들이 정말 예쁨
바람에 흐트러지는 메밀꽃들

상당산성~휴식을 취하는 곳


마지막으로 상당산성에 들렀어요.
검색해보면 트래킹이 많이 나와
살짝 걱정했으나 예상과는 다르게 다들 텐트치고
돗자리에 눕거나 캐치볼, 연날리는 사람들을 볼 수 있음
가족단위로 애들과 오기에도 좋구
커플여행으로도 좋은 곳


성내방죽


상당산성에서 차로 5분정도 거리에 저수지와 억새밭이 있으니 사진도 찍고 가을을 느끼는 것도 좋은 추억이 될듯ㅎㅎ

728x90

+ Recent posts