본문 바로가기
Java Spring/MVC

[Spring] Spring JDBC 사용하기

by GGShin 2022. 7. 2.

Spring JDBC를 사용하기 위해서는 먼저 jdbc dependency를 추가해주어야 됩니다. 

 

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>

 

그리고 JdbcTemplate class의 객체를 이용하여 jdbc를 사용하면 됩니다.

Dao처럼 repository 역할을 하는 class에 주입하여 사용하게 되는데, 아래 코드를 참고하시면 됩니다.

 

@Repository
public class PersonJdbcDao {

    @Autowired
    JdbcTemplate jdbcTemplate;

  //...

}

 

이 jdbcTemplate는 CRUD 기능을 하는 method들이 정의되어 있고, 그 method와 sql query문을 사용해서 CRUD를 구현하게 되는 것 입니다.

 

예시에서 사용한 person 이라는 table은 sql파일을 통해 아래와 같이 구성해 두었습니다.

 

CREATE TABLE person (
    id integer NOT NULL,
    name varchar(255),
    location varchar(255),
    birth_date timestamp,

    PRIMARY KEY(id)
);

INSERT INTO PERSON (ID, NAME, LOCATION, BIRTH_DATE )
VALUES(10001,  'Ranga', 'Hyderabad',now());
INSERT INTO PERSON (ID, NAME, LOCATION, BIRTH_DATE )
VALUES(10002,  'James', 'New York',now());
INSERT INTO PERSON (ID, NAME, LOCATION, BIRTH_DATE )
VALUES(10003,  'Pieter', 'Amsterdam',now());

 

그리고 동일한 타입의 데이터를 갖는 Person이라는 자바 클래스도 하나 생성해두어, sql과 java간에 데이터 mapping이 가능하도록 준비하였습니다.

 

package com.ggshin.databaseprac.entity;

import java.util.Date;

public class Person {

//person table의 column들과 동일한 이름 & 데이터 타입의 field들!
    private int id;
    private String name;
    private String location;
    private Date birthDate;

    public Person(){}

    public Person(int id, String name, String location, Date birthDate) {
        this.id = id;
        this.name = name;
        this.location = location;
        this.birthDate = birthDate;
    }

    //getters, setters omitted

    @Override
    public String toString() {
        return "id: " + id + ", name: " + name + ", location: " + location + ", birth_date: " + birthDate + "\n";
    }
}

 

사전 준비는 완료되었으니 CRUD 기능을 어떻게 구현하는지 하나씩 살펴보겠습니다. 

 

 

1.CREATE

새로운 Person을 저장하려면 update이라는 method를 사용하면 됩니다.

public int insert(Person person) {
    return jdbcTemplate.update(
    "insert into person (id, name, location, birth_date) values(?, ?, ?, ?)",
           person.getId(),
           person.getName(), 
           person.getLocation(),
           new Timestamp(person.getBirthDate().getTime()));
}

 

method의 파라미터로 어떤 것들이 들어가 있는지 살펴보겠습니다.

 

jdbcTemplate.update(
    //첫번째 파라미터로는 query문이 들어갑니다.insert into 구문을 사용했습니다.
    //values(?, ?, ?, ?)에 '?' 부분에 들어갈 값들은 뒤이은 파라미터들이 채워줍니다. 
    "insert into person (id, name, location, birth_date) values(?, ?, ?, ?)",
    	//첫번째 ?에 해당하는 id 값입니다.
           person.getId(),
        //두번째 ?에 해당하는 name 값입니다.
           person.getName(), 
        //세번째 ?에 해당하는 location 값입니다.
           person.getLocation(),
       	//마지막 ?에 해당하는 birth_date 값입니다.
           new Timestamp(person.getBirthDate().getTime())
);

 

2. Read

//select * from person 에 해당하는 method 구현
//전체 데이터 GET하기!

public List<Person> findAll() {
  return jdbcTemplate.query("select * from person", new BeanPropertyRowMapper<>(Person.class));
}

