[Day 27 | Spring] MyBatis - 실습 코드

y♡ding·2024년 11월 19일

데브코스 TIL - Spring

목록 보기
22/46

Spring Boot와 MyBatis 사용 개요

MyBatis는 SQL과 Java 객체 간 매핑을 제공하는 프레임워크입니다. SQL 쿼리를 XML 또는 어노테이션으로 관리하며, 개발자는 SQL 쿼리를 더 명시적으로 제어할 수 있습니다. Spring Boot와 MyBatis를 사용하여 데이터베이스 작업을 간소화하고 유지 보수성을 높일 수 있습니다.


1. MyBatis의 기본 구조와 동작 원리

  1. 환경 설정

    • MyBatis를 사용하려면 application.properties 파일에서 데이터 소스를 정의합니다.
    • MyBatis 의존성을 추가하고, SQL 매퍼 파일(XML)을 정의합니다.
  2. Mapper

    • SQL 쿼리문은 XML 파일(mapper.xml)에 작성합니다.
    • 쿼리 ID를 사용해 SQL문을 호출합니다.
  3. 호출

    • SqlSession 객체를 통해 매퍼 파일에 정의된 SQL 쿼리를 실행합니다.

2. 코드 설명

1) 기본 설정

Dependencies

  • Spring Boot DevTools, Lombok, MariaDB Driver, MyBatis Starter를 추가합니다.

application.properties

spring.application.name=myBatis01
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
spring.datasource.url=jdbc:mariadb://localhost:3306/mysql
spring.datasource.username=root
spring.datasource.password=exxyeon
  • driver-class-name: MariaDB 드라이버 설정.
  • url: 데이터베이스 URL.
  • usernamepassword: 데이터베이스 접근 정보.

2) SQL 실행: 단일 값 조회

Mapper (mapper.xml)

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.example.mybatis">
    <!-- 단일 값 조회 -->
    <select id="select" resultType="String">
        select now() as now
    </select>
</mapper>
  • namespace: 매퍼를 구분하는 고유 이름입니다.
  • id="select": 호출 시 사용할 SQL문 ID입니다.
  • resultType="String": 반환 데이터 타입을 정의합니다.

Java 코드

@SpringBootApplication
public class MyBatis01Application implements CommandLineRunner {

    @Autowired
    private DataSource dataSource;
    @Autowired
    private ApplicationContext ctx;

    public static void main(String[] args) {
        SpringApplication.run(MyBatis01Application.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        // MyBatis Framework 접근
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource);
        sqlSessionFactoryBean.setMapperLocations(ctx.getResource("classpath:/mapper/mapper.xml"));

        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBean.getObject();
        SqlSession sqlSession = sqlSessionFactory.openSession(true);

        String result = sqlSession.selectOne("select");
        System.out.println("현재 시간: " + result);
        sqlSession.close();
    }
}

설명

  1. SqlSessionFactoryBean 설정:
    • 데이터 소스 및 매퍼 위치를 설정합니다.
  2. SQL 호출:
    • selectOne("select")mapper.xmlid="select" 쿼리를 호출합니다.
  3. 결과 출력:
    • select now()는 현재 시간을 반환하며, 결과가 출력됩니다.

3) 단일 행 데이터 조회

Mapper

<select id="selectone1" resultType="java.util.HashMap">
    select deptno, dname, loc
    from dept
    where deptno=10
</select>

Java 코드

@Override
public void run(String... args) throws Exception {
    SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
    sqlSessionFactoryBean.setDataSource(dataSource);
    sqlSessionFactoryBean.setMapperLocations(ctx.getResource("classpath:/mapper/mapper.xml"));

    SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBean.getObject();
    SqlSession sqlSession = sqlSessionFactory.openSession(true);

    Map map = sqlSession.selectOne("selectone1");
    for (String key : map.keySet()) {
        System.out.println(key + " : " + map.get(key));
    }
    sqlSession.close();
}

설명

  1. selectOne("selectone1"):
    • mapper.xml의 쿼리를 실행합니다.
    • 결과는 Map으로 반환됩니다.
  2. map.get(key):
    • deptno, dname, loc 값을 출력합니다.

4) 여러 행 데이터 조회

Mapper

<select id="selectlist1" resultType="map">
    select deptno, dname, loc
    from dept
</select>

Java 코드

@Override
public void run(String... args) throws Exception {
    SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
    sqlSessionFactoryBean.setDataSource(dataSource);
    sqlSessionFactoryBean.setMapperLocations(ctx.getResource("classpath:/mapper/mapper.xml"));

    SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBean.getObject();
    SqlSession sqlSession = sqlSessionFactory.openSession(true);

    List<Map<String, Object>> lists = sqlSession.selectList("selectlist1");
    for (Map<String, Object> map : lists) {
        System.out.println(map.get("deptno") + "/" + map.get("dname") + "/" + map.get("loc"));
    }
    sqlSession.close();
}

5) DeptTP로 가져오기 (단일 행)

