[java 자바공부] Statement와 PreparedStatement이란?, ORM, 로컬 트랜잭션 과 글로벌 트랜잭션 , Dialect , Map 키와 값 , Jdbc Connection pool 와 스레드
본문 바로가기

컴퓨터공부/Java

[java 자바공부] Statement와 PreparedStatement이란?, ORM, 로컬 트랜잭션 과 글로벌 트랜잭션 , Dialect , Map 키와 값 , Jdbc Connection pool 와 스레드

by Life & study 2023. 10. 31.
반응형

[java 자바공부] Statement와 PreparedStatement이란?, ORM, 로컬 트랜잭션 과 글로벌 트랜잭션 , Dialect , Map 키와 값 , Jdbc Connection pool 와 스레드

 

[java 자바공부] Statement와 PreparedStatement이란?

 

Statement와 PreparedStatement는 

Java의 JDBC API에서 SQL 쿼리를 데이터베이스에 전송하는 데 사용되는 인터페이스입니다. 

두 인터페이스의 주요 차이점은 SQL 쿼리를 어떻게 처리하느냐에 있습니다.

Statement:
Statement는 SQL 쿼리를 그대로 실행하는 방식입니다. 

쿼리가 실행될 때마다 SQL 문법을 검사하고, 

쿼리를 컴파일하여 데이터베이스에 전송합니다.


PreparedStatement:
PreparedStatement는 미리 컴파일된 SQL 쿼리를 사용하는 방식입니다. 

동일한 SQL 쿼리를 반복적으로 실행해야 하는 경우, PreparedStatement는 성능 향상을 가져올 수 있습니다.

 또한, SQL 쿼리에 파라미터를 바인딩하는 방식을 사용하므로 SQL Injection 공격으로부터 보호를 제공합니다.
스프링 부트에서는 JdbcTemplate을 사용하여 Statement와 PreparedStatement를 다룰 수 있습니다.

Statement 사용 예제:

java
@Autowired
private JdbcTemplate jdbcTemplate;

public void addUser(String name, String email) {
    String sql = "INSERT INTO Users (name, email) VALUES ('" + name + "', '" + email + "')";
    jdbcTemplate.update(sql);
}
PreparedStatement 사용 예제:
java
@Autowired
private JdbcTemplate jdbcTemplate;

 

public void addUser(String name, String email) {
    String sql = "INSERT INTO Users (name, email) VALUES (?, ?)";
    jdbcTemplate.update(sql, name, email);
}

 


위의 코드에서 볼 수 있듯이, PreparedStatement는 '?'를 사용하여 쿼리에 파라미터를 바인딩합니다. 

이는 쿼리를 보다 안전하게 만들어 주며, SQL Injection 공격을 방지하는 데 도움이 됩니다.

PreparedStatement

위 그림은 PreparedStatement가 어떻게 작동하는지를 나타낸 것입니다. PreparedStatement는 SQL 쿼리를 미리 컴파일하고, 실행 시점에서 파라미터를 바인딩하여 쿼리를 완성합니다. 이 방식은 동일한 쿼리를 반복적으로 실행할 때 데이터베이스의 부하를 줄일 수 있으며, SQL 쿼리의 안전성을 높여줍니다.

 

 

결론,

 

PreparedStatement을 사용해서 Values 값을 감추고 sql 쿼리를 사용해서 컴파일하고, 파리미터로 바인딩하여

쿼리를 완성하므로써 sql 인잭션을 보호 할수있다.

 

 

 

 

 

[java 자바공부] ORM

 

ORM이란 ?

ORM(Object-Relational Mapping)은 객체 지향 프로그래밍 언어와 관계형 데이터베이스 사이의 호환되지 않는 데이터를 변환하는 프로그래밍 기법입니다. ORM 프레임워크는 개발자가 SQL 쿼리 없이 데이터베이스 데이터를 조작할 수 있게 해주며, 이는 개발의 생산성을 높이고 코드의 유지 관리를 쉽게 합니다.

스프링 부트에서는 주로 JPA(Java Persistence API)를 사용한 ORM을 사용합니다. JPA는 자바 ORM 표준이며, JPA를 구현한 대표적인 프레임워크로는 Hibernate가 있습니다. JPA를 사용하면 SQL 대신 JPQL(Java Persistence Query Language)이라는 쿼리 언어를 사용하여 데이터베이스 데이터를 조작할 수 있습니다.

기존의 Mapper 방식과 비교했을 때, JPA는 SQL 쿼리를 직접 작성하는 대신 객체 지향적인 코드로 데이터베이스 데이터를 조작할 수 있도록 도와줍니다. Mapper 방식에서는 SQL 쿼리를 직접 작성하고, 이를 통해 데이터베이스와 직접 상호작용합니다.

 

@Repository
public interface UserRepository extends JpaRepository<User, Long> {

    List<User> findByName(String name);

}

 

"name"이라는 이름을 가진 사용자를 찾는 메서드를 정의한 UserRepository 인터페이스입니다.

 

 

 

 

 

