Spring

MyBatis - service, CRUD

H_eh 2022. 8. 11. 15:12

service인터페이스

사용자의 요청을 SQL을 어떻게 처리할 것인지를 정의한다

사용자의 요구사항에 맞게 어떠한 작업을 처리할지, 추상 메서드로 정의한다

Long submit(BVO bo);	//글 추가작업
BVO get(int bnum);		//특정 게시글 조회
boolean modify(BVO bo);	//글 수정
boolean del(int bnum);	//글 삭제	
List<BVO> getList();	//글 전체 조회

 

service 인터페이스를 구현한 클래스

전체코드

  • 비즈니스 로직에 맞는 메서드를 작성하고, 매핑된 쿼리메서드를 불러온다

 

서비스 클래스로 사용하기 위해서 설정을 추가한다

@Service
비즈니스 로직, 사용자의 요구사항을 반영한다
@Log4j
@RequiredArgsConstructor
→ final, @Notnull를 사용한 필드에 대한 생성자를 자동으로 생성
→ 의존성 주입을 편리하게 한다

@Autowired는 필드주입(비권장), @RequiredArgsConstructor 생성자 주입(권장)

 

private final BMapper mapper;
  • 실제 쿼리문이 매핑된 클래스(BMapper)의 생성자가 만들어 진다
  • 게시글 전체조회 / 추가 / 수정 / 삭제 등 매핑된 메서드를 이용하여 메서드를 만든다

 

public class BServiceImpl implements BService{
	private final BMapper mapper;

	//글 추가작업
	@Override
	public Long submit(BVO bo) {
		mapper.inkey(bo);
		return bo.getBnum();
	}

	//글 전체 조회
	@Override
	public List<BVO> getList() {
		return mapper.getList();
	}

	//특정 게시글 조회
	@Override
	public BVO get(int bnum) {
		return mapper.getBoardOne(bnum);
	}

	//글 수정
	public boolean modify(BVO bo) {
		return mapper.up(bo) == 1;
	}

	//글 삭제
	@Override
	public boolean del(int bnum) {
		return mapper.del(bnum) == 1;
		//해당 글이 있으면 1(true)를 반환하여 test 실행
	}
}

 

 

Mapper 클래스와 쿼리문이 있는 Mapper.xml 파일

더보기

Mapper 클래스

package co.sol.mapper;

public interface BMapper {
	public List<BVO> getList();		//전체 조회
	public BVO getBoardOne(int bnum);	//조회
	public void insert(BVO vo);		//입력
	public void inkey(BVO vo);		//selectKey
	public int up(BVO vo);			//수정
	public int del(int bnum);			//삭제
}

 