<!--    mapper2.xml-->
    <select id="selectone" resultType="org.example.mybatis.model.DeptTO" >
        select deptno, dname, loc
        from dept
        where deptno=10
    </select>
// DetpTO
@Getter
@Setter
public class DeptTO {
    private String deptno;
    private String dname;
    private String loc;
}

// main
    @Override
    public void run(String... args) throws Exception {
        // MyBatis Framework 접근
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();

        sqlSessionFactoryBean.setDataSource(dataSource);
        sqlSessionFactoryBean.setMapperLocations(ctx.getResource("classpath:/mapper/mapper2.xml"));

        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBean.getObject();
        SqlSession sqlSession = sqlSessionFactory.openSession(true);

        System.out.println(sqlSession); // org.apache.ibatis.session.defaults.DefaultSqlSession@ref

        DeptTO to = sqlSession.selectOne("selectone");
        System.out.println(to.getDeptno() + "/" + to.getDname() + "/" + to.getLoc());

        sqlSession.close();
    }
   

6) DeptTP로 가져오기 (여러 행)

    <select id="selectlist1" resultType="org.example.mybatis.model.DeptTO" >
        select deptno, dname, loc
        from dept
    </select>
        List<DeptTO> lists = sqlSession.selectList("selectlist1");
        for (DeptTO to : lists) {
            System.out.println(to.getDeptno() + "/" + to.getDname() + "/" + to.getLoc());
        }

7) 조건부 조회

Mapper

<select id="selectlist2" parameterType="String" resultType="org.example.mybatis.model.EmpTO">
    select empno, ename, job, deptno
    from emp
    where deptno = #{deptno}
</select>

Java 코드

// EmpTO
@Getter
@Setter
public class EmoTO {
    private String empno;
    private String ename;
    private String job;
    private String mgr;
    private String hiredate;
    private String sal;
    private String comm;
    private String deptno;
}
// main
        List<EmpTO> lists = sqlSession.selectList("selectlist2", 10);
        for (EmpTO to : lists) {
            System.out.println(to.getEmpno() + "/" + to.getEmpno() + "/" + to.getDeptno());
        }

        sqlSession.close();

%: where ename like #{ename}

7) 두 가지 값

    <select id="selectlist4" parameterType="org.example.mybatis.model.EmpTO" resultType="org.example.mybatis.model.EmpTO" >
        select empno, ename, job, deptno
        from emp
        where job = #{job} and deptno = #{deptno}
    </select>
    
// 메인
				EmpTO paramTO = new EmpTO();
        paramTO.setJob("SALESMAN");
        paramTO.setDeptno("30");
        List<EmpTO> lists = sqlSession.selectList("selectlist4", paramTO);
        for (EmpTO to : lists) {
            System.out.println(to.getEmpno() + "/" + to.getEname() + "/" + to.getDeptno());
        }

8) 우편 번호 검색기

 // application.properties
 spring.application.name=Zipcode02_myBatis
 
 spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
 spring.datasource.url=jdbc:mariadb://localhost:3306/sample
 spring.datasource.username=root
 spring.datasource.password=exxyeon
 
 // mapper
 <?xml version="1.0" encoding="utf-8" ?>
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
 <mapper namespace="org.example.mybatis">
     <select id="select" parameterType="String" resultType="org.example.zipcode02.model.ZipcodeTO" >
         select zipcode, sido, gugun, dong, ri, bunji
         from zipcode
         where dong like #{dong}
     </select>
 </mapper>
 
 // ZipcodeTO
 @Getter
 @Setter
 public class ZipcodeTO {
     private String zipcode;
     private String sido;
     private String gugun;
     private String dong;
     private String ri;
     private String bunji;
 }
 
 // main
 @SpringBootApplication
 public class Zipcode02MyBatisApplication implements CommandLineRunner {
 
     @Autowired
     private DataSource dataSource;
     @Autowired
     private ApplicationContext ctx;
 
     public static void main(String[] args) {
         SpringApplication.run(Zipcode02MyBatisApplication.class, args);
     }
 
     @Override
     public void run(String... args) throws Exception {
         SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
 
         sqlSessionFactoryBean.setDataSource(dataSource);
         sqlSessionFactoryBean.setMapperLocations(ctx.getResource("classpath:/mapper/mapper.xml"));
 
         SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBean.getObject();
         SqlSession sqlSession = sqlSessionFactory.openSession(true);
 
         List<ZipcodeTO> lists = sqlSession.selectList("select", "신사");
         for (ZipcodeTO to : lists) {
             System.out.printf("[%s] %s %s %s %s %s %n",
                     to.getZipcode(), to.getSido(), to.getGugun(), to.getDong(), to.getRi(), to.getBunji());
         }
         sqlSession.close();
     }
 }

정리

  1. MyBatis 사용 시 장점:

    • SQL문 관리가 용이(XML 분리).
    • 자동 매핑 지원(객체로 데이터 변환).
  2. 활용 상황:

    • 데이터베이스와의 통신을 효율적으로 관리.
    • 조건에 따라 유연하게 데이터 조회.

0개의 댓글