본문 바로가기
Back-End/Spring Boot

Spring Boot - MyBatis 쿼리 Xml, DAO생성

by 코젼 2022. 7. 25.
728x90
반응형

2022-07-25(26일차)


2022.07.25 - [Back-End/Spring Boot] - Spring - MyBatis VO 작업

💁‍♀️ 이전 글과 이어집니다. 이전 글을 참고해주세요!

 

Spring - MyBatis VO 작업

💡MyBatis 관련 라이브러리 추가 💁‍♀️MyBatis 추가 🔸Maven 프로젝트 MyBatis 추가 ▪️ pom.xml에 디펜던시 추가 org.mybatis.spring.boot mybatis-spring-boot-starter 2.2.2 ​ ▪️ pom.xml 선택 후 마..

cojyeon.tistory.com


💡Query Xml 경로 생성

▪️ mybatis 경로가 루트 경로의 mybatis/mapper 이하로 되어있기 때문에, mybatis.mapper 패키지를 만든다.

추가된 것을 확인할 수 있다.


💡repository - dao역할

▪️ com.shop.controller
▪️ com.shop.dto
▪️ com.shop.entitiy
▪️ com.shop.repository
▪️ com.shop.service
▪️ com.shop.vo

업무별로 나누기 (패키지 생성)


💡dao, 쿼리 Xml 생성

▪️ com.shop.dao 패키지 안에 ISampleDAO.java dao를 생성한다.


▪️ com.shop.dao 패키지 하단에 ISampleDAO.xml 쿼리를 생성한다.
▪️ 하단 사진에 com.shop.dao로 쿼리를 생성하였는데, 이는 경로가 잘못되었다.
▪️ src/main/resource/mybatis/mapper 경로 안에 ISampleDAO.xml을 생성한다.

▪️ 동일한 이름으로 되어있으면 추후에 찾기 쉽다.


 

▪️ 쿼리의 각각마다 id를 부여할 것이고 이 파일 안에서 id는 유일해야 한다.
▪️ id값은 유일하게 값을 붙여주는 이름이고 result타입은 결과를 돌려준다.

▪️ 매개변수가 한 개가 아니라 여러개이면 콤마로 구분해서 사용하면 된다.

▪️ 클래스로 지정하고 파라미터를 클래스로 받는다.
▪️ parameter이름을 key값으로 HashMap에서 키로 불러다 사용하면 된다.
▪️ 파라미터를 해시맵으로 사용하는 것이 효율적아다
 --> 참인 경우는 1 그 외는 0

🔸Primitive type
▪️ resultType이 Primitive type(원시타입)이면 언더바를 붙인다. (ex. _int)
▪️ _int와 int와 다르다.
별칭은 string이고 데이터 형태는 String이다. 구분을 해야 한다. 실수 안하도록 주의


▪️ xml파일과 연결되는 dao파일이다.
▪️ dao파일을 만들어놓고도 자동으로 getter, setter를 만들기 위해 lombok에게 보내고 어노테이션을 붙인다.

▪️ dao는 인터페이스를 만든다.
▪️ 구체적인 것은 개발자가 지정하지 않고 무엇을 사용할 건지만 정의하기 위해 인터페이스를 정의한다.
▪️ xml파일과 연결이 되어야 한다 --> @Mapper

▪️ @Mapper라고 적어놓으면 xml쿼리하고 묶이는 것이고 bean인 것을 알 수 있다.

▪️ ISampleDAO.xml파일의 id는 ISampleDAO.java파일의 articleCount()함수 이름을 이용한다.

▪️ 함수이름이 id값이랑 같은 이름이다.

▪️ 쿼리를 준비하고 쿼리를 호출한다.
▪️ 디렉터리를 만들어서 각각의 sql문을 정의하였다.
▪️ 인터페이스로 필요한 것을 불러온다.

📃ISampleDAO.java

package com.shop.dao;

