Spring

230206 Spring MyBatis mapper

주영재 2023. 2. 6. 19:23

mapper태그


mapper.xml의 mapper태그의 namespace에는 풀경로를 적는다. 

db의 select태그는 select태그를, update, delete는 update태그, delete태그를 사용.

태그의 id는 해당 인터페이스의 추상메서드 이름과 대소문자까지 정확하게 일치해야 함.

resultType은 추상메서드의 리턴타입과 동일하게.


select태그

select와 insert, delete, update의 차이
->select는 반환이 있음. insert, delete, update는 true(or 1)나 false(or 0)로 성공실패 결과만 돌려준다.

1. 그래서 select태그는 resultType이란 속성을 반드시 적어줘야 한다. 없으면 에러
->정수, 문자열, map, vo등이 사용됨. int, String, Map, 해당VO.
->;은 적지 않는다. 적으면 에러
->한 행에 대한 처리를 할 타입을 적어주면 된다. ArrayList<VO객체>가 메서드 반환 타입이더라도 VO객체를 적는다.
->이때, vo의 패키지명을 포함한 풀 경로를 적는다. mybatis-config.xml에 등록하면 단축명으로도 사용가능하다.
->ArrayList<Map<>>이면 resultType엔 map을 적는다.

2. resultMap속성은 JOIN을 할 때 사용한다.

3. parameterType은 메서드가 전달받는 타입. 생략가능함. 
웬만하면 코드해석용으로 작성함.


insert, delete, update 태그

id태그 있음
resultType 없음.
parameterType 있음. 생략가능


insert, delete, update


반환이 성공실패결과를 받거나(int or boolean) 없다(void)

id는 필수
resultType은 적지 않는다.

parameterType도 만약 vo가 들어간다면 풀경로를 넣어준다.
대소문자 가린다.

TestMapper.xml에서, sql구문을 적을 때, vo가 매개변수일 경우 #{}들 안에 들어가는 값은
vo의 setter명이다. 멤버변수를 통해 setter를 만들기 때문에 멤버변수명과 동일하게 각각 넣으면 된다.

map이 매개변수일 경우,
xml의 구문은 똑같이 쓴다. test의 메서드에서 put을 할 때 key값이 파라미터가 된다.

웬만하면 map타입은 지양. 


Sql구분의 값 전달.

?->#{}

마이바티스 값(인터페이스에 사용하는 파라미터 타입)을 전달하는 방법.

  1.  단일값은 그냥 전달할 수 있음.
  2. VO클래스를 통째로 전달할 수 있음.
  3.  map을 통해서도 전달할 수 있음. 키=값의 형태로 선언한 map에 넣어놓으면 됨. 
    -대신, 정말 필요한 경우가 아니면 map은 사용하지 않음.  변화되는 데이터에 대처하기 까다롭기 때문
  4. 여러 값을 전달할 때는 @Param으로 이름을 지정해서 사용가능.

단일값일 경우 #{}안에 추상메서드에서 사용한 매개변수명이 그대로 들어감

 

마이바티스는 매개변수가 무조건 하나!
mapper insert구문 @Param-매개변수 2개 이상일 때 반드시 이름 정해줘야 한다. vo타입에도 사용가능.
이때, 인터페이스에서 매개변수로 @Param("변수명") String name으로 하고
xml에서 name=#{변수명}으로 사용한다.


+)동적쿼리 지원(sql문이 조건에 따라 변함)-검색에 사용
1. if
2. chose(when, otherwise)
3. foreach

 


MyBatis를 사용하기 위한 Root-context.xml 설정 추가

선택사항

configLocation은 마이바티스 설정 속성
vo의 풀 경로를 줄여쓰기가 가능

classpath:/는 src/main/resources파일 아래의 파일의 경로를 참조하는 방법임.
classpath아래의 파일을 맵핑시켜 마이바티스 설정을 추가하는 것이 가능


src/main/resources아래에 폴더 만들고, xml파일 만듦.
mybatis-config.xml파일에 

<!DOCTYPE configuration
 PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
 "http://mybatis.org/dtd/mybatis-3-config.dtd">

추가.

그리고

<configuration>
	<typeAliases>
		<typeAlias type="com.simple.command.ScoreVO" alias="ScoreVO"/> 
	</typeAliases>
</configuration>


를 추가하면, vo를 쓸 때 풀경로 대신 단축명(alias="단축명")으로 사용가능.
부가적으로 사용할 수 있는 여러 속성이 있다. mybatis문서를 보고 사용.