Mapper  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="co.sol.mapper.BMapper">
	<!-- 기본 조회 sql, 재사용을 위해서 정의 -->
	<sql id="boardSelect">
		select * from t_board
	</sql>

	<!-- 전체 조회  -->
	<select id="getList" resultType="co.sol.main.BVO" >
		<include refid="boardSelect"></include>
		order by bnum desc
	</select>

	<!-- 1건 조회  -->
	<select id="getBoardOne" resultType="co.sol.main.BVO">
		<include refid="boardSelect"></include>
		WHERE bnum=#{bnum}
	</select>

	<!-- 게시물 추가  -->
	<insert id="insert"> <!-- parameterType="co.sol.main.BVO"  -->
		insert into t_board(bnum, title, content, writer) values (seq_bo.nextval, #{title}, #{content}, #{writer})
	</insert>
	
	<!-- 게시물 추가 전 selectKey 추출 -->
	<insert id="inkey">
		<selectKey keyProperty="bnum" order="BEFORE" resultType="long">
			select seq_bo.nextval from dual
		</selectKey>
		insert into t_board(bnum, title, content, writer) values (#{bnum}, #{title}, #{content}, #{writer})
	</insert>
	
	<!-- 게시물 수정  -->
	<update id="up">
		UPDATE t_board 
 		SET title=#{title}, content=#{content}, writer=#{writer}, updateDate=sysdate 
 		WHERE bnum=#{bnum}
	</update>
	
	<!-- 게시물 삭제 -->
	<delete id="del">
		delete from t_board where bnum=#{bnum}
	</delete>
</mapper>

 

<selectKey keyProperty="bnum" order="BEFORE" resultType="long">
    select seq_bo.nextval from dual
</selectKey>
  • seq_bo.nextval를 추출(PK)을 해서 insert 실행 시 추가한다 
  • keyProperty :  저장할 변수
  • order : 추출 실행 시점

 

빈 등록

<context:component-scan base-package="co.sol.service" />

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 -->

	<bean class="com.zaxxer.hikari.HikariConfig" id="hikariConfig">
		<property value="net.sf.log4jdbc.sql.jdbcapi.DriverSpy"
			name="driverClassName" />
		<property
			value="jdbc:log4jdbc:oracle:thin:@localhost:1521/xepdb1"
			name="jdbcUrl" />
		<property value="아이디" name="username" />
		<property value="비번" name="password" />
	</bean>

	<bean class="com.zaxxer.hikari.HikariDataSource" id="dataSource"
		destroy-method="close">
		<constructor-arg ref="hikariConfig" />
	</bean>

	<bean class="org.mybatis.spring.SqlSessionFactoryBean"
		id="sqlSessionFactory">
		<property name="dataSource" ref="dataSource" />
	</bean>

<mybatis-spring:scan base-package="co.sol.mapper"/>
<context:component-scan base-package="co.sol.service" />

</beans>

 

테스트코드

테스트 코드를 작성하여 단위 테스트를 실행한다

더보기
package co.sol.service;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("file:src/main/webapp/WEB-INF/spring/root-context.xml")
@Log4j
public class BServiceTests {
	@Autowired
	private BService service;

	//전체목록 조회
	@Test
	public void testGetList(){
		log.info(service.getList());
	}

	//특정 게시글 조회
	@Test
	public void testget() {
		log.info(service.get(121));
	}

	//글 추가작업
	@Test
	public void testsubmit() {
		BVO bb = new BVO();
		
		bb.setTitle("spring");
		bb.setContent("spring content");
		bb.setWriter("new writer");

		log.info("-------------- testsubmit() ");
		log.info(service.submit(bb));
	}
	
	//글 수정
	@Test
	public void testmodify() {
		BVO bb = service.get(21);
		
		if(bb == null) {
			return;
		}
		bb.setTitle("글 수정 boolean");
		bb.setContent("글을 수정합니다.boolean");
		bb.setWriter("boolean");

		log.info(service.modify(bb));
	}
	
	//글 삭제
	@Test
	public void testdel() {
		log.info(service.del(22));
	}
}

테스트 코드를 사용하기 위해서 초기 설정을 한다

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("file:src/main/webapp/WEB-INF/spring/root-context.xml")
@Log4j
@Autowired
private BService service;
  • 비즈니스 로직이 있는 service 인터페이스를 필드 주입 받는다

 

  • 목록조회 메서드와 쿼리문
@Test
public void testGetList(){
    log.info(service.getList());
}
//전체 조회
public List<BVO> getList();

<select id="getList" resultType="co.sol.main.BVO" >
    <include refid="boardSelect"></include>
    order by bnum desc
</select>

@Test
public void testget() {
    log.info(service.get(121));
}
//1건 조회
public BVO getBoardOne(int bnum);

<select id="getBoardOne" resultType="co.sol.main.BVO">
    <include refid="boardSelect"></include>
    WHERE bnum=#{bnum}
</select>

 

  • 글 등록
@Test
public void testsubmit() {
    BVO bb = new BVO();

    bb.setTitle("spring");
    bb.setContent("spring content");
    bb.setWriter("new writer");

    log.info("-------------- testsubmit() ");
    log.info(service.submit(bb));
}
//글 추가작업
public void insert(BVO vo);

<insert id="insert"> <!-- parameterType="co.sol.main.BVO"  -->
    insert into t_board(bnum, title, content, writer) values (seq_bo.nextval, #{title}, #{content}, #{writer})
</insert>

 

  • 글 등록 시 selectKey를 사용하여 PK를 추출 후 글 번호로 사용하여 등록
public void inkey(BVO vo);
//게시물 추가 전 selectKey 추출
<insert id="inkey">
    <selectKey keyProperty="bnum" order="BEFORE" resultType="long">
        select seq_bo.nextval from dual
    </selectKey>
	insert into t_board(bnum, title, content, writer) values (#{bnum}, #{title}, #{content}, #{writer})
</insert>

 

 

  • 글 수정
@Test
public void testmodify() {
    BVO bb = service.get(21);

    if(bb == null) {
        return;
    }
    bb.setTitle("글 수정 boolean");
    bb.setContent("글을 수정합니다.boolean");
    bb.setWriter("boolean");

    log.info(service.modify(bb));
}
//수정
public int up(BVO vo);

<update id="up">
    UPDATE t_board 
    SET title=#{title}, content=#{content}, writer=#{writer}, updateDate=sysdate 
    WHERE bnum=#{bnum}
</update>

 

  • 글 삭제
@Test
public void testdel() {
    log.info(service.del(22));
}
//삭제
public int del(int bnum);

<delete id="del">
    delete from t_board where bnum=#{bnum}
</delete>

 

 

 

 

 

 

 

 

 

728x90
728x90