[java 자바공부]  로컬 트랜잭션 과 글로벌 트랜잭션은 무엇인가?

 

Local Transaction:
Local Transaction은 하나의 데이터베이스 연결에서 수행되는 트랜잭션을 의미합니다. 

스프링에서는 @Transactional 어노테이션을 이용하여 Local Transaction을 관리합니다.

 

java
@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    @Transactional
    public void updateUser(Long id, String newName) {
        User user = userRepository.findById(id).orElseThrow();
        user.setName(newName);
    }

}

 

Global Transaction (분산 트랜잭션):
Global Transaction은 여러 데이터베이스 연결에서 수행되는 트랜잭션을 의미합니다. 이는 JTA(Java Transaction API)를 이용하여 관리됩니다. 스프링에서는 @Transactional 어노테이션과 JTA를 이용하여 Global Transaction을 관리할 수 있습니다. 하지만 이는 설정이 복잡하고 성능 이슈가 있을 수 있어, 일반적으로는 각 서비스가 각자의 트랜잭션을 가지고, 이를 조정하는 방식(Saga 패턴 등)을 사용하는 것이 권장됩니다.


위 그림은 Local Transaction과 Global Transaction의 차이를 나타냅니다. Local Transaction은 단일 데이터베이스에서 수행되며, Global Transaction은 여러 데이터베이스에서 동시에 수행됩니다. 

Global Transaction은 여러 데이터베이스의 일관성을 유지해야 하므로 처리가 복잡하고 성능 이슈가 있을 수 있습니다. 따라서 가능하면 Local Transaction을 사용하고, 여러 데이터베이스를 사용해야 하는 경우에는 적절한 방식을 통해 이를 관리하는 것이 중요합니다.

 

 

 

 

[java 자바공부] Dialect 란 무엇인가?

 

 

Dialect(방언)는 JPA나 Hibernate 같은 ORM(Object-Relational Mapping) 프레임워크에서 사용하는 개념입니다. SQL은 표준 언어지만, 각 데이터베이스 벤더(Oracle, MySQL, PostgreSQL 등)는 자신들만의 특성을 반영한 고유한 SQL 문법을 추가로 제공합니다. 이러한 벤더별로 다른 SQL 문법을 ORM 프레임워크가 처리할 수 있게 해주는 것이 바로 Dialect입니다.

Dialect는 데이터베이스 벤더별로 다른 SQL 문법을 추상화하여, 개발자가 데이터베이스 종류에 상관없이 동일한 코드를 작성할 수 있게 도와줍니다. 즉, Dialect를 통해 개발자는 특정 데이터베이스에 종속적인 코드를 작성하지 않아도 됩니다.

스프링 부트에서는 application.properties 또는 application.yml 파일에서 spring.jpa.database-platform 속성을 이용하여 Dialect를 설정할 수 있습니다.

 

아래는 MySQL을 사용하는 경우의 Dialect 설정 예제입니다.

properties
# application.properties 파일
spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect
yml



위의 설정을 통해 스프링 부트는 MySQL에 맞는 Dialect를 사용하게 됩니다.

 

# application.yml 파일
spring:
  jpa:
    database-platform: org.hibernate.dialect.MySQL5InnoDBDialect

[java 자바공부] Map 키와 값

 

Java의 Map은 키(Key)와 값(Value)의 쌍으로 이루어진 데이터를 저장하는 자료 구조입니다. Map 인터페이스를 구현하는 클래스로는 HashMap, TreeMap, LinkedHashMap 등이 있습니다.

다음은 Map의 간단한 사용 예입니다.

java
Map<String, Integer> map = new HashMap<>();
map.put("Apple", 10);
map.put("Banana", 20);
Integer appleCount = map.get("Apple");  // appleCount는 10

 

MyBatis와 같은 SQL Mapper를 사용할 때는, Map을 이용하여 쿼리의 파라미터를 전달하거나 결과를 받아올 수 있습니다.

java
// 파라미터로 Map 사용
Map<String, Object> params = new HashMap<>();
params.put("name", "John");
params.put("age", 30);
List<User> users = sqlSession.selectList("UserMapper.selectUsers", params);

 

// 결과를 Map으로 받아오기
Map<String, Object> userMap = sqlSession.selectOne("UserMapper.selectUser", 1);


스프링 데이터 JPA에서는 메서드 이름을 이용하여 쿼리를 생성하거나, @Query 어노테이션을 이용하여 JPQL(Java Persistence Query Language)이나 SQL 쿼리를 직접 작성할 수 있습니다.

java
@Repository
public interface UserRepository extends JpaRepository<User, Long> {

    List<User> findByName(String name);

    @Query("SELECT u FROM User u WHERE u.age > :age")
    List<User> findUsersOlderThan(@Param("age") int age);

}


Map and Query

