myBatis - 2. 실습 전체 목록 조회(xml형식)

만약 라이브러리 추가안하신분들은 1편보고오세요!

 

우선적으로 mybatis-config.xml 먼저 설정하겠습니다.

 

생성되는 위치는 아래와같습니다

프로젝트 - config - mybatis-config.xml

주의사항으로는 Source Folder로 폴더설정해줘야합니다.

 

mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
  <environments default="dev">
    <environment id="dev">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED">
        <property name="driver" value="oracle.jdbc.driver.OracleDriver"/>
        <property name="url" value="jdbc:oracle:this:@localhost:1521:xe"/>
        <property name="username" value="mybatis"/>
        <property name="password" value="mybatis"/>
      </dataSource>
    </environment>
  </environments>
  <!-- <mappers>
    <mapper resource="org/mybatis/example/BlogMapper.xml"/>
  </mappers> -->
</configuration>

 

기본적으로 위의 구조라고 생각하면된다.

수동적으로 commit할것이고 Connection 연결해서 사용한다는 설정입니다.

 

위의 설정을 가지고 테이블에서 목록을 전체조회하도록하겠습니다.

현재저장된 db내용은 아래와같습니다.

 

우선 Menu vo 작성

package com.memory.batis.model.vo;

public class Menu {
	/*
	 * 	MENU_CODE	NUMBER
		MENU_NAME	VARCHAR2(30 BYTE)
		MENU_PRICE	NUMBER
		CATEGORY_CODE	NUMBER
		ORDERABLE_STATUS	CHAR(1 BYTE)
	 * */
	private int code;
	private String name;
	private int price;
	private int categoryCode;
	private String orderableStatus;
	
	public Menu() {
		super();
	}

	public Menu(int code, String name, int price, int categoryCode, String orderableStatus) {
		super();
		this.code = code;
		this.name = name;
		this.price = price;
		this.categoryCode = categoryCode;
		this.orderableStatus = orderableStatus;
	}

	public int getCode() {
		return code;
	}

	public void setCode(int code) {
		this.code = code;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getPrice() {
		return price;
	}

	public void setPrice(int price) {
		this.price = price;
	}

	public int getCategoryCode() {
		return categoryCode;
	}

	public void setCategoryCode(int categoryCode) {
		this.categoryCode = categoryCode;
	}

	public String getOrderableStatus() {
		return orderableStatus;
	}

	public void setOrderableStatus(String orderableStatus) {
		this.orderableStatus = orderableStatus;
	}

	@Override
	public String toString() {
		return "Menu [code=" + code + ", name=" + name + ", price=" + price + ", categoryCode=" + categoryCode
				+ ", orderableStatus=" + orderableStatus + "]";
	}
	
}

 

mybatis를 공통적으로 관리하기위해 만든 Templete.class 생성

package com.memory.batis.common;

import java.io.IOException;
import java.io.InputStream;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class Templete {
	private static SqlSessionFactory sqlSessionFactory;
	
	public static SqlSession getSqlSession() {
		
		if(sqlSessionFactory == null) {
			// 우선 xml의 위치를 저장
			String resource = "mybatis-config.xml";
			
			try {
				InputStream inputStream = Resources.getResourceAsStream(resource);
				sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
				
			} catch (IOException e) {
				e.printStackTrace();
			}
			
		}
		
		SqlSession sqlSession = sqlSessionFactory.openSession(false);
		
		return sqlSession;
	}
}

 

메인 실행 클래스

package com.memory.batis.run;

import java.util.Scanner;

import com.memory.batis.controller.MenuController;

public class Application {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		MenuController menuController = new MenuController();
		
		do {
			System.out.println("================ 메뉴 관련 ================");
			System.out.println("1. 메뉴 전체 조회");
			System.out.println("2. 메뉴 코드로 메뉴 조회");
			System.out.println("3. 신규 메뉴 추가");
			System.out.println("4. 메뉴 수정");
			System.out.println("5. 메뉴 삭제");
			System.out.println("메뉴 관리 번호를 입력하세요 : ");
			int no = sc.nextInt();
			
			switch(no) {
				case 1 : menuController.selectAllMenu(); break;
				default : System.out.println("잘못된 메뉴를 선택하셨습니다."); break;
			}
			
		}while(true);
	}
}

