본문 바로가기
GD's IT Lectures : 기초부터 시리즈/마이바티스(MyBatis) 기초부터 ~

[마이바티스(MyBatis)] 실습 및 예제

by GDNGY 2023. 5. 16.

Chapter 9. 실습 및 예제

이론적 지식만으로는 충분하지 않습니다. 이 장에서는 실제 마이바티스를 사용한 다양한 실습과 예제를 통해 마이바티스의 활용법을 배워보도록 하겠습니다.

 


 

반응형

 


[Chapter 9. 실습 및 예제]

 

9.1. CRUD 기반 예제

9.1.1. 회원 관리 시스템 실습

9.1.1.1. 회원 데이터베이스 구축

9.1.1.2. 회원 등록 기능 구현

9.1.1.3. 회원 조회 기능 구현

9.1.1.4. 회원 정보 수정 기능 구현

9.1.1.5. 회원 삭제 기능 구현

 

9.2. 웹 애플리케이션 연동

9.2.1. 스프링 부트와 마이바티스 연동 예제

9.2.1.1. 프로젝트 설정

9.2.1.2. 웹 애플리케이션 구현

9.2.1.3. 웹 애플리케이션 테스트

 

9.3. 고급 기능 실습

9.3.1. 동적 SQL 실습

9.3.1.1. 동적 SQL 작성 방법

9.3.1.2. 동적 SQL 활용 예제

9.3.2. 페이징 처리 실습

9.3.2.1. 페이징 처리 방법

9.3.2.2. 페이징 처리 예제

9.3.3. 배치 작업 실습

9.3.3.1. 배치 작업 방법

9.3.3.2. 배치 작업 예제


9.1. CRUD 기반 예제

CRUD는 데이터를 처리하는 기본적인 연산인 Create(생성), Read(읽기), Update(수정), Delete(삭제)의 첫 글자들을 따서 만든 용어입니다. CRUD 연산은 대부분의 시스템에서 기본적으로 필요한 기능이며, 따라서 이 예제에서는 CRUD 연산을 처리하는 회원 관리 시스템을 구현해 보도록 하겠습니다.

 


9.1.1. 회원 관리 시스템 실습

이 실습에서는 마이바티스를 사용하여 데이터베이스에서 CRUD 연산을 수행하는 간단한 회원 관리 시스템을 구현해보겠습니다. 회원 관리 시스템은 회원 정보를 등록, 조회, 수정, 삭제하는 기능을 포함합니다. 이를 위해서는 먼저 데이터베이스에 회원 정보를 저장할 테이블을 생성해야 합니다.

 

9.1.1.1. 회원 데이터베이스 구축

회원 정보를 저장할 데이터베이스와 테이블을 생성합니다. 간단하게 회원 아이디, 이름, 이메일, 등록일을 필드로 가지는 member 테이블을 만들어보겠습니다. 다음은 이를 위한 SQL 스크립트입니다.

 

[예제]

CREATE TABLE member (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(30) NOT NULL,
    email VARCHAR(50) NOT NULL,
    regdate DATETIME DEFAULT CURRENT_TIMESTAMP
);

 

이제 이 테이블에 데이터를 넣고 조회하거나 수정, 삭제하는 기능을 구현할 차례입니다.

 

9.1.1.2. 회원 등록 기능 구현

이제 회원 정보를 데이터베이스에 등록하는 기능을 구현해 보겠습니다. 이를 위해 필요한 것은 삽입을 위한 SQL 문과 해당 SQL을 실행할 MyBatis 매퍼입니다.

 

[예제]

// Member.java
public class Member {
    private int id;
    private String name;
    private String email;
    private Date regdate;
    
    // getters and setters
}

// MemberMapper.java
public interface MemberMapper {
    void insertMember(Member member);
}

 

이제 'MemberMapper.xml' 파일을 만들어 매퍼 메서드와 SQL을 연결해 보겠습니다.

 

[예제]