위 그림은 Map과 SQL Mapper, JPA의 관계를 나타냅니다. Map은 키와 값의 쌍으로 데이터를 저장하며, SQL Mapper와 JPA는 이를 이용하여 데이터베이스와 상호작용합니다. SQL Mapper는 SQL 쿼리를 직접 작성하여 사용하며, Map을 이용하여 쿼리의 파라미터를 전달하거나 결과를 받아올 수 있습니다. 반면 JPA는 메서드 이름이나 @Query 어노테이션을 이용하여 쿼리를 생성하고, 이를 통해 데이터베이스와 상호작용합니다.

 

 

 

java에서는 map으로 키 벨류를 넣고

List<User> users = sqlSession.selectList("UserMapper.selectUsers", params); 로 받아올수있고,

 

Jpa에서는 

java
@Repository
public interface UserRepository extends JpaRepository<User, Long> {

    List<User> findByName(String name);

    @Query("SELECT u FROM User u WHERE u.age > :age")
    List<User> findUsersOlderThan(@Param("age") int age);

}

 

   List findUsersOlderThan(@Param("age") int age); 로 받아올수있다.

 

 

 

[java 자바공부] Jdbc Connection pool 와 스레드

 

JDBC Connection Pool:


JDBC Connection Pool은 데이터베이스 연결을 재사용할 수 있도록 관리하는 기술입니다. 데이터베이스 연결은 생성과 종료 시에 비용이 많이 드는 작업이므로, 이를 재사용함으로써 애플리케이션의 성능을 향상시킬 수 있습니다. 스프링 부트에서는 HikariCP, Tomcat JDBC, C3P0 등 다양한 Connection Pool 라이브러리를 사용할 수 있습니다. 기본적으로는 HikariCP가 사용됩니다.

위의 설정을 통해 최대 5개의 데이터베이스 연결을 Connection Pool에서 관리하도록 설정할 수 있습니다.
스레드(Thread):
스레드는 프로세스 내에서 실행되는 흐름의 단위입니다. 멀티 스레딩을 이용하면 여러 작업을 동시에 처리할 수 있어, 애플리케이션의 성능을 향상시킬 수 있습니다. 자바에서는 Thread 클래스 또는 Runnable 인터페이스를 이용하여 스레드를 생성하고 관리할 수 있습니다.

properties
# application.properties 파일
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=secret
spring.datasource.hikari.maximum-pool-size=5

 

java
Thread thread = new Thread(() -> {
    // 스레드에서 실행할 코드
});
thread.start();
스프링 부트에서는 @Async 어노테이션을 이용하여 비동기 처리를 수행할 수 있습니다.
java
@Service
public class MyService {

    @Async
    public void doSomething() {
        // 비동기로 처리할 코드
    }

}

 


JDBC Connection Pool and Thread

위 그림은 JDBC Connection Pool과 스레드의 관계를 나타냅니다. 

각 스레드는 Connection Pool에서 데이터베이스 연결을 가져와 사용하며, 사용이 끝나면 이를 Connection Pool에 반환합니다. 이를 통해 데이터베이스 연결을 효율적으로 재사용할 수 있습니다. 한편, 여러 스레드가 동시에 데이터베이스 연결을 요청할 경우, Connection Pool의 크기를 적절히 설정하여 동시성 문제를 관리할 수 있습니다

 

스레드라 무엇인가?

 

 

스레드(Thread)는 프로그램 내에서 실행되는 흐름의 단위를 의미합니다. 하나의 프로세스는 여러 개의 스레드를 가질 수 있으며, 이를 통해 여러 작업을 동시에 수행하는 것처럼 보이게 할 수 있습니다. 이를 멀티스레딩(Multithreading)이라고 합니다.

Java에서는 Thread 클래스를 사용하여 스레드를 생성하고 제어할 수 있습니다. 또는 Runnable 인터페이스를 구현하여 스레드를 생성할 수도 있습니다.

java
// Thread 클래스를 상속받아서 스레드 생성
class MyThread extends Thread {
    public void run(){
        // 스레드에서 실행할 코드
    }
}

MyThread t = new MyThread();
t.start();  // 스레드 시작

// Runnable 인터페이스를 구현하여 스레드 생성
class MyRunnable implements Runnable {
    public void run(){
        // 스레드에서 실행할 코드
    }
}

Thread t = new Thread(new MyRunnable());
t.start();  // 스레드 시작

 

스프링 부트에서는 @Async 어노테이션을 사용하여 비동기 처리를 구현할 수 있습니다. 

@Async 어노테이션을 메서드에 적용하면, 해당 메서드는 별도의 스레드에서 실행됩니다.

java
@Service
public class MyService {

    @Async
    public void doSomething() {
        // 비동기로 처리할 코드
    }

}




위 그림은 하나의 프로세스에서 여러 스레드가 동시에 실행되는 모습을 보여줍니다. 각 스레드는 독립적으로 실행되므로, 서로 다른 작업을 동시에 처리할 수 있습니다. 이를 통해 애플리케이션의 응답성을 향상시키거나 CPU를 효율적으로 사용할 수 있습니다. 하지만 스레드를 제어하는 것은 복잡하며, 동기화 문제 등을 주의해야 합니다.



결론, 

 

스레드는 어플리케이션 실행단위이다.

 

 

 

 

반응형

댓글