JAVA 웹개발 과정 국비 82일차 정리

82일차

※ 배우는 과정이므로 정확하지 않을 수 있습니다.
잘못된 점은 알려주시면 수정하도록 하겠습니다!


1. Spring Framework 이어서..

1) Mybatis의 작동 원리

image

기존에는 DAO에서 DB로 직접 연결을 했다면, Mybatis를 쓰게 되면 DAO에서 Mapper라는 파일을 참조하여 DB와 연결을 하는 개념이다.
보통 테이블 하나당 Mapper 파일 하나로 이루어진다.
Mapper는 쿼리만 분리하여 가지는 파일이다.

2) Mapper 파일 생성

src/main/resources폴더에 mybatis 패키지를 만들어 준 뒤, 테이블 명을 보통 앞에 붙여서 mapper 파일을 생성한다.
실습에서는 전화번호부 웹 애플리케이션을 만들고 있기 때문에 contact 테이블을 쓰므로 contact-mapper.xml로 파일을 생성했다.

xml 파일에서 사용할 문법들을 챙겨오기 위해서 구글에서 mybatis을 검색하여 공식홈페이지로 이동한 뒤 시작하기로 들어가 매핑된 SQL 구문 살펴보기 부분의 예제를 가져온다.
매핑은 직접할 거기 때문에 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 속성을 준다.
namespace는 dao에서 해당 mapper를 구분짓기 위한 구분자 역할을 한다.

<mapper namespace="Contact">

</mapper>

3) DAO 코드

@Autowired 어노테이션을 줘서 SqlSessionTemplate를 연결한다.
SqlSessionTemplate는 이미 roo-context.xml에 bean태그를 추가해서 스프링에서 인스턴스를 가지고 있게 해주었다.

@Autowired
private SqlSessionTemplate mybatis;

4) Mybatis로 CRUD 구현하기

① INSERT 쿼리문

ⓐ xml 코드

insert 태그를 사용해준다.
id는 어떤 이름이든 상관없지만, 직관적인 이름을 사용해준다.
쿼리문에 들어가야하는 변수는 #{ } 으로 표현해준다. dao에서 dto를 넘겼다면, EL 문법과 같이 필드명만 적어주면 된다.

