오후에 시험을 본다
MyBatis
- 쿼리문을 별도 관리, 분리한다
- 동적 쿼리를 작성할 수 있다.
- 캐시 기능을 제공해 데이터베이스 연산 속도를 높일 수 있다.
동적쿼리란
실행 시점에 조건에 따라 SQL 쿼리를 동적으로 생성하는 것.
데이터 베이스의 검색 조건이나 결과값 등이 동적으로 변환할 때 유용하게 사용된다.
src/main/resources > mapping > board-mapping.xml 에서 쿼리문을 처리
BoardDAO에서는 board-mapping.xml에서 적은 쿼리문을 언제 사용할지 정의해준다고 생각하면 됨.
board-mapping.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="BoardDAO">
<!-- 글 등록 -->
<insert id="insertBoard">
insert into board (seq,title,writer,content)
values ((select nvl(max(seq),0) + 1 from board), #{title}, #{writer}, #{content})
</insert>
<!-- 글 수정 -->
<update id="updateBoard">
update board set title=#{title}, content=#{content}, where seq=#{seq}
</update>
<!-- 글 삭제 -->
<delete id="deleteBoard">
delete board where seq=#{seq}
</delete>
<!-- 글 상세 조회 -->
<select id="getBoard" resultType="board">
select * from board where seq=#{seq}
</select>
<!-- 글 목록 조회 -->
<select id="getBoardList" resultType="board">
select * from board where title like '%'||#{searchKeyword}||'%'
order by seq desc
</select>
</mapper>
src/main/java > com.springbook.biz.board > BoardServiceClient
package com.springbook.biz.board;
import com.springbook.biz.board.impl.BoardDAO;
public class BoardServiceClient {
public static void main(String[] args) {
BoardDAO boardDAO = new BoardDAO();
BoardVO vo = new BoardVO();
vo.setTitle("myBatis 제목");
vo.setWriter("홍길동");
vo.setContent("여름아 부탁해");
boardDAO.insertBoard(vo);
}
}
이렇게 하고 실행했는데 이런 경고 메세지가 생겨서 보니
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by org.apache.ibatis.reflection.Reflector (file:/C:/Users/USER/.m2/repository/org/mybatis/mybatis/3.3.1/mybatis-3.3.1.jar) to method java.lang.Object.finalize()
WARNING: Please consider reporting this to the maintainers of org.apache.ibatis.reflection.Reflector
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
mybatis 버전 문제였다. 3.3.1 버전에서 → 3.5.2 버전으로 업그레이드 한 후 실행했더니 해결
pom.xml 수정
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.2</version>
</dependency>
[Mybatis] WARNING: An illegal reflective access operation has occurred
원인 테스트 중 다음과 같은 경고가 발생했다. WARNING: An illegal reflective access operation has occurred WARNING: Illegal reflective access by org.apache.ibatis.reflection.Reflector (file:/C:/Users/USER/.m2/repository/org/mybatis/mybatis/
sillutt.tistory.com
BoardServiceClient.java
package com.springbook.biz.board;
import java.util.List;
import com.springbook.biz.board.impl.BoardDAO;
public class BoardServiceClient {
public static void main(String[] args) {
BoardDAO boardDAO = new BoardDAO();
BoardVO vo = new BoardVO();
// 글 등록
vo.setTitle("myBatis 제목");
vo.setWriter("홍길동");
vo.setContent("여름아 부탁해");
boardDAO.insertBoard(vo);
vo.setSearchCondition("TITLE");
vo.setSearchKeyword("");
// 상세글 조회
//vo.setSeq(19);
//BoardVO getboard = boardDAO.getBoard(vo);
//System.out.println("상세글 조회 결과: " + getboard);
// 글 수정
//vo.setTitle("오늘의 날씨");
//vo.setContent("맑음");
//vo.setSeq(17);
//boardDAO.updateBoard(vo);
// 글 삭제
//vo.setSeq(29);
//boardDAO.deleteBoard(vo);
// 전체 글 조회
List<BoardVO> boardList = boardDAO.getBoardList(vo);
for (BoardVO board : boardList) {
System.out.println("==>" + board.toString());
}
}
}
조회, 수정, 삭제가 안된다..! 미해결과제
해결 )
스프링 pom.xml 세팅 시 aspectjweaver 태그 위치 설정 관계
0729)금요일에 mybatis 를 기존에 만들어 둔 게시판과 연동했는데 실행 오류가 났다.오늘 오전 다시 파일들을 찬찬히 살펴보며 코드를 수정했는데 pom.xml 에 세팅 오류가 있었다.' 오류 메세지 )Contex
100dumpling.tistory.com
추가로 알아 둘 것.
board-mapping.xml
<selectkey keyProperty="seq" resultType="int" order="BEFORE">
select board_seq.nextval as seq from duel
</selectkey>
insert into board (seq,title,writer,content)
values (#{seq}, #{title}, #{writer}, #{content})
<!-- 어떤 값을 따로 쓰고 싶을 때 -->
<!-- order="AFTER" insert 처리가 된 후에 값을 가지고 와라 -->
<selectkey keyProperty="writer" resultType="int" order="AFTER">
select writer from board
</selectkey>
</insert>
<insert id ="hobby">
insert into hobby (writer) values(#{writer}) <!-- 다른 테이블의 writer를 끌어올 수 있다 -->
</insert>
시퀀스 객체를 DB에 만들어 두고 시퀀스 객체를 이용할 수 있다.
board-mapping.xml
<!-- 컬럼이름과 VO객체 멤버 이름 비교, 이름이 다르더라도 자동으로 매치가 된다 -->
<resultMap id="boardResult" type="board">
<id property="seq" column="SEQ"/>
<result property="title" column="TITLE"/>
<result property="writer" column="WRITER"/>
<result property="content" column="CONTENT"/>
<result property="regDate" column="REGDATE"/>
<result property="cnt" column="CNT"/>
</resultMap>
쿼리문을 쓸 때 부등호( <, > ) 인식을 못한다. 그럼으로 부등호를 써야할 때는
<!-- 조건절에 비교연산자(<, >)을 식으로 인식하기 위해 -->
<![CDATA[
insert into board (seq,title,writer,content)
values ((select nvl(max(seq),0) + 1 from board), #{title}, #{writer}, #{content})
]]>
<![CDATA[ ]]> 안에 비교할 대상의 식이 쓰이게 사용해야 한다.
BoardDAO.java
package com.springbook.biz.board.impl;
import java.sql.SQLException;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import com.springbook.biz.board.BoardVO;
import com.springbook.biz.util.SqlSessionFactoryBean;
public class BoardDAO {
// 원형
// public List seleList(String statement)
// public List seleList(String statement, Object parmeter)
//
// public int insert(String statement, Object parmeter)
// public int update(String statement, Object parmeter) throws SQLException
// public int delete(String statement, Object parmeter) throws SQLException
// SqlSession 타입 mybatis은 xml의 정보를 다 가지고 있다.
private SqlSession mybatis;
public BoardDAO() {
mybatis = SqlSessionFactoryBean.getSqlSessionInstance();
}
// 글 등록
public void insertBoard(BoardVO vo) {
mybatis.insert("BoardDAO.insertBoard", vo);
mybatis.commit();
}
// 글 수정
public void updateBoard(BoardVO vo) {
mybatis.update("BoardDAO.updateBoard", vo);
mybatis.commit();
}
// 글 삭제
public void deleteBoard(BoardVO vo) {
mybatis.delete("BoardDAO.deleteBoard", vo);
mybatis.commit();
}
// 글 상세조회
public BoardVO getBoard(BoardVO vo) {
return mybatis.selectOne("BoardDAO.getBoard", vo); // 하나만 조회할때 selectOne
}
// 글 목록 조회
public List<BoardVO> getBoardList(BoardVO vo) {
return mybatis.selectList("BoardDAO.getBoardList", vo); // 여러 개 조회할때 selectList
}
}
Spring에 Mybatis 연결하기
어떤 프로그램을 사용하기 위해서는 접점이 필요하다
Spring에서도 Mybatis을 사용하기 위해서는 SDK → api 인터페이스가 필요.
SDK 을 통해 Mybatis에 접근한다.
자바에서 오라클DB를 쓰는 것과 똑같은 원리. - JDBC가 SDK
다이나믹 SQL = 동적 쿼리문
조건절 분기
BoardWep > board-mapping.xml
<!-- 글 목록 조회 -->
<select id="getBoardList" resultType="board" resultMap="boardResult">
select * from board where title like '%'||#{searchKeyword}||'%'
order by seq desc
</select>
위와 같은 구문 고정이 title인데 동적 처리를 하면
BoardWep > board-mapping.xml
<!-- 글 목록 조회 -->
<select id="getBoardList" resultType="board" resultMap="boardResult">
select * from board
where 1=1
<if test="searchCondition == 'TITLE'">
and title like '%'||#{searchKeyword}||'%'
</if>
<if test="searchCondition == 'CONTENT'">
and content like '%'||#{searchKeyword}||'%'
</if>
order by seq desc
</select>
이렇게 바꿀 수 있다.
where 절의 중복을 막기 위해 where 1=1 를 쓰고 where 절이 들어가는 곳마다 and 를 쓴다.
BoardWep > BoardDAOMybatis
package com.springbook.biz.board.impl;
import java.util.List;
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.springbook.biz.board.BoardVO;
@Repository
public class BoardDAOMybatis {
// SqlSessionTemplate이 mybatis 기능을 쓰는 라이브러리
// SqlSessionTemplate 객체를 사용
// 자동의존주입
@Autowired
private SqlSessionTemplate mybatis;
public void insertBoard(BoardVO vo) {
System.out.println("==> Mybatis로 insertBoard() 기능 처리");
mybatis.insert("BoardDAO.insertBoard", vo);
}
public void updateBoard(BoardVO vo) {
System.out.println("==> Mybatis로 updateBoard() 기능 처리");
mybatis.update("BoardDAO.updateBoard", vo);
}
public void deleteBoard(BoardVO vo) {
System.out.println("==> Mybatis로 deleteBoard() 기능 처리");
mybatis.delete("BoardDAO.deleteBoard", vo);
}
public BoardVO getBoard(BoardVO vo) {
System.out.println("==> Mybatis로 getBoard() 기능 처리");
return mybatis.selectOne("BoardDAO.getBoard", vo);
}
public List<BoardVO> getBoardList(BoardVO vo) {
System.out.println("==> Mybatis로 getBoardList() 기능 처리");
return mybatis.selectList("BoardDAO.getBoardList", vo);
}
}
applicationContext
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
<!-- 패키지를 스캔해준다. 다 해주는 것은 아니고 표시되어진 클래스만 스캔해준다 -> 이것이 어노테이션 -->
<!-- <context:component-scan base-package="polymorphism"></context:component-scan> -->
<context:component-scan base-package="com.springbook.biz"></context:component-scan>
<!-- database.properties 의 파일을 읽어올 수 있게 해준다 -->
<context:property-placeholder location="classpath:config/database.properties"/>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!--JdbcTemplate 클래스를 통해 DB에 접근 (crud) -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"></property>
</bean>
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="get*" read-only="true"/> <!-- get메소드 제외하고 트랜잭션 처리를 해줘라 -->
<tx:method name="*" />
</tx:attributes>
</tx:advice>
<bean id="sqlsession" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpth:sql-map-config.xml"/>
</bean>
<bean class="org.mybatis.spring.SqlSessionTemplate">
<!-- 생성자 의존 주입 -->
<constructor-arg ref="sqlSession"></constructor-arg>
</bean>
<aop:config>
<aop:pointcut expression="execution(* com.springbook.biz..*(..))" id="txPointcut"/> <!-- biz 하위의 모든 메소드를 수정하겠다 -->
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut" />
</aop:config>
</beans>
'2024_UIUX 국비 TIL' 카테고리의 다른 글
UIUX _국비과정 0729 ~ 30 (🍀Git, git bash 명령어) (0) | 2024.08.22 |
---|---|
UIUX _국비과정 0725 [스프링 JSON형식변환, 페이징 추가, MyBatis] (0) | 2024.08.21 |
UIUX _국비과정 0724 [검색기능, 파일업로드, 제이슨 형식으로 반환받기] (0) | 2024.08.21 |
UIUX _국비과정 0723 [스프링 컨트롤러 사용하기] (0) | 2024.08.19 |
UIUX _국비과정 0722 [웹소켓 채팅, 스프링 컨트롤러 사용하기] (0) | 2024.07.31 |