실행하고 번호를 입력하면 메소드 실행되도록 설정

현재는 메뉴전체조회만 구현하여서 1번만선택되도록 설정하였습니다.

 

cotroller.MenuController.class

 

MenuService의 selectAllMenu 메소드 호출시 반환값은 null 또한 List형식으로 반환하도록하였다.

package com.memory.batis.controller;

import java.util.List;

import com.memory.batis.model.service.MenuService;
import com.memory.batis.model.vo.Menu;
import com.memory.batis.view.ResultPrint;

public class MenuController {
	private MenuService menuService = new MenuService();
	private ResultPrint resultPrint = new ResultPrint();
	
	// 메뉴 전체 조회
	public void selectAllMenu() {
		List<Menu> menuList = menuService.selectAllMenu();
		
		if(menuList != null) {
			resultPrint.succesPrint(menuList);
		}else{
			resultPrint.failPrint("selectAllMenu");
		}
		
	}

}

 

화면에 표시하기위한 view

ResultPrint.class

 

만약 List값이 null이면 failPrint 메소드 실행하고

List의 값이 null이 아니면 List목록을 하나씩 출력한다는 의미이다.

package com.memory.batis.view;

import java.util.List;

import com.memory.batis.model.vo.Menu;

public class ResultPrint {
	
	
	public void succesPrint(List<Menu> menuList) {
		for(Menu menu : menuList) {
			System.out.println(menu);
		}
	}
	
	public void failPrint(String errorMsg) {
		switch(errorMsg) {
			case "selectAllMenu" : System.out.println("메뉴 전체 조회를 실패하였습니다."); break;
		}
	}
	
}

 

MenuService.class

MenuDao에 sqlSession 커넥션을 매개변수로 같이 전달해 List컬렉션으로 반환받는다.

항상 커넥션후 close() 이용하여 객체 반납해줘야함

조회이기떄문에 commit, rollback은 사용하지 않았다.

package com.memory.batis.model.service;

import java.util.List;

import org.apache.ibatis.session.SqlSession;

import com.memory.batis.model.dao.MenuDao;
import com.memory.batis.model.vo.Menu;

import static com.memory.batis.common.Templete.*;

public class MenuService {

	private MenuDao menuDao = new MenuDao();
	
	// 메뉴 전체 조회
	public List<Menu> selectAllMenu() {
		
		SqlSession sqlSession = getSqlSession();
		
		List<Menu> menuList = menuDao.selectAllMenu(sqlSession);
		
		sqlSession.close();
		
		return menuList;
	}

}

 

MenuDao.class

 

원래 mybatis를 이용하지않았을시

ResultSet, PreparedStatement, 등 이용하여

반복문으로 ResultSet 값을 next()로 확인하여 ..List에 담는방식을사용하였는데 ..

mybatis사용후 어떤 sql을 사용할지만 알려준다면 자동적으로 List로 반환한다.

package com.memory.batis.model.dao;

import java.util.List;

import org.apache.ibatis.session.SqlSession;

import com.memory.batis.model.vo.Menu;

public class MenuDao {
	
	// 메뉴 전체 조회
	public List<Menu> selectAllMenu(SqlSession sqlSession) {
		
		return sqlSession.selectList("menu-mapper.menuSelectAll");
	}

}

반환값이 List<Menu> 로 지정되어있는것을 확인할수있음

 

왜이렇게 됐는지 하면 

mapper/menu-mapper.xml에 가이드라인을 제시해줘서 mybatis가 알아서 다 해준것을확인할수있다.

 

쿼리문에 사용한 xml입니다.

여기서 select 태그이용하여 전체값을 조회하였습니다.

만약 컬럼값과 vo의 변수값이 동일하다면 resultMap을 사용하지않아도되지만

 