<insert id="insert">
	INSERT INTO contact VALUES(contact_seq.NEXTVAL, #{name}, #{contact})
</insert>
ⓑ dao 코드

insert 메소드를 사용한다.
첫번째 파라미터로는 매퍼의 namespace와 id를 적어준다.
두번째 파라미터는 넘길 데이터를 적어준다.
리턴값은 int이므로 그대로 return을 적어주면 된다.

public int insert(ContactDTO dto) {
	return mybatis.insert("Contact.insert", dto);
}

② SELECT 쿼리문 (두개 이상의 값 리턴)

ⓐ xml 코드

select 태그를 사용해준다.
resultType은 select 태그를 사용할 때 써줘야 하는 속성으로 어떤 자료형을 받는지 명세한다.
int를 받아온다면 생략 가능하지만, 표기해주는 습관을 들이자.

<select id="selectAll" resultType="kh.spring.dto.ContactDTO">
	SELECT * FROM contact ORDER BY seq
</select>
ⓑ dao 코드

여러값을 받아오기 때문에 selectList 메소드를 사용한다.
테이블의 컬럼명과 DTO의 멤버필드명을 일치시켜줘야 mybatis가 동일하게 값을 가져오니 주의하자.

public List<ContactDTO> selectAll() {
	return mybatis.selectList("Contact.selectAll");
}

③ SELECT 쿼리문 (하나의 값 리턴)

ⓐ xml 코드
<select id="selectCount" resultType="int">
	SELECT COUNT(*) FROM contact
</select>
ⓑ dao 코드

하나의 값만 받아오기 때문에 selectOne 메소드를 사용한다.

public int selectCount() {
	return mybatis.selectOne("Contact.selectCount");
}

④ SELECT 쿼리문 (인자값을 넘기는)

ⓐ xml 코드
<select id="selectBySeq" resultType="kh.spring.dto.ContactDTO">
	SELECT * FROM contact WHERE id = #{value}
</select>
ⓑ dao 코드

실습에서는 seq로 검색했기 때문이 한가지의 값을 받아오지만, jsp에서 자료를 뿌려줄 때 통일시키기 위해 List로 받았다.
데이터를 ContactDTO로 받고, selectOne 메소드를 사용해도 상관 없다.
쿼리문에 넣을 데이터를 두번째 파라미터로 전달한다.

public List<ContactDTO> search(int seq){
	return mybatis.selectList("Contact.selectBySeq", seq);
}

⑤ DELETE 쿼리문

ⓐ xml 코드

delete 태그를 사용해준다.
받아온 인자값이 DTO같이 key값이 없는 하나의 데이터라면 value로 통일하여 적어준다.

<delete id="deleteBySeq">
	DELETE FROM contact WHERE seq = #{value}
</delete>
ⓑ dao 코드

쿼리문에 넘겨줄 인자값 seq를 두번째 파라미터로 적어준다.

public int deleteBySeq(int seq) {
	return mybatis.delete("Contact.deleteBySeq", seq);
}

⑥ UPDATE 쿼리문

ⓐ xml 코드

update 태그를 사용해준다.
쿼리문 안에는 map의 key 값을 적어준다.
column같은 경우는 쿼리문에 ‘ ‘(싱글 쿼테이션)이 붙으면 안되기때문에 $를 사용한다.

<update id="update">
	UPDATE contact SET ${column} = #{value} WHERE seq = #{seq}
</update>
ⓑ dao 코드

dto가 아니며, 여러개의 값을 매퍼파일에 넘길 때는 key값을 가지는 Hashmap을 사용한다.
put 메소드로 map에 데이터를 넣어주고, update메소드에 두번째 파라미터로 map을 전달해주면 dto를 넘긴 것과 같이 사용할 수 있게 된다.

public int update(String column, String value, int seq) {
	Map<String,String> map = new HashMap<>();
	map.put("column", column);
	map.put("value", value);
	map.put("seq", String.valueOf(seq));
	return mybatis.update("Contact.update", map);
}

⑦ 다중 SELECT 쿼리문

ⓐ xml 코드

trim 태그는 자신의 태그 영역 안쪽에 아무것도 없다면 동작하지 않는다. 그러나 어떤 글자라도 안에 존재한다면, 자신의 역할을 수행한다.
prefix 속성은 trim 안쪽의 쿼리문이 튀어나올 때 그 앞에 붙여주는 단어를 지정할 수 있다.
예를 들어 첫번째 if문이 동작한다면, SELECT * FROM contact WHERE name=#{name} 으로 적절한 쿼리문이 된다.
prefixOverrides 속성은 trim 안쪽에 쿼리문이 튀어나올 때 제일 앞쪽에 같은 단어가 있다면 없애(무효화)버리는 기능을 한다.
예를 들면 두번째 if문이 동작한다면, and contact=#{contact} 가 trim 밖으로 튀어나오려고 할 것이고, 이 때 prefixOverrides에 and가 있기 때문에 and가 삭제되어 최종 쿼리문은 SELECT * FROM contact contact=#{contact} 가 되어 에러가 나지 않는다.
prefixOverrides=”and” 또는 prefixOverrides=”or” 도 가능하고, 아래와 같이 두 값을 동시에 주는 것도 가능하다.

<select id="searchByMultiCon" resultType="kh.spring.dto.ContactDTO">
	SELECT * FROM contact 
	<trim prefix="where" prefixOverrides="and|or">
		<if test="name!=''">
			name=#{name}
		</if>
		<if test="contact!=''">
			and contact=#{contact}
		</if>
	</trim>
</select>

추가로 쿼리문에 LIKE를 사용할 때는 아래와 같이 쓸 수 있다.

AND contact LIKE '%'||#{contact}||'%'
ⓑ dao 코드

dto가 아니며, 여러개의 값을 매퍼파일에 넘길 때는 key값을 가지는 Hashmap을 사용한다.
put 메소드로 map에 데이터를 넣어주고, update메소드에 두번째 파라미터로 map을 전달해주면 dto를 넘긴 것과 같이 사용할 수 있게 된다.

public List<ContactDTO> searchByMultiCon(ContactDTO dto) {
	return mybatis.selectList("Contact.searchByMultiCon", dto);
}

댓글남기기