테이블 안에 저장된 모든 데이터를 GET 하기 위해서는 위와 같이 query라는 method를 사용해서 구현해주면 됩니다. Parameter로 query문과 rowmapper를 받습니다. Rowmapper에는 BeanPropertyRowMapper를 사용하였는데, 해당 mapper는 table의 row를 명시된 class의 인스턴스로 변환해주는 역할을 해줍니다! Query문을 통해 받은 결과물을 java class 인스턴스로 바꾸어 주는 것입니다. 여기에서는 Person.class로 명시해주었으니 Person 인스턴스로 변환해주게 됩니다.

BeanPropertyRowMapper : Converts a row into a new instance of the specified mapped target class
출처: https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/jdbc/core/BeanPropertyRowMapper.html

 

만약에 특정 id만 GET하려면 어떻게 할 수 있을까요? 전체 데이터가 아닌 특정 데이터를 query하기 위해서는 queryForObject method를 사용합니다. 반환 값이 하나이므로 반환 type을 List<Person>이 아닌 Person이라는 단수 형태로 바꾸어주었습니다. 그리고 parameter로는 위의 findAll과 유사하나 id 부분이 추가되었는데, 이는 query문 내부에 id=? 에서 ? 에 들어가게 되는 데이터를 명시해주는 것입니다.

 

//특정 id인 데이터만 GET하기!

public Person findById(int id) {
        return jdbcTemplate.queryForObject(
                "SELECT * FROM person WHERE id=?",
                new BeanPropertyRowMapper<>(Person.class)
                ,id);
}

 

3. Update

이미 존재하는 데이터를 수정할 때에도 update method를 사용합니다. 데이터를 처음 생성할 때(create)도 update을 사용했었죠?

동일한 method입니다.

다만 sql query문으로 insert into ... values... 가 아니라 update ... set ... 구문을 사용하게 됩니다.

where id = ? 로 어떤 id인 데이터를 변경할 것인지 찾아서 업데이트하게 됩니다. 

public int update(Person person) {
   return jdbcTemplate.update(
          "update person set name = ?, location=?, birth_date=? where id =?",
           person.getName(),
           person.getLocation(),
           new Timestamp(person.getBirthDate().getTime()), person.getId());
}

 

 

 

4. DELETE

Row를 삭제하고 싶을 때도 마찬가지로 update method를 사용하면 됩니다. (CREATE만을 제외하고 다 update을 사용하네요 ㅎㅎ)

public int deleteById(int id) {
     return jdbcTemplate.update(
         "DELETE FROM person WHERE id=?", id);
}

 

parameter로 query문과 어떤 것을 기준으로 삭제를 할지를 넣어주면 됩니다.

위의 예시에서는 deleteById의 parameter로 들어올 id에 해당하는 데이터를 삭제해달라는 내용의 method를 작성하였습니다.

 

이렇게 기본적인 Spring JDBC를 사용한 CRUD 구현 방식에 대해 알아보았는데, 기본적인 내용들은 많이 어렵지 않습니다!

아래 깃허브에서 파일 보실 수 있고, clone 하신다음 본인 IDE에서 run 해보면 어떻게 구동되는지도 확인해 보시면 이해에 더 도움이 될 것 같습니다. :) 

 

https://github.com/happyduck-git/SpringJDBC

 

GitHub - happyduck-git/SpringJDBC: SpringJDBC 사용방법

SpringJDBC 사용방법. Contribute to happyduck-git/SpringJDBC development by creating an account on GitHub.

github.com

 

감사합니다.

 


참고자료

 

1.

https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/jdbc/core/BeanPropertyRowMapper.html

 

BeanPropertyRowMapper (Spring Framework 5.3.21 API)

RowMapper implementation that converts a row into a new instance of the specified mapped target class. The mapped target class must be a top-level class and it must have a default or no-arg constructor. Column values are mapped based on matching the column

docs.spring.io

 

* CommandLineRunner: Application contex가 준비되면 바로 실행되게 한다. 

반응형