하고, root-context.xml에 

<!-- 마이바티스 설정 sqlSessionFactory 빈으로 생성-->
<!-- classpath:/ 자바/리소스 경로를 가르킵니다 -->
<bean class="org.mybatis.spring.SqlSessionFactoryBean">
	<!-- 데이터베이스 정보 전달 -->
	<property name="dataSource" ref="ds"/>
	<property name="configLocation" value="classpath:/mybatis-config/mybatis-config.xml"></property>
</bean>

 

로 추가.

==>이렇게하면 resultType과 parameterType에 단축명으로 사용가능.


TestMapper.java

package com.simple.basic.mapper;

import java.util.ArrayList;
import java.util.Map;

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

import com.simple.command.ScoreVO;

@Mapper //마이바티스 지칭 -(스프링에서는 생략가능)
public interface TestMapper {
	
	public ArrayList<ScoreVO> getScore();
	public ScoreVO getOne(int a);
	
	public Map<String, Object> selectMap(int num); //1행
	public ArrayList<Map<String, Object>> selectTwo(); //맵을 통한 다중행 조회
	
	public int insertOne(String s); //단일값
	public int insertTwo(ScoreVO vo); //다중값 -vo
	public int insertThree(Map<String, String> map); //다중값 -map
	
	public boolean updateOne(ScoreVO vo);//update
	
	public void insertFour(@Param("변수명1")String name, @Param("변수명2")int kor);
	
}

 

 

 

