⚙️ Backend/스프링(Spring) Framework
스프링(Spring) -(1) 게시판 만들기 - MyBatis + Oracle DB 연동
반응형
<?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.koreait.mapper.BoardMapper">
<select id="getList" resultType="com.koreait.domain.BoardVO">
<![CDATA[
SELECT * FROM TBL_BOARD WHERE BNO > 0
]]>
</select>
</mapper>
(1) 게시판 만들기 - 프로젝트 설정
1. 프로젝트 생성 - Legacy, Spring MVC로 생성.
테이블 생성
--
CREATE SEQUENCE SEQ_BOARD;
DROP TABLE TBL_BOARD;
CREATE TABLE TBL_BOARD(
BNO NUMBER(10),
TITLE VARCHAR2(200) NOT NULL,
CONTENT VARCHAR2(2000) NOT NULL,
WRITER VARCHAR2(200) NOT NULL,
REGDATE DATE DEFAULT SYSDATE,
UPDATEDATE DATE DEFAULT SYSDATE
);
ALTER TABLE TBL_BOARD ADD CONSTRAINT PK_BOARD PRIMARY KEY(BNO);
INSERT INTO TBL_BOARD
(BNO, TITLE, CONTENT, WRITER, REGDATE)
VALUES(SEQ_BOARD.NEXTVAL, '테스트 제목', '테스트 내용', 'user001', SYSDATE
);
SELECT * FROM TBL_BOARD;
VO 생성
BoardVO.java
package com.koreait.domain;
import lombok.Data;
@Data
public class BoardVO {
// VO는 컬럼에 매핑된 것을 사용할 때
// DTO는 사용자 정의 모델된 것을 사용할 때
private Long bno;
private String title;
private String content;
private String writer;
private String regDate;
private String updateDate;
}
아웃라인 확인
BoardMapper.java (Interface)
package com.koreait.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Select;
import com.koreait.domain.BoardVO;
public interface BoardMapper {
// @Select("SELECT * FROM TBL_BOARD WHERE BNO > 0")
public List<BoardVO> getList();
}
BoardMapperTest.java
package com.koreait.mapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import lombok.Setter;
import lombok.extern.log4j.Log4j;
@RunWith(SpringJUnit4ClassRunner.class) //테스트 코드가 스프링을 실행
@ContextConfiguration("file:src/main/webapp/WEB-INF/spring/root-context.xml")//지정된 클래스나 문자열을 이용해서 필요한 객체들을 스프링 내에 객체로 등록
@Log4j
public class BoardMapperTests {
@Setter(onMethod_ = @Autowired)
private BoardMapper mapper;
@Test
public void testGetList() {
mapper.getList().forEach(board -> log.info(board));
}
}
root-context.xml 에 스캔 추가
<mybatis-spring:scan base-package="com.koreait.mapper" />
<?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:mybatis-spring="http://mybatis.org/schema/mybatis-spring"
xsi:schemaLocation="http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring-1.2.xsd
http://www.springframework.org/schema/beans https://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">
<!-- Root Context: defines shared resources visible to all other web components -->
<!-- HikariConfig hikariConfig = new HikariConfig() -->
<!-- hikariConfig.setDriverClassName("") -->
<!-- hikariConfig.jdbcUrl("") -->
<!-- hikariConfig.username("") -->
<!-- hikariConfig.password("") -->
<bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
<!-- <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<property name="jdbcUrl" value="jdbc:oracle:thin:@localhost:1521:XE"/> -->
<property name="driverClassName"
value="net.sf.log4jdbc.sql.jdbcapi.DriverSpy" />
<property name="jdbcUrl"
value="jdbc:log4jdbc:oracle:thin:@localhost:1521:XE" />
<property name="username" value="hr" />
<property name="password" value="hr" />
</bean>
<!-- DataSource dataSource = new DataSource(hikariConfig) -->
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource"
destroy-method="close">
<constructor-arg ref="hikariConfig" />
</bean>
<bean id="sqlSessionFactory"
class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- <property name="mapperLocations"
value="classpath:/META-INF/com/koreait/mappera/**/*.xml" />
-->
<!-- <property name="configLocation" value="classpath:/META-INF/com/koreait/config/MapperConfig.xml"/> -->
</bean>
<mybatis-spring:scan base-package="com.koreait.mapper" />
</beans>
BoardMapper.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.koreait.mapper.BoardMapper">
<select id="getList" resultType="com.koreait.domain.BoardVO">
<![CDATA[
SELECT * FROM TBL_BOARD WHERE BNO > 0
]]>
</select>
<insert id="insert">
INSERT INTO TBL_BOARD (BNO, TITLE, CONTENT, WRITER)
VALUES(SEQ_BOARD.NEXTVAL, #{title}, #{content}, #{writer})
</insert>
</mapper>
CDATA를 사용하는 이유는 ' > ' 부등호 연산자를 이용하기 위해서 이다.
BoardMapperTests.java
@Test
public void testInsert() {
BoardVO board = new BoardVO();
// 메소드 안에서는 의존성 주입(DI)가 되지않기 때문이다.
// 그렇기 때문에 전역변수에만 주입하는 것이다.
// 메소드 안에서는 new로 할당한다.
board.setTitle("새로 작성한 글 제목");
board.setContent("새로 작성한 글 내용");
board.setWirter("newbie");
mapper.insert(board);
log.info("board .... : "+ board);
}
<!--
PK값을 미리 SQL을 통해서 처리하는 방식
SQL을 한 번 더 실행하는 부담이 있기는 하지만 자동으로 추가되는 PK값을 확인해야 하는 상황에서는
유용하게 사용될 수 있다.
-->
<insert id="insertSelectKey_bno">
<!-- BEFORE라는 속성은 먼저 실행되기 위함이다.-->
<selectKey keyProperty="bno" order="BEFORE" resultType="long">
SELECT SEQ_BOARD.NEXTVAL FROM DUAL
</selectKey>
INSERT INTO TBL_BOARD (BNO, TITLE, CONTENT, WRITER)
VALUES(#{bno}, #{title}, #{content}, #{writer})
</insert>
BoardMapper.java (인터페이스)
// read() 선언 후 테스트 : 게시글 상세보기
public void read(long bno);
//delete() 선언 후 테스트 : 게시글 삭제
// 게시글 삭제 시 1 이상의 값 리턴 , 없으면 0 리턴
public boolean delete(long bno);
mapper.xml
<select id="read">
SELECT * FROM TBL_BOARD WHERE bno = #{bno}
</select>
<delete id="delete">
DELETE FROM TBL_BOARD WHERE bno = #{bno}
</delete>
@Test
public void delete() {
if(mapper.delete(2l) > 0) {
log.info("check : 성공 ");
} else {
log.info("check : 실패 ");
}
}
전체 코드
root-context.xml
더보기
<?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:mybatis-spring="http://mybatis.org/schema/mybatis-spring"
xsi:schemaLocation="http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring-1.2.xsd
http://www.springframework.org/schema/beans https://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">
<!-- Root Context: defines shared resources visible to all other web components -->
<!-- Root Context: defines shared resources visible to all other web components -->
<!-- HikariConfig hikariConfig = new HikariConfig(); -->
<!-- hikariConffig.setDriverClassName(""); -->
<!-- hikariConffig.jdbcUrl(""); -->
<!-- hikariConffig.username(""); -->
<!-- hikariConffig.password(""); -->
<bean id="hikariConfig" class="com.zaxxer.hikari.HikariConfig">
<!-- <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<property name="jdbcUrl" value="jdbc:oracle:thin:@132.226.169.45:1521:XE"/> -->
<property name="driverClassName" value="net.sf.log4jdbc.sql.jdbcapi.DriverSpy"/>
<property name="jdbcUrl" value="jdbc:log4jdbc:oracle:thin:@localhost:1521:XE"/>
<property name="username" value="hr"/>
<property name="password" value="hr"/>
</bean>
<!-- DataSource dataSource = new DataSource(hikariConfig) -->
<bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource" destroy-method="close">
<constructor-arg ref="hikariConfig"/>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mapperLocations" value="classpath:/META-INF/com/koreait/mapper/**/*.xml"/>
<!-- <property name="configLocation" value="classpath:/META-INF/com/koreait/config/MapperConfig.xml"/> -->
</bean>
<mybatis-spring:scan base-package="com.koreait.mapper"/>
</beans>
log4j.xml
더보기
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<!-- Appenders -->
<appender name="console" class="org.apache.log4j.ConsoleAppender">
<param name="Target" value="System.out" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p: %c - %m%n" />
</layout>
</appender>
<!-- Application Loggers -->
<logger name="com.koreait.controller">
<level value="info" />
</logger>
<!-- 3rdparty Loggers -->
<logger name="org.springframework.core">
<level value="info" />
</logger>
<logger name="org.springframework.beans">
<level value="info" />
</logger>
<logger name="org.springframework.context">
<level value="info" />
</logger>
<logger name="org.springframework.web">
<level value="info" />
</logger>
<logger name="jdbc.audit">
<level value="warn"/>
</logger>
<logger name="jdbc.resultset">
<level value="warn"/>
</logger>
<logger name="jdbc.connection">
<level value="warn"/>
</logger>
<!-- Root Logger -->
<root>
<priority value="info" />
<appender-ref ref="console" />
</root>
</log4j:configuration>
BoardMapperTests.java
더보기
package com.koreait.mapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.koreait.domain.BoardVO;
import lombok.Setter;
import lombok.extern.log4j.Log4j;
@RunWith(SpringJUnit4ClassRunner.class) //테스트 코드가 스프링을 실행
@ContextConfiguration("file:src/main/webapp/WEB-INF/spring/root-context.xml")//지정된 클래스나 문자열을 이용해서 필요한 객체들을 스프링 내에 객체로 등록
@Log4j
public class BoardMapperTests {
@Setter(onMethod_ = @Autowired)
private BoardMapper mapper;
@Test
public void update() {
BoardVO board = new BoardVO();
board.setBno(1l);
board.setTitle("수정된 글 제목");
board.setContent("수정된 글 내용");
board.setWriter("어드민");
log.info(" 수정 성공 : "+ mapper.update(board));
}
// @Test
// public void delete() {
// if(mapper.delete(2l) > 0) {
// log.info("check : 성공 ");
// } else {
// log.info("check : 실패 ");
// }
// }
// @Test
// public void read() {
// Long bno = 2l;
// log.info(mapper.read(bno));
// }
// @Test
// public void testInsertSelectKey_bno() {
// BoardVO board = new BoardVO();
// board.setTitle("새로 작성한 글 제목2");
// board.setContent("새로 작성한 글 내용2");
// board.setwriter("newbie2");
//
// mapper.insert(board);
// log.info("board .... : "+ board);
// }
// @Test
// public void testInsert() {
// BoardVO board = new BoardVO();
// // 메소드 안에서는 의존성 주입(DI)가 되지않기 때문이다.
// // 그렇기 때문에 전역변수에만 주입하는 것이다.
// // 메소드 안에서는 new로 할당한다.
// board.setTitle("새로 작성한 글 제목");
// board.setContent("새로 작성한 글 내용");
// board.setwriter("newbie");
//
// mapper.insert(board);
// log.info("board .... : "+ board);
// }
// @Test
// public void testGetList() {
// mapper.getList().forEach(board -> log.info(board));
// }
}
BoardMapper.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.koreait.mapper.BoardMapper">
<select id="getList" resultType="com.koreait.domain.BoardVO">
<![CDATA[
SELECT * FROM TBL_BOARD WHERE BNO > 0
]]>
</select>
<insert id="insert">
INSERT INTO TBL_BOARD (BNO, TITLE, CONTENT, WRITER)
VALUES(SEQ_BOARD.NEXTVAL, #{title}, #{content}, #{writer})
</insert>
<!--
PK값을 미리 SQL을 통해서 처리하는 방식
SQL을 한 번 더 실행하는 부담이 있기는 하지만 자동으로 추가되는 PK값을 확인해야 하는 상황에서는
유용하게 사용될 수 있다.
-->
<insert id="insertSelectKey_bno">
<!-- BEFORE라는 속성은 먼저 실행되기 위함이다.-->
<selectKey keyProperty="bno" order="BEFORE" resultType="long">
SELECT SEQ_BOARD.NEXTVAL FROM DUAL
</selectKey>
INSERT INTO TBL_BOARD (BNO, TITLE, CONTENT, WRITER)
VALUES(#{bno}, #{title}, #{content}, #{writer})
</insert>
<select id="read" resultType="com.koreait.domain.BoardVO">
SELECT * FROM TBL_BOARD WHERE bno = #{bno}
</select>
<delete id="delete">
DELETE FROM TBL_BOARD WHERE bno = #{bno}
</delete>
<update id="update">
UPDATE TBL_BOARD
SET TITLE = #{title}, CONTENT = #{content}, WRITER = #{writer}, UPDATEDATE = SYSDATE
WHERE BNO = #{bno}
</update>
</mapper>
BoardMapper.java
더보기
package com.koreait.mapper;
import java.util.List;
import com.koreait.domain.BoardVO;
public interface BoardMapper {
// @Select("SELECT * FROM TBL_BOARD WHERE BNO > 0")
public List<BoardVO> getList();
public void insert(BoardVO board); // 추가
// insert 하면서 select
public void insertSelectKey_bno(BoardVO board);
// read() 선언 후 테스트 : 게시글 상세보기
public BoardVO read(long bno);
//delete() 선언 후 테스트 : 게시글 삭제
// 게시글 삭제 시 1 이상의 값 리턴 , 없으면 0 리턴
public int delete(long bno);
// update() 게시글 수정
public int update(BoardVO board);
}
pom.xml
더보기
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.koreait</groupId>
<artifactId>controller</artifactId>
<name>ex02</name>
<packaging>war</packaging>
<version>1.0.0-BUILD-SNAPSHOT</version>
<properties>
<java-version>1.8</java-version>
<org.springframework-version>5.0.7.RELEASE</org.springframework-version>
<org.aspectj-version>1.6.10</org.aspectj-version>
<org.slf4j-version>1.6.6</org.slf4j-version>
</properties>
<dependencies>
<!-- Spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${org.springframework-version}</version>
<exclusions>
<!-- Exclude Commons Logging in favor of SLF4j -->
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<!-- AspectJ -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${org.aspectj-version}</version>
</dependency>
<!-- Logging -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${org.slf4j-version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>${org.slf4j-version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${org.slf4j-version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.0</version>
<scope>1.2.17</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!-- @Inject -->
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
<!-- Servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<!-- Test -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.1.1.RELEASE</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com.artifact/com.zaxxer/HikariCP -->
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>2.7.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${org.springframework-version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.bgee.log4jdbc-log4j2 -->
<dependency>
<groupId>org.bgee.log4jdbc-log4j2</groupId>
<artifactId>log4jdbc-log4j2-jdbc4</artifactId>
<version>1.16</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.9</version>
<configuration>
<additionalProjectnatures>
<projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
</additionalProjectnatures>
<additionalBuildcommands>
<buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand>
</additionalBuildcommands>
<downloadSources>true</downloadSources>
<downloadJavadocs>true</downloadJavadocs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<compilerArgument>-Xlint:all</compilerArgument>
<showWarnings>true</showWarnings>
<showDeprecation>true</showDeprecation>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<configuration>
<mainClass>org.test.int1.Main</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
BoardVO.java
더보기
package com.koreait.domain;
import lombok.Data;
@Data
public class BoardVO {
// VO는 컬럼에 매핑된 것을 사용할 때
// DTO는 사용자 정의 모델된 것을 사용할 때
private Long bno;
private String title;
private String content;
private String wirter;
private String regDate;
private String updateDate;
}
반응형
'⚙️ Backend > 스프링(Spring) Framework' 카테고리의 다른 글
스프링 (Spring) 의존성 주입이란 ? (0) | 2021.05.10 |
---|---|
스프링(Spring) -(2) 게시판 만들기 - Service , ServiceImple (0) | 2021.05.10 |
스프링(Spring) - 스프링 MVC 프로젝트의 기본 구성 (0) | 2021.05.10 |
스프링(Spring) - 예외처리, 500 오류 (@ControllerAdvice) (0) | 2021.05.10 |
(Spring MVC) Front-Controller 패턴 (0) | 2021.05.07 |
댓글