<mapper namespace="com.example.mapper.MemberMapper">
    <insert id="insertMember" parameterType="com.example.domain.Member">
        INSERT INTO member (name, email) VALUES (#{name}, #{email})
    </insert>
</mapper>

 

이제 이 매퍼를 사용해서 회원 정보를 데이터베이스에 추가하는 서비스 메서드를 작성해 보겠습니다.

 

[예제]

@Service
public class MemberService {
    private final MemberMapper memberMapper;

    public MemberService(MemberMapper memberMapper) {
        this.memberMapper = memberMapper;
    }

    public void addMember(Member member) {
        memberMapper.insertMember(member);
    }
}

 

이제 addMember 메서드를 호출하면 회원 정보가 데이터베이스에 추가됩니다.

 

9.1.1.3. 회원 조회 기능 구현

이제 회원 정보를 데이터베이스에서 조회하는 기능을 구현해 보겠습니다. 다음은 조회를 위한 SQL 문과 해당 SQL을 실행할 MyBatis 매퍼의 구현 예제입니다.

 

[예제]

// MemberMapper.java에 메소드 추가
public interface MemberMapper {
    //...
    Member selectMember(int id);
}

 

매퍼 XML 파일에서는 이 메서드에 해당하는 SQL을 매핑합니다.

 

[예제]

<mapper namespace="com.example.mapper.MemberMapper">
    <!--...-->
    <select id="selectMember" parameterType="int" resultType="com.example.domain.Member">
        SELECT * FROM member WHERE id = #{id}
    </select>
</mapper>

 

이제 이 매퍼를 사용해서 회원 정보를 데이터베이스에서 가져오는 서비스 메서드를 작성해 보겠습니다.

 

[예제]

// MemberService.java에 메소드 추가
public class MemberService {
    //...
    public Member getMember(int id) {
        return memberMapper.selectMember(id);
    }
}


이제 getMember 메서드를 호출하면 데이터베이스에서 해당 ID의 회원 정보를 가져옵니다.

 

9.1.1.4. 회원 정보 수정 기능 구현

회원 정보를 수정하는 기능도 비슷한 방식으로 구현할 수 있습니다. 다음은 수정을 위한 SQL 문과 해당 SQL을 실행할 MyBatis 매퍼의 구현 예제입니다.

 

[예제]

// MemberMapper.java에 메소드 추가
public interface MemberMapper {
    //...
    void updateMember(Member member);
}

 

매퍼 XML 파일에서는 이 메서드에 해당하는 SQL을 매핑합니다.

 

[예제]

<mapper namespace="com.example.mapper.MemberMapper">
    <!--...-->
    <update id="updateMember" parameterType="com.example.domain.Member">
        UPDATE member SET name = #{name}, email = #{email} WHERE id = #{id}
    </update>
</mapper>


이제 이 매퍼를 사용해서 회원 정보를 수정하는 서비스 메서드를 작성해 보겠습니다.

 

[예제]

// MemberService.java에 메소드 추가
public class MemberService {
    //...
    public void updateMember(Member member) {
        memberMapper.updateMember(member);
    }
}

 

이제 updateMember 메서드를 호출하면 데이터베이스의 해당 회원 정보가 업데이트됩니다.

 

9.1.1.5. 회원 삭제 기능 구현

마지막으로, 회원 정보를 삭제하는 기능을 구현하겠습니다. 다음은 삭제를 위한 SQL 문과 해당 SQL을 실행할 MyBatis 매퍼의 구현 예제입니다.

 

[예제]

// MemberMapper.java에 메소드 추가
public interface MemberMapper {
    //...
    void deleteMember(int id);
}


매퍼 XML 파일에서는 이 메서드에 해당하는 SQL을 매핑합니다.

 

[예제]

<mapper namespace="com.example.mapper.MemberMapper">
    <!--...-->
    <delete id="deleteMember" parameterType="int">
        DELETE FROM member WHERE id = #{id}
    </delete>
</mapper>

 

이제 이 매퍼를 사용해서 회원 정보를 삭제하는 서비스 메서드를 작성해 보겠습니다.

 

[예제]

// MemberService.java에 메소드 추가
public class MemberService {
    //...
    public void deleteMember(int id) {
        memberMapper.deleteMember(id);
    }
}

 

이제 deleteMember 메서드를 호출하면 데이터베이스에서 해당 ID의 회원 정보를 삭제합니다.

 


9.2. 웹 애플리케이션 연동

마이바티스와 스프링 부트를 사용하여 웹 애플리케이션을 구현하는 방법을 살펴봅니다. 이를 위해 스프링 부트 프로젝트를 생성하고, 그 안에 마이바티스 설정을 추가합니다.

 


9.2.1. 스프링 부트와 마이바티스 연동 예제

9.2.1.1. 프로젝트 설정

먼저, 스프링 부트 프로젝트를 생성하고 필요한 의존성을 추가합니다. pom.xml에 다음 내용을 추가하면 됩니다.

 

[예제]

<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.2.0</version>
</dependency>

 

이 의존성을 추가하면 스프링 부트 프로젝트에서 마이바티스를 사용할 수 있게 됩니다.

 

9.2.1.2. 웹 애플리케이션 구현

스프링 부트와 마이바티스를 연동하여 웹 애플리케이션을 구현해봅시다. 아래 예제에서는 회원 정보를 관리하는 간단한 웹 애플리케이션을 구현합니다.

 

먼저 Member 클래스를 정의하겠습니다.

 

[예제]

public class Member {
    private int id;
    private String name;
    private String email;
    // getters and setters
}

 

그 다음으로, MemberMapper 인터페이스를 정의하고, 각 메서드에 해당하는 SQL을 매핑 파일에 작성합니다.

 

[예제]

public interface MemberMapper {
    List<Member> selectAllMembers();
    Member selectMember(int id);
    void insertMember(Member member);
    void updateMember(Member member);
    void deleteMember(int id);
}

 

[예제]

<mapper namespace="com.example.mapper.MemberMapper">
    <select id="selectAllMembers" resultType="com.example.Member">
        SELECT * FROM member
    </select>
    <select id="selectMember" parameterType="int" resultType="com.example.Member">
        SELECT * FROM member WHERE id = #{id}
    </select>
    <insert id="insertMember" parameterType="com.example.Member">
        INSERT INTO member (name, email) VALUES (#{name}, #{email})
    </insert>
    <update id="updateMember" parameterType="com.example.Member">
        UPDATE member SET name = #{name}, email = #{email} WHERE id = #{id}
    </update>
    <delete id="deleteMember" parameterType="int">
        DELETE FROM member WHERE id = #{id}
    </delete>
</mapper>

 

그리고 나서, 서비스 클래스에서 매퍼를 주입받아 사용합니다.

 

[예제]

@Service
public class MemberService {
    private final MemberMapper memberMapper;

    public MemberService(MemberMapper memberMapper) {
        this.memberMapper = memberMapper;
    }

    public List<Member> getAllMembers() {
        return memberMapper.selectAllMembers();
    }

    public Member getMember(int id) {
        return memberMapper.selectMember(id);
    }

    public void addMember(Member member) {
        memberMapper.insertMember(member);
    }

    public void modifyMember(Member member) {
        memberMapper.updateMember(member);
    }

    public void removeMember(int id) {
        memberMapper.deleteMember(id);
    }
}

 

마지막으로, 컨트롤러에서 서비스를 주입받아 웹 요청을 처리합니다.

 

[예제]

@RestController
public class MemberController {
    private final MemberService memberService;

    public MemberController(MemberService memberService) {
        this.memberService = memberService;
    }

    @GetMapping("/members")
    public List<Member> getAllMembers() {
        return memberService.getAllMembers();
    }

    @GetMapping("/members/{id}")
    public Member getMember(@PathVariable int id) {
        return memberService.getMember(id);
    }

    @PostMapping("/members")
    public void addMember(@RequestBody Member member) {
        memberService.addMember(member);
    }

    @PutMapping("/members/{id}")
    public void modifyMember(@PathVariable int id, @RequestBody Member member) {
        member.setId(id);
        memberService.modifyMember(member);
    }

    @DeleteMapping("/members/{id}")
    public void removeMember(@PathVariable int id) {
        memberService.removeMember(id);
    }
}

 

9.2.1.3. 웹 애플리케이션 테스트

위에서 작성한 웹 애플리케이션을 테스트해 봅시다. 스프링 부트 테스트를 활용하여 각 기능이 정상적으로 동작하는지 확인합니다. 이를 위해 @SpringBootTest 애노테이션과 TestRestTemplate를 사용할 것입니다.

 

다음은 회원 관리 기능을 테스트하는 코드입니다:

 

[예제]

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class MemberControllerTest {

    @Autowired
    private TestRestTemplate restTemplate;
    
    @Autowired
    private MemberMapper memberMapper;

    @Test
    public void getAllMembersTest() {
        List<Member> members = restTemplate.getForObject("/members", List.class);
        assertThat(members).isNotNull();
    }
    
    @Test
    public void getMemberTest() {
        Member member = memberMapper.selectAllMembers().get(0);
        Member testMember = restTemplate.getForObject("/members/" + member.getId(), Member.class);
        assertThat(testMember).isNotNull();
        assertThat(testMember.getName()).isEqualTo(member.getName());
    }

    @Test
    public void addMemberTest() {
        int before = memberMapper.selectAllMembers().size();
        Member member = new Member();
        member.setName("test");
        member.setEmail("test@gmail.com");
        restTemplate.postForObject("/members", member, Member.class);
        int after = memberMapper.selectAllMembers().size();
        assertThat(after).isEqualTo(before + 1);
    }
    
    // similarly, implement modifyMemberTest() and removeMemberTest()
}

 

여기서는 TestRestTemplate 객체를 활용하여 실제 HTTP 요청을 보내고 응답을 받아 검증합니다. 이렇게 웹 애플리케이션의 실제 동작을 테스트하는 것은 애플리케이션의 정상 작동을 보장하는 데 큰 도움이 됩니다.

 


9.3. 고급 기능 실습

마이바티스의 강력한 기능 중 몇 가지를 살펴보겠습니다. 여기서는 동적 SQL, 페이징 처리, 그리고 배치 작업에 대해 실습하도록 하겠습니다.

 


9.3.1. 동적 SQL 실습

마이바티스는 SQL 구문을 동적으로 생성하는 것을 지원합니다. 이는 사용자의 입력에 따라 SQL 구문이 달라져야 하는 상황에서 매우 유용합니다.

 

9.3.1.1. 동적 SQL 작성 방법

동적 SQL을 작성하기 위해서는 <if>, <choose>, <when>, <otherwise> 등의 XML 태그를 사용할 수 있습니다. 다음은 <if> 태그를 사용한 예제입니다:

 

[예제]

<select id="findMembers" resultType="Member">
    SELECT * FROM members
    <if test="name != null">
        WHERE name = #{name}
    </if>
</select>


이 SQL문은 이름을 입력받아 해당 이름의 회원을 찾는 쿼리입니다. 만약 이름이 입력되지 않았다면 모든 회원을 검색하는 쿼리가 됩니다.

 

9.3.1.2. 동적 SQL 활용 예제

동적 SQL을 활용하여 회원을 검색하는 기능을 추가해 봅시다. 사용자는 이름을 선택적으로 입력할 수 있으며, 이름이 입력되지 않았다면 모든 회원을 검색합니다.

 

[예제]

public List<Member> findMembers(String name) {
    return sqlSession.selectList("findMembers", name);
}


이는 SQL 구문을 동적으로 생성하여 사용자의 입력에 따라 다르게 동작하는 코드를 작성하는 방법을 보여줍니다.

 

9.3.2. 페이징 처리 실습

많은 양의 데이터를 처리해야 할 때, 한번에 모든 데이터를 로드하는 것은 비효율적일 수 있습니다. 이럴 때 사용하는 것이 페이징 처리입니다.

 

9.3.2.1. 페이징 처리 방법

MyBatis에서는 페이징 처리를 위해 RowBounds 클래스를 제공합니다. RowBounds를 사용하면 몇 번째 레코드부터 몇 개의 레코드를 가져올지를 지정할 수 있습니다.

 

다음은 RowBounds를 사용하여 페이징 처리를 하는 코드의 예입니다.

 

[예제]

int offset = 0; // 시작 위치
int limit = 10; // 가져올 레코드의 개수
RowBounds rowBounds = new RowBounds(offset, limit);
List<Member> members = sqlSession.selectList("selectAllMembers", null, rowBounds);


9.3.2.2. 페이징 처리 예제

이제 회원 목록을 페이징 처리하여 가져오는 메서드를 만들어 봅시다.

 

[예제]

public List<Member> getMembers(int page, int pageSize) {
    int offset = (page - 1) * pageSize;
    RowBounds rowBounds = new RowBounds(offset, pageSize);
    return sqlSession.selectList("selectAllMembers", null, rowBounds);
}


이 메서드는 페이지 번호와 페이지 크기를 인수로 받아 해당 페이지의 회원 목록을 반환합니다. 사용자는 원하는 페이지의 데이터만 요청하여 효율적으로 데이터를 조회할 수 있습니다.

 

9.3.3. 배치 작업 실습

배치 작업은 대량의 데이터를 한 번에 처리하는 작업을 말합니다. MyBatis에서는 SqlSession의 commit() 메서드를 사용하여 여러 개의 SQL 작업을 한 번에 실행할 수 있습니다.

 

9.3.3.1. 배치 작업 방법

배치 작업을 수행하는 기본적인 방법은 다음과 같습니다.

 

[예제]

sqlSession.insert("insertMember", member1);
sqlSession.insert("insertMember", member2);
sqlSession.insert("insertMember", member3);
sqlSession.commit(); // 여기서 모든 삽입 작업이 한 번에 실행됩니다.


9.3.3.2. 배치 작업 예제

이제 여러 명의 회원을 한 번에 등록하는 메서드를 만들어 봅시다.

 

[예제]

public void registerMembers(List<Member> members) {
    for (Member member : members) {
        sqlSession.insert("insertMember", member);
    }
    sqlSession.commit();
}

 

이 메서드는 회원 객체의 리스트를 인수로 받아 한 번의 DB 작업으로 모든 회원을 등록합니다.

 

 

 

2023.05.16 - [GD's IT Lectures : 기초부터 시리즈/마이바티스(MyBatis) 기초부터 ~] - [마이바티스(MyBatis)] 마이바티스와 스프링 연동

 

[마이바티스(MyBatis)] 마이바티스와 스프링 연동

Chapter 8. 마이바티스와 스프링 연동 마이바티스는 스프링 프레임워크와 잘 연동되며, 이를 통해 개발의 편의성과 유연성을 향상할 수 있습니다. 이 장에서는 마이바티스와 스프링의 연동 방법에

gdngy.tistory.com

 

반응형

댓글