60일차 (2) - 스프링 (Jdbc, JdbcTest)

Yohan·2024년 5월 18일
0

코딩기록

목록 보기
89/156
post-custom-banner

Jdbc (Java DataBase Connectivity)

자바 프로그램에서 SQL 문을 실행하여 데이터를 관리하기 위한 JAVA API

-> 즉, Java가 DB와 통신할 수 있게 해주는 API

  • 별도의 프로그램을 만들 필요 없이, 해당 데이터베이스의 JDBC를 이용하면 하나의 프로그램으로 데이터베이스를 관리가능

전통적인 JDBC 방식의 문제점



해결방안

  • Spring Framework에서의 JdbcTemplate 이라는 객체
    -> JDBC의 장점을 유지하면서, 전통적 방식의 JDBC 단점을 극복하여, 간결한 형태의 API 사용법을 제공하며, 기존 방식에서 지원하지 않는 편리한 기능을 제공
  • 가장 대표적은 장점으로는, 전통적 JDBC 방식에서 반복적으로 진행하던 작업을 대신한다.
    (Connection, PreparedStatement, ResultSet의 반복 처리, Exception 처리 등)

JdbcTemplate 사용 방법

1. JdbcTemplate 의존성 주입

  • build.gradle에 의존성 추가
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-jdbc'
}
  • application.properties에 데이터베이스 연결 설정을 추가

2. SELECT(다중행 조회, 단일행 조회)

  • query()
    • 쿼리 실행 결과가 여러 행인 경우 사용
  • queryForObject()
    • 쿼리 실행 결과가 한 행인 경우 사용
    // SELECT : 다중행 조회
    // 조회했을 때의 내용에 대한 처리만 건네주면 나머지는 다 해줄게
    public List<Person> findAll() {
        String sql = "SELECT * FROM tbl_person";
        return template.query(sql, (rs, rowNum) -> new Person(rs));
    }

    // SELECT : 단일행 조회
    public Person findOne(long id) {
        String sql = "SELECT * FROM tbl_person WHERE id = ?";
        return template.queryForObject(sql, (rs, n) -> new Person(rs), id);
    }
  • 정보에 대한 내용은 Person에서 생성자로 처리

3. INSERT, UPDATE, DELETE에 사용하는 update() 메서드

// INSERT
    public int save(Person person) {
        String sql = "INSERT INTO tbl_person VALUES (?, ?, ?)";
        return template.update(sql, person.getId(),
                person.getPersonName(), person.getPersonAge());
    }

    // DELETE
    public boolean delete(long id) {
        String sql = "DELETE FROM tbl_person WHERE id = ?";
        int result = template.update(sql, id);
        return result == 1;
    }

    // UPDATE
    public boolean update(Person newPerson) {
        // 이름, 나이 수정
        String sql = "UPDATE tbl_person SET person_name = ?, person_age = ? WHERE id = ?";
        int flag = template.update(sql, newPerson.getPersonName(),
                newPerson.getPersonAge(), newPerson.getId());
        return flag == 1;
    }

SpringJdbcTest

Jdbc에서 메서드를 만들었으면 단위 테스트 프레임워크인 JUnit5를 통해 JdbcTest를 진행하여 코드에 오류가 없는지 확인

  • @SpringBootTest를 통해 테스트임을 알리고, @Transactional, @Rollback을 명시함으로써 테스트 후 데이터베이스를 원래 상태로 되돌릴 수 있다.
    -> 테스트 간에 데이터 일관성을 유지하고, 테스트가 다른 테스트나 실제 데이터에 영향을 미치지 않도록함
  • 테스트 시에는 생성자 주입 대신에 필드 주입을 사용하는 것이 관례
  • 테스트 대상을 명시해주고 테스트 전에 데이터를 미리 집어넣어서 테스트에 사용
  • Test의 이름은 단언한다. (확실하게 적어줌)
  • gwt 패턴에 맞추어 적어준다.

전체 코드

@SpringBootTest
@Transactional
@Rollback
class SpringJdbcTest {

    // 테스트시에는 필드 주입
    @Autowired
    SpringJdbc springJdbc; // 테스트 대상


    // 각 테스트 전에 공통으로 실행할 코드
    // -> 미리 데이터를 몇개 집어넣어놓음
    @BeforeEach
    void bulkInsert() {
        for (int i = 0; i < 10; i++) {
            Person p = new Person(i + 2000,
                    "테스트맨" + i,
                    10);
            springJdbc.save(p);

        }
    }


    // 단위 테스트 프레임워크 : JUnit5
    // 테스트 == 단언 (Assertion)
    @Test
    @DisplayName("사람의 정보를 입력하면 데이터베이스에 반드시 저장되어야 한다.")
    void saveTest() {
        // gwt 패턴
        // given : 테스트에 주어질 데이터
        Person p = new Person(1000, "천천이", 34);

        // when : 테스트 상황
        int result = springJdbc.save(p);

        // then : 테스트 결과 단언
        assertEquals(1, result);
    }



    @Test
    @DisplayName("아이디가 주어지면 해당 아이디의 사람정보가" +
            " 데이터베이스로부터 삭제되어야 한다.")
    void deleteTest() {
        //given
        long id = 77;
        //when
        boolean flag = springJdbc.delete(id);
        //then
        assertTrue(flag);
    }


    @Test
    @DisplayName("새로운 이름과 나이를 전달하면 사람의 정보가 " +
            "데이터베이스에서 수정된다." )
    void modifyTest() {
        //given
        Person person
                = new Person(77, "팔팔이", 8);
        //when
        boolean flag = springJdbc.update(person);
        //then
        assertTrue(flag);
    }


    @Test
    @DisplayName("사람 정보를 전체조회하면 결과" +
            " 건수는 4건이며, 첫번째 사람의 이름은 \'팔팔이\'다.")
    void findAllTest() {
        //given

        //when
        List<Person> people = springJdbc.findAll();
        //then
        people.forEach(System.out::println);

        assertEquals(4, people.size());
        assertEquals("팔팔이", people.get(0).getPersonName());
    }



    @Test
    @DisplayName("사람 정보를 아이디로 단일조회시 아이디가 300인 " +
            "사람의 이름은 삼백이이고 나이는 34이다.")
    void findOneTest() {
        //given
        long id = 300;
        //when
        Person person = springJdbc.findOne(id);
        //then
        System.out.println("person = " + person);

        assertNotNull(person);
        assertEquals("삼백이", person.getPersonName());
        assertEquals(34, person.getPersonAge());
    }
profile
백엔드 개발자
post-custom-banner

0개의 댓글