import java.util.List;
import java.util.Map;

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import com.shop.vo.SampleVO;

@Mapper
public interface ISampleDAO {
	public List<SampleVO> listDao();
    public SampleVO viewDao(String id);
    public int writeDao(Map<String, String> map); // 가장 흔한 타입
    public int deleteDao(@Param("_id") String id); // Parameter의 값을 직접 넘겨줄 것이다.
    public int articleCount();
}

📃ISampleDAO.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="com.shop.dao.ISampleDAO"> 
    
    <select id="listDao" resultType="com.shop.vo.SampleVO">
        select * from member order by id desc
    </select>

    <select id="viewDao" resultType="com.shop.vo.SampleVO">
        select * from member where id = #{0}
    </select>

    <insert id="writeDao" parameterType="java.util.HashMap">
        insert into member (id, writer, title, content)
             values (sample_seq.nextval, #{item1}, #{item2}, #{item3})
    </insert>

    <delete id="deleteDao">
        delete from member where id = #{_id}
    </delete>
    
    <select id="articleCount" resultType="_int">
        select count(*) from member
    </select>
    
</mapper>

 

▪️ 쿼리 파일에서는 resultType를 맞춰준다.
▪️ 작동시킬 때는 interface이름이 같고 namespace의 경로가 틀리면 안되는 것이 가장 중요하다.
▪️ Dao에서는 내가 보고자하는 아이디와 똑같이 매치를 해야한다.

▪️ dao는 인터페이스이다.
▪️ 인터페이스는 본체없이 이름만 있기 때문에 new로 생성할 수 없다.
그러나 new가 안되는 인터페이스는 스프링이 자동으로 만들어두었기 때문에 사용할 수 있다.
▪️ 스프링에게 dao를 요청하면 된다.
 --> 따라서 개발자가 new를 할 필요가 없다.

▪️ controller쪽은 주소를 받아서 사용자가 입력한 것이 있다면 그것을 service에게 넘긴다.
▪️ 주소 요청을 받기만 받고 사용자가 아무것도 안 넣었다면 안 넣은대로, 입력했다면 입력한 것을 service에게 넘긴다.
▪️ 서버에서 controller에게 다시 주고, 결과를 page로 넘겨준다.

💡호출

▪️ 컨트롤러에서 dao를 호출하려면, 스프링에게 @AutoWired를 사용한다.
▪️ 자바가 스프링에게 dao를 만든것을 요청한다.
@AutoWired를 붙여서 new를 하지 않고 스프링이 만들어준 ISampleDAO를 sampleDao변수 안에 넣어달라고 요청한다.
호출해서 사용해야하기 때문에 MyBatis에서 가장 중요한 작업이다.
@Autowired
ISampleDAO sampleDao;

사용할 수 있는 함수가 여러가지 있다.

▪️ ISampleDAO에서 sampleDao를 만들어 articleCount()함수에 접근하여 개수가 몇 개인지 센다.


💡더 나아가, 타임리프 예제를 수정해봅시다.

📃TyhmeleafExController.java

	@Autowired
	ISampleDAO sampleDao;
	
    @GetMapping(value = "/ex01")
    public String thymeleafExample01(Model model){
        model.addAttribute("data", "타임리프 예제 입니다. Count : [" + sampleDao.articleCount() + "]");
        return "thymeleafEx/thymeleafEx01";
    }

    @GetMapping(value = "/ex02")
    public String thymeleafExample02(Model model){
        ItemDto itemDto = new ItemDto();
        itemDto.setItemDetail(""+sampleDao.viewDao("1").getEmail()); 
        itemDto.setItemNm(""+sampleDao.viewDao("1").getName()); //멤버테이블의 이름같은 정보를 보여주기
        itemDto.setPrice(10000);
        itemDto.setRegTime(LocalDateTime.now());

        model.addAttribute("itemDto", itemDto);
        return "thymeleafEx/thymeleafEx02";
    }

📃ISampleDAO.xml

    <select id="listDao" resultType="com.shop.vo.SampleVO">
        select * from member order by member_id desc
    </select>

    <select id="viewDao" resultType="com.shop.vo.SampleVO">
        select * from member where member_id = #{0}
    </select>

📃Console


📃SampleVO.java

▪️ 버전이 안 맞아서 웹페이지에 null값이 나오면 하단 소스코드처럼 수정해야 합니다.

package com.shop.vo;

import java.math.BigInteger;
import java.sql.Timestamp;

import lombok.Data;

@Data
public class SampleVO {
    private BigInteger member_id;
    private String name;
    private String email;
    private String password;
    private String address;
    private String role;
    private Timestamp reg_time;
    private Timestamp update_time;
    private String create_by;
    private String modified_by;
}

💡listDao() 함수 사용하기

▪️ SampleVO의 리스트 형태로 추출한다.
sampleDao.listDao();​

▪️ sampleDao의 리스트로 하면 리스트의  SampleVO라는 형태로 리스트 형태를 result에 저장한다.
List<SampleVO> result = sampleDao.listDao();​

 

▪️ 리스트 사용

    	
    	List<SampleVO> result = sampleDao.listDao();
    	SampleVO objVo = result.get(0); // 0번째 인덱스 값을 호출한다.
    	
    	
        ItemDto itemDto = new ItemDto();
        
        itemDto.setItemDetail(""+ objVo.getEmail());
        itemDto.setItemNm(""+ objVo.getName());
//        itemDto.setPrice(objVo.getMember_id()); // Long이 아니라 BigInteger로 해놓으면 오류나기 때문에 int형으로 전환해야한다.
        itemDto.setPrice(objVo.getMember_id().intValue()); // int형으로 바꾼다.


▪️ 데이터가 null일 수도 있기 때문에 조건문을 사용한다.

    	if(result.size()>0) { // 만약 리스트가 null이 아니라면
    		objVo = result.get(0); // 0번째 인덱스 값을 호출한다.
    	}
BigInteger memId = objVo.getMember_id();

        // getMember_id값이 null이면 0을 반환하고 아니라면 그 id값을 반환한다.
        itemDto.setPrice((memId==null?0:memId).intValue()); // int형으로 바꾼다.

▪️ 하드코딩 방지

        // getMember_id값이 null이면 0을 반환하고 아니라면 그 id값을 반환한다.
        itemDto.setPrice((objVo.getMember_id()==null?0:objVo.getMember_id()).intValue()); // int형으로 바꾼다.

💡viewDao() 함수 사용하기

 

        itemDto.setItemDetail(""+sampleDao.viewDao("1").getEmail()); 
        itemDto.setItemNm(""+sampleDao.viewDao("1").getName()); //멤버테이블의 이름같은 정보를 보여주기

 

 


💡전체 코드

📃ThymeleafExController.java

package com.shop.controller;

import java.math.BigInteger;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;

import com.shop.dao.ISampleDAO;
import com.shop.dto.ItemDto;
import com.shop.vo.SampleVO;

@Controller
@RequestMapping(value = "/thymeleaf")
public class ThymeleafExController {

	@Autowired
	ISampleDAO sampleDao;

	@GetMapping(value = "/ex01")
	public String thymeleafExample01(Model model) {
		model.addAttribute("data", "타임리프 예제 입니다. Count : [" + sampleDao.articleCount() + "]");
		return "thymeleafEx/thymeleafEx01";
	}

	@GetMapping(value = "/ex02")
	public String thymeleafExample02(Model model) {

		List<SampleVO> result = sampleDao.listDao();
		SampleVO objVo = new SampleVO();

		if (result.size() > 0) { // 만약 리스트가 null이 아니라면
			objVo = result.get(0); // 0번째 인덱스 값을 호출한다.
		}

		ItemDto itemDto = new ItemDto();

		itemDto.setItemDetail("" + objVo.getEmail());
		itemDto.setItemNm("" + objVo.getName());

//        itemDto.setItemDetail(""+sampleDao.viewDao("1").getEmail()); 
//        itemDto.setItemNm(""+sampleDao.viewDao("1").getName()); //멤버테이블의 이름같은 정보를 보여주기

		BigInteger memId = objVo.getMember_id();

//        itemDto.setPrice(objVo.getMember_id()); // Long이 아니라 BigInteger로 해놓으면 오류나기 때문에 int형으로 전환해야한다.

		// getMember_id값이 null이면 0을 반환하고 아니라면 그 id값을 반환한다.
		itemDto.setPrice((memId == null ? 0 : memId).intValue()); // int형으로 바꾼다.
		itemDto.setRegTime(LocalDateTime.now());

		model.addAttribute("itemDto", itemDto);
		return "thymeleafEx/thymeleafEx02";
	}

	@GetMapping(value = "/ex03")
	public String thymeleafExample03(Model model) {

		List<ItemDto> itemDtoList = new ArrayList<>();

		for (int i = 1; i <= 10; i++) {

			ItemDto itemDto = new ItemDto();
			itemDto.setItemDetail("상품 상세 설명" + i);
			itemDto.setItemNm("테스트 상품" + i);
			itemDto.setPrice(1000 * i);
			itemDto.setRegTime(LocalDateTime.now());

			itemDtoList.add(itemDto);
		}

		model.addAttribute("itemDtoList", itemDtoList);
		return "thymeleafEx/thymeleafEx03";
	}

	@GetMapping(value = "/ex04")
	public String thymeleafExample04(Model model) {

		List<ItemDto> itemDtoList = new ArrayList<>();

		for (int i = 1; i <= 10; i++) {

			ItemDto itemDto = new ItemDto();
			itemDto.setItemDetail("상품 상세 설명" + i);
			itemDto.setItemNm("테스트 상품" + i);
			itemDto.setPrice(1000 * i);
			itemDto.setRegTime(LocalDateTime.now());

			itemDtoList.add(itemDto);
		}

		model.addAttribute("itemDtoList", itemDtoList);
		return "thymeleafEx/thymeleafEx04";
	}

	@GetMapping(value = "/ex05")
	public String thymeleafExample05() {
		return "thymeleafEx/thymeleafEx05";
	}

	@GetMapping(value = "/ex06")
	public String thymeleafExample06(String param1, String param2, Model model) {
		model.addAttribute("param1", param1);
		model.addAttribute("param2", param2);
		return "thymeleafEx/thymeleafEx06";
	}

	@GetMapping(value = "/ex07")
	public String thymeleafExample07() {
		return "thymeleafEx/thymeleafEx07";
	}

}

📃ISampleDAO.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="com.shop.dao.ISampleDAO"> 
    
    <select id="listDao" resultType="com.shop.vo.SampleVO">
        select * from member order by member_id desc
    </select>

    <select id="viewDao" resultType="com.shop.vo.SampleVO">
        select * from member where member_id = #{0}
    </select>

    <insert id="writeDao" parameterType="java.util.HashMap">
        insert into member (id, writer, title, content)
             values (sample_seq.nextval, #{item1}, #{item2}, #{item3})
    </insert>

    <delete id="deleteDao">
        delete from member where id = #{_id}
    </delete>
    
    <select id="articleCount" resultType="_int">
        select count(*) from member
    </select>
    
</mapper>

 

728x90
반응형

'Back-End > Spring Boot' 카테고리의 다른 글

Spring Boot - JPA 지연 로딩  (0) 2022.07.25
Spring Boot - javax.validation 어노테이션 예시  (0) 2022.07.25
Spring - MyBatis VO 작업  (0) 2022.07.25
Spring - Thymeleaf 레이아웃  (0) 2022.07.25
Spring Boot - MyBatis 추가  (0) 2022.07.22

댓글