<?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="menu-mapper">
 <resultMap id="menuResultMap" type="com.memory.batis.model.vo.Menu">
 	<id property="code" column="MENU_CODE"/>
 	<result property="name" column="MENU_NAME"/>
 	<result property="price" column="MENU_PRICE"/>
 	<result property="categoryCode" column="CATEGORY_CODE"/>
 	<result property="orderableStatus" column="ORDERABLE_STATUS"/>
 </resultMap>
  <select id="menuSelectAll" resultMap="menuResultMap">
    	SELECT
    		   MENU_CODE
    		 , MENU_NAME
    		 , MENU_PRICE
    		 , CATEGORY_CODE
    		 , ORDERABLE_STATUS
    	  FROM TBL_MENU
    	 WHERE ORDERABLE_STATUS = 'Y'
      ORDER BY MENU_CODE
  </select>
</mapper>

 

여기 3개의 이름이 컬럼값과 달라서 가이드라인을 제시해줘야합니다.

<id> 태그는 고유의 컬럼을 설정해주면됩니다.

그후 result 태그에 작성하면되지만

propertis는 vo의 변수값 column는 컬럼의 이름을 작성해주면됩니다.

 

mybatis가 처음 사용할때는 좀더어려운느낌이들기도하고 그러지만

좀만 능숙하게 다룰수 있게 된다면 시간도 완전히 줄일수 있다고 판단합니다

실무에서 많이 사용되는 이유가 있을거같습니다.

 

 

실행화면입니다.

 

 

-------------------------------------------------------------------------------------------------------------------------------

2. 메뉴코드로  메뉴 조회

메뉴코드 번호입력시 하나만 조회하는 기능을 구현해보겠습니다.

아래보이는 MENU_CODE 컬럼의 값으로 조회하는기능입니다.

 

 

Application.class

우선 2번을 입력하게되면 

메뉴코드를 입력하라는 텍스트가출력되고 메뉴코드를입력하면 컨트롤러로 번호가 전달됩니다.

package com.memory.batis.run;

import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

import com.memory.batis.controller.MenuController;

public class Application {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		MenuController menuController = new MenuController();
		
		do {
			System.out.println("================ 메뉴 관련 ================");
			System.out.println("1. 메뉴 전체 조회");
			System.out.println("2. 메뉴 코드로 메뉴 조회");
			System.out.println("3. 신규 메뉴 추가");
			System.out.println("4. 메뉴 수정");
			System.out.println("5. 메뉴 삭제");
			System.out.println("메뉴 관리 번호를 입력하세요 : ");
			int no = sc.nextInt();
			
			switch(no) {
				case 1 : menuController.selectAllMenu(); break;
				case 2 : menuController.selectMenu(inputMenu()); break;
				default : System.out.println("잘못된 메뉴를 선택하셨습니다."); break;
			}
			
		}while(true);
	}
	
	// 메뉴코드 번호 받아오기
	private static Map<String, String> inputMenu(){
		Scanner sc = new Scanner(System.in);
		
		System.out.print("조회하실 메뉴코드를 입력해주세요 : ");
		String code = sc.nextLine();
		
		Map<String, String> parameter = new HashMap<>();
		parameter.put("code", code);
		
		return parameter;
	}
}

 

MenuController.class

받은 매개변수 값을 code에 정수형으로 저장하고 

서비스 클래스에 입력받은번호를 한번더 매개변수값으로보내고

최종 전달받아야할 반환타입은 Menu객체입니다.

 

그후 menu가 null이 아닐시성공 메시지출력하고

menu가 null일시 조회에 실패하였다는 메세지를 출력하게됩니다. 

// 메뉴코드로 메뉴조회
	public void selectMenu(Map<String, String> parameter) {
		int code = Integer.parseInt(parameter.get("code"));
		
		Menu menu = menuService.selectMenu(code);
		
		if(menu != null) {
			resultPrint.menuPrint(menu);
		}else{
			resultPrint.failPrint("selectMenu");
		}
		
	}

 

MenuService.class

SqlSession 객체를 생성해주고

Dao클래스로 방금 생성한 SqlSession 객체와 code값을 매개변수로 연결합니다 .

항상 작업이끝난후 SqlSession값은 close()하여 닫아줘야합니다.

// 메뉴코드로 메뉴조회
	public Menu selectMenu(int code) {
		SqlSession sqlSession = getSqlSession();
		
		Menu menu = menuDao.selectMenu(sqlSession, code);
		
		sqlSession.close();
		
		return menu;
	}

 

