파게로그

[Persistence Framework] MyBatis를 통한 DAO 인터페이스의 구현 본문

콤퓨타 왕기초/Spring Boot

[Persistence Framework] MyBatis를 통한 DAO 인터페이스의 구현

파게 2021. 5. 10. 19:43

Controller, Service, DAO

com.ddoongi.web.controller.EmpController

@Controller("adminEmpController")
@RequestMapping("/admin/emp/")
public class EmpController {
    
    @Autowired
    private EmpService service;
    
    @GetMapping("list")
    public String list() {
        List<Emp> list = service.getEmpList();
        return "admin/emp/list";
    }
}

 

차근차근 생각해보자. URL을 통해 request가 들어오면, 일단 Controller가 이 request를 적절한 Service에 전달해야 하고, Service는 자신이 가지고 있는 비즈니스 로직을 이용하여 해당 request를 처리해서 반환해주면 된다. 데이터를 가져오는 건 DAO가 하고, 여러 DAO의 기능이 종합적으로 사용될 필요가 있으면 그것을 Service가 담당하는 것이다. 이 과정에서 DB에의 접근이 필요할 때, DAO를 사용한다.

일련의 과정이 성공적으로 이루어지기 위해 Controller는 Service 객체를, Service는 DAO 객체를 필드 변수로 가진다. 위 코드에서 구현되어야 할 것은 다음 2개의 클래스이다.

 

com.ddoongi.web.entity.Emp

com.ddoongi.web.service.EmpService

 

여기서 Service는 인터페이스로서, 이를 구현하는 클래스는 별개로 존재할 것이다.

 

public interface EmpService {
    List<Emp> getList();
}

 

위 Service 인터페이스를 구현하는 클래스는 아래와 같다.

 

com.ddoongi.web.service.EmpServiceImpl

public class EmpServiceImpl implements EmpService {

    @Autowired
    private EmpDao empDao;

    @Override
    public List<Emp> getEmpList() {
    	List<Emp> list = empDao.getEmpList();
        return list;
    }
    
}

 

위에서 알 수 있듯이, Service의 구현체는 DAO 객체를 필드 변수로 가진다. DAO 객체 또한 인터페이스부터 만들어주어 구현체가 바뀌더라도 쉽게 갈아끼울 수 있도록 한다.

 

com.ddoongi.web.dao.EmpDao

public interface EmpDao {
    List<Emp> getList();
}

 

이제 이 DAO 인터페이스를 구현하는 클래스를 만들어야 하는데, MyBatis를 사용하면, 이 DAO의 구현체를 직접 만들 필요가 없다.

 

MyBatis를 사용하여 DAO 구현

MyBatis Framework와 MySQL Driver를 Maven dependencies에 추가한다.

 

com.ddoongi.web.dao.EmpDao

public interface EmpDao {
    List<Emp> getList();
}

 

위와 같은 인터페이스를 구현할 새로운 클래스를 만드는 것이 아니라, 인터페이스 자체를 아래와 같이 수정한다.

 

@Mapper
public interface EmpDao {
    @Select("SELECT * FROM emp")
    List<Emp> getList();
}

 

1라인에서, 매핑된 것이 있다는 사실을 알리는 annotation을 달아준다(@Mapper가 Spring annotation처럼 객체 생성, 그리고 이를 IoC Container에 담는 과정까지도 담당한다).

3라인에서, 해당 메서드가 구현해야 하는 SQL문을 annotation으로 달아줌으로써 직접 구현하는 수고로움을 피할 수 있다(일부 메서드는 달아주고, 일부는 안 달아주고 하는 것도 가능하다).

 

com.ddoongi.web.entity.Emp

public class Emp {
    private int empno;
    private String ename;
    private Date hiredate;
    private int sal;
    private int deptno;
    
    public Emp(int empno, String ename, Date hiredate, int sal, int deptno) {
        this.empno = empno;
        this.ename = ename;
        this.hiredate = hiredate;
        this.sal = sal;
        this.deptno = deptno;
    }
    
    // getter and setters
    // ...
    
    @Override
    public String toString() {
        return "...";
    }
}

 

 

MySQL은 서버 타임존 설정이 필요하다.

- JDBC 드라이버 사용할 때 연결 문자열에서 지정 (application단에서 지정하는 걸 당연히 권장)

   spring.datasource.url=jdbc:mysql://localhost:3306/ddoongi?serverTimezone=Asia/Seoul

- 서버에서 지정 (권장x)

 

 

만약 뷰를 생성한다면?

@Mapper
public interface EmpDao {
    @Select("SELECT * FROM emp")
    List<EmpView> getList(); // T는 Emp가 아니라 EmpView이다
}

 

com.ddoongi.web.entity - EmpView.java

 

public class EmpView extends Emp {
    
    private String deptname;
    
    public EmpView() {
    }
    
    public EmpView(int empno, String ename, Date hiredate, int sal, int deptno, String deptname) {
        super(empno, ename, hiredate, sal, deptno, deptname);
        this.deptname = deptname; // 추가된 attribute
    }
    
    // getter and setters...
    // toString()
}

 

 

 

조심

jjunii486.tistory.com/114

Comments