TestMapper.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.simple.basic.mapper.TestMapper">
	<!-- id는 인터페이스의 메서드명, resultType은 반환타입 -->
	<select id="getTime" resultType="string">
		select now()
	</select>


	<!-- ;은 적지 않는다. -->
	<!-- 한 행에 대한 처리를 할 데이터 타입(풀 경로) -->
	<select id="getScore" resultType="ScoreVO">
		select * from score
	</select>


	<!-- 매개변수 =단일값(매개변수명을 그대로) -->
	<select id="getOne" resultType="ScoreVO">
		select * from score where num=#{a}
	</select>
	
    
	<select id="selectMap" resultType="map" parameterType="int">
		select * from score where num=#{num}
	</select>
	
    
	<select id="selectTwo" resultType="map">
		select * from score
	</select>
	
	

	<!-- parameterType -매개변수의 타입(생략가능) -->
	<insert id="insertOne" parameterType="string">
		insert into score(name) values(#{s})
	</insert>


	<insert id="insertTwo"
		parameterType="com.simple.command.ScoreVO">
		insert into score(name, kor, eng)
		values(#{name},#{kor},#{eng})
	</insert>


	<insert id="insertThree">
		insert into score(name, kor, eng)
		values(#{name},#{kor},#{eng})
	</insert>
	
    
	<!-- alias설정이 있다면 parameter타입, result타입에 단축명으로 사용가능합니다. -->
	<update id="updateOne" parameterType="ScoreVO">
		update score set name=#{name}, kor=#{kor}, eng=#{eng} where num=#{num}	
	</update>
	
    
	<insert id="insertFour">
		insert into score(name, kor) value(#{변수명1}, #{변수명2})
	</insert>
	
	
</mapper>

 

 

 

JDBCMybatis.java

package com.simple.basic;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.simple.basic.mapper.TestMapper;
import com.simple.command.ScoreVO;

@RunWith(SpringJUnit4ClassRunner.class) //junit으로 테스트환경을 구성
@ContextConfiguration("file:src/main/webapp/WEB-INF/config/root-context.xml") //동작시킬 스프링 설정파일
public class JDBCMybatis {
	
	@Autowired
	TestMapper testMapper;
	
	//select태그의 resultType
	@Test
	public void testCode03() {
		ArrayList<ScoreVO> list=testMapper.getScore();
		System.out.println(list.toString());
	}
	
	//매개변수 - 단일값
	@Test
	public void testcode04() {
		ScoreVO vo = testMapper.getOne(14);
		System.out.println(vo.toString());
	}
	
	
	//insert -단일값
	@Test
	public void testCode05() {
		
		int result=testMapper.insertOne("이름");
		System.out.println("성공실패: "+ result);
	}
	
	//insert -다중값(vo) - setter가 파라미터가 된다.
	@Test
	public void testCode06() {
		ScoreVO vo=new ScoreVO(0,"테이","50","70");
		
			int result=testMapper.insertTwo(vo);
			System.out.println("성공실패: "+ result);
	}
	
	//insert -다중값(Map) : key값이 파라미터가 된다.
	@Test
	public void testCode07() {
		
		Map<String, String> map = new HashMap<>();
		map.put("name", "오라클");
		map.put("kor", "30");
		map.put("eng", "40");
		
		int result=testMapper.insertThree(map);
		System.out.println("성공실패: "+ result);
		
	}
	
	//select -map타입의 반환
	@Test
	public void testCod08() {
		Map<String, Object> map = testMapper.selectMap(17);
		System.out.println(map.toString());
	}
	
	//select-map타입의 반환: 맵타입을 사용하는 것은 부득이한 경우만 사용한다.
	@Test
	public void testCode09() {
		ArrayList<Map<String,Object>> list = testMapper.selectTwo();
		System.out.println(list.toString());
	}
	
	//update
	@Test
	public void testCode10() {
		
		ScoreVO vo = new ScoreVO(10, "마나", "70", "80");
		boolean result=testMapper.updateOne(vo);
		System.out.println("성공실패:"+result);
	}
	
	//insert구문 @Param-매개변수 2개 이상일 때 반드시 이름 정해줘야 한다. vo타입에도 사용가능
	@Test
	public void testCode11() {
		testMapper.insertFour("파람테스트", 100);
	}
	
	
	
	
}

 

 

콘솔출력문

ScoreVO [num=14, name=에이스, kor=50, eng=80]
{num=17, name=가이, kor=50, eng=70}
[ScoreVO [num=10, name=마나, kor=70, eng=80], ScoreVO [num=14, name=에이스, kor=50, eng=80], ScoreVO [num=15, name=ㅁㅁ, kor=11, eng=22], ScoreVO [num=16, name=이름, kor=0, eng=0], ScoreVO [num=17, name=가이, kor=50, eng=70], ScoreVO [num=18, name=테이, kor=50, eng=70], ScoreVO [num=19, name=오라클, kor=30, eng=40], ScoreVO [num=20, name=테스트, kor=85, eng=98], ScoreVO [num=21, name=수정이, kor=788, eng=87], ScoreVO [num=22, name=마느, kor=55, eng=55], ScoreVO [num=23, name=aa, kor=12, eng=123], ScoreVO [num=24, name=파람테스트, kor=100, eng=0], ScoreVO [num=25, name=파람테스트, kor=100, eng=0], ScoreVO [num=26, name=파람테스트, kor=100, eng=0], ScoreVO [num=27, name=파람테스트, kor=100, eng=0]]
성공실패: 1
성공실패: 1
성공실패: 1
[{num=10, name=마나, kor=70, eng=80}, {num=14, name=에이스, kor=50, eng=80}, {num=15, name=ㅁㅁ, kor=11, eng=22}, {num=16, name=이름, kor=0, eng=0}, {num=17, name=가이, kor=50, eng=70}, {num=18, name=테이, kor=50, eng=70}, {num=19, name=오라클, kor=30, eng=40}, {num=20, name=테스트, kor=85, eng=98}, {num=21, name=수정이, kor=788, eng=87}, {num=22, name=마느, kor=55, eng=55}, {num=23, name=aa, kor=12, eng=123}, {num=24, name=파람테스트, kor=100, eng=0}, {num=25, name=파람테스트, kor=100, eng=0}, {num=26, name=파람테스트, kor=100, eng=0}, {num=27, name=파람테스트, kor=100, eng=0}, {num=28, name=이름, kor=0, eng=0}, {num=29, name=테이, kor=50, eng=70}, {num=30, name=오라클, kor=30, eng=40}]
성공실패:true

★기억할것

-vo를 입력할 때 등록하지 않았으면 풀경로를 적을 것

-ArrayList<ScoreVO>가 반환타입이어도 mapper.xml에선 resultType에 ScoreVO만 적을 것

-vo를 사용할 땐 #{}안에 setter명에 맞게 적는 것

-Map<>을 사용할 땐 resultType이나 prarameterType엔 "map"만 적는 것

-Map을 매개변수로 받을 땐 map.put 등에서 사용하는 키값과 동일하게 #{}에 적을 것

-mybatis는 매개변수를 하나만 받는다, 두개 이상부터는 @Param("변수명")으로 인터페이스 추상메서드 매개변수에 넣고 xml에서 #{변수명}으로 사용할 것.