MenuDao.class

전달받은 객체와 code 값을이용해

menu-mapper.xml에 id값이 selectMenu랑 연결하여

쿼리구문을 실행합니다.

// 메뉴코드로 메뉴조회
	public Menu selectMenu(SqlSession sqlSession, int code) {
		return sqlSession.selectOne("menu-mapper.selectMenu", code);
	}

 

menu-mapper.xml

parameterType는 안적어줘도되지만 전달받은 파라미터 타입이 int형이라는것을 알려줍니다.

그리고 resultMap으로 어디 변수에 어떤컬럼의값을넣어야하는지 알려줍니다.

<select id="selectMenu" parameterType="_int" resultMap="menuResultMap">
  	SELECT
   		   MENU_CODE
   		 , MENU_NAME
   		 , MENU_PRICE
   		 , CATEGORY_CODE
   		 , ORDERABLE_STATUS
   	  FROM TBL_MENU
   	 WHERE ORDERABLE_STATUS = 'Y'
   	   AND MENU_CODE = #{code}
  </select>

 

완성이미지

 

 

3. 신규 메뉴 추가

처음에 추가할 메뉴명, 가격, 카테고리 코드를 입력받아 매개변수값으로 보내

INSERT문 수행하는 루트입니다.

 

Application.class

// 신규 메뉴 추가 입력
	private static Map<String, String> inputInsert(){
		Scanner sc = new Scanner(System.in);
		
		System.out.print("추가하실 메뉴명을 입력해주세요 : ");
		String name = sc.nextLine();
		
		System.out.print("추가하실 메뉴의 가격을 입력해주세요 : ");
		String price = sc.nextLine();
		
		System.out.print("추가하실 메뉴의 카테고리 코드를 입력해주세요 : ");
		String categoryCode = sc.nextLine();
		
		Map<String, String> parameter = new HashMap<>();
		parameter.put("name", name);
		parameter.put("price", price);
		parameter.put("categoryCode", categoryCode);
		
		return parameter;
	}

 

 

MenuController.class

// 신규 메뉴 추가
	public void insertMenu(Map<String, String> parameter) {
		
		// 전달받은 파라미터값을 변수에 저장
		String name = parameter.get("name");
		int price = Integer.parseInt(parameter.get("price"));
		int categoryCode = Integer.parseInt(parameter.get("categoryCode"));
		
		// 작업에 필요한 값을 Menu객체에 저장
		Menu menu = new Menu();
		menu.setName(name);
		menu.setPrice(price);
		menu.setCategoryCode(categoryCode);
		
		if(menuService.insertMenu(menu)) {
			resultPrint.sPrint("insert");
		}else {
			resultPrint.failPrint("insert");
		}
		
	
		
	}

 

 

MenuService.class

// 신규메뉴 추가
	public boolean insertMenu(Menu menu) {
		SqlSession sqlSession = getSqlSession();
		
		int result = menuDao.insertMenu(sqlSession, menu);
		
		if(result > 0) {
			sqlSession.commit();
		}else {
			sqlSession.rollback();
		}
		
		return result > 0 ? true : false;
	}

 

MenuDao.class

// 신규메뉴 추가
	public int insertMenu(SqlSession sqlSession, Menu menu) {
		return sqlSession.insert("menu-mapper.insertMenu", menu);
	}

 

Menu-mapper.xml

<insert id="insertMenu">
  	INSERT
  	  INTO TBL_MENU
  	  (
  	  	MENU_CODE
  	  , MENU_NAME
  	  , MENU_PRICE
  	  , CATEGORY_CODE
  	  , ORDERABLE_STATUS
  	  )
  	  VALUES
  	  (
  	  	SEQ_MENU_CODE.NEXTVAL
  	  , #{name}
  	  , #{price}
  	  , #{categoryCode}
  	  , 'Y'
  	  )
  </insert>

 

실행화면

 

 

4. 메뉴 수정

기존에 존재하고있는 메뉴 코드를 이용하여

메뉴명, 가격, 메뉴 코드를 수정하는 루트입니다.

Insert형식과 비슷합니다.

 

Application.class

// 메뉴 수정
	private static Map<String, String> inputUpdate(){
		Scanner sc = new Scanner(System.in);
		
		System.out.print("수정하실 메뉴 코드를 입력해주세요 : ");
		String code = sc.nextLine();
		
		System.out.print("수정하실 메뉴명을 입력해주세요 : ");
		String name = sc.nextLine();
		
		System.out.print("수정하실 메뉴의 가격을 입력해주세요 : ");
		String price = sc.nextLine();
		
		System.out.print("수정하실 메뉴의 카테고리 코드를 입력해주세요 : ");
		String categoryCode = sc.nextLine();
		
		Map<String, String> parameter = new HashMap<>();
		parameter.put("code", code);
		parameter.put("name", name);
		parameter.put("price", price);
		parameter.put("categoryCode", categoryCode);
		
		return parameter;
	}

 

MenuContoller.class

// 메뉴 수정
	public void UpdateMenu(Map<String, String> parameter) {
		int code = Integer.parseInt(parameter.get("code"));
		String name = parameter.get("name");
		int price = Integer.parseInt(parameter.get("price"));
		int categoryCode = Integer.parseInt(parameter.get("categoryCode"));
		
		// 작업에 필요한 값을 Menu객체에 저장
		Menu menu = new Menu();
		menu.setCode(code);
		menu.setName(name);
		menu.setPrice(price);
		menu.setCategoryCode(categoryCode);
		
		if(menuService.updateMenu(menu)) {
			resultPrint.sPrint("update");
		}else {
			resultPrint.failPrint("update");
		}
		
	}

 

MenuService.class

// 메뉴수정
	public boolean updateMenu(Menu menu) {
		SqlSession sqlSession = getSqlSession();
		
		int result = menuDao.updateMenu(sqlSession, menu);
		
		if(result > 0) {
			sqlSession.commit();
		}else {
			sqlSession.rollback();
		}
		
		return result > 0 ? true : false;
	}

 

MenuDao.class

// 메뉴 수정
	public int updateMenu(SqlSession sqlSession, Menu menu) {
		return sqlSession.update("menu-mapper.updateMenu", menu);
	}

 

menu-mapper.xml

<update id="updateMenu">
  	UPDATE
  		   TBL_MENU
  	   SET MENU_NAME = #{name}
  	     , MENU_PRICE = #{price}
  	     , CATEGORY_CODE = #{categoryCode}
  	 WHERE MENU_CODE = #{code}
  </update>

 

5. 메뉴 삭제

MenuContoller.class

// 메뉴 삭제
	public void deleteMenu(Map<String, String> parameter) {
		int code = Integer.parseInt(parameter.get("code"));
		
		if(menuService.deleteMenu(code)) {
			resultPrint.sPrint("delete");
		}else {
			resultPrint.failPrint("delete");
		}
		
	}

 

MenuService.class

// 메뉴 삭제
	public boolean deleteMenu(int code) {
		SqlSession sqlSession = getSqlSession();
		
		int result = menuDao.deleteMenu(sqlSession, code);
		
		if(result > 0) {
			sqlSession.commit();
		}else {
			sqlSession.rollback();
		}
		
		sqlSession.close();
		
		return result > 0 ? true : false;
	}

 

MenuDao.class

// 메뉴 삭제
	public int deleteMenu(SqlSession sqlSession, int code) {
		return sqlSession.delete("menu-mapper.deleteMenu", code);
	}

 

menu-mapper.xml

<delete id="deleteMenu">
  	DELETE
  	  FROM TBL_MENU
  	 WHERE MENU_CODE = #{code}
  </delete>

 

실행확인

 

지금까찌 xml로 mybatis작업을완료하였습니다.

다음작업은 class형식으로 애너테이션이용한 방법을 실습해보겠습니다.

'프로그래밍 > myBatis' 카테고리의 다른 글

myBatis - 5. 동적 쿼리  (0) 2021.10.07
myBatis - 4. 실습 (class + xml 형식)  (0) 2021.10.07
myBatis - 3. 실습 (class형식)  (0) 2021.10.06
myBatis - 1. 기본설정  (0) 2021.10.05
Framwork, Library  (0) 2021.10.05
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유