KOSA Server - 비즈니스 계층 (Service)

채정윤·2025년 4월 18일

Spring

목록 보기
14/25
  • 역할: 컨트롤러와 데이터 계층(DAO/Repository) 사이에서 핵심 로직을 담당
  • 기능: 여러 데이터 처리 과정을 조합하거나, 조건에 따라 다른 처리를 수행
  • 장점: 로직을 재사용 가능하게 하고, 유지보수를 쉽게 해줌

요청 → 디스패처 → 컨트롤러 → 서비스 → DB → 서비스 → 컨트롤러 → 뷰

🗺️ interface BoardService.java

설계도 역할

package org.zerock.service;

import java.util.List;

import org.zerock.domain.BoardVO;
//import org.zerock.domain.Criteria;

public interface BoardService {

	public void register(BoardVO board);

	public BoardVO get(Long bno);

	public boolean modify(BoardVO board);

	public boolean remove(Long bno);

	// public List<BoardVO> getList();

//	public List<BoardVO> getList(Criteria cri);

	//추가
//	public int getTotal(Criteria cri);

}

🔩 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="org.zerock.mapper.BoardMapper">

	<sql id="criteria">
		<trim prefix="(" suffix=") AND " prefixOverrides="OR">
			<foreach item='type' collection="typeArr">
				<trim prefix="OR">
					<choose>
						<when test="type == 'T'.toString()">
							title like '%'||#{keyword}||'%'
						</when>
						<when test="type == 'C'.toString()">
							content like '%'||#{keyword}||'%'
						</when>
						<when test="type == 'W'.toString()">
							writer like '%'||#{keyword}||'%'
						</when>
					</choose>
				</trim>
			</foreach>
		</trim>
	</sql>

	<select id="getList" resultType="org.zerock.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>

	<insert id="insertSelectKey">

		<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="org.zerock.domain.BoardVO">
		select * from tbl_board where bno =
		#{bno}
	</select>

	<delete id="delete">
		delete 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>

	<!-- <select id="getListWithPaging" resultType="org.zerock.domain.BoardVO"> 
		<![CDATA[ select bno, title, content, writer, regdate, updatedate from ( 
		select /*+INDEX_DESC(tbl_board pk_board) */ rownum rn, bno, title, content, 
		writer, regdate, updatedate from tbl_board where rownum <= #{pageNum} * #{amount} 
		) where rn > (#{pageNum} -1) * #{amount} ]]> </select> -->

	<select id="getListWithPaging"
		resultType="org.zerock.domain.BoardVO">
  <![CDATA[
  select 
    bno, title, content, writer, regdate, updatedate
  from 
      (
      select /*+INDEX_DESC(tbl_board pk_board) */
        rownum rn, bno, title, content, writer, regdate, updatedate 
      from 
        tbl_board
      where 
  ]]>
		<trim prefix="(" suffix=") AND " prefixOverrides="OR">
			<foreach item='type' collection="typeArr">
				<trim prefix="OR">
					<choose>
						<when test="type == 'T'.toString()">
							title like '%'||#{keyword}||'%'
						</when>
						<when test="type == 'C'.toString()">
							content like '%'||#{keyword}||'%'
						</when>
						<when test="type == 'W'.toString()">
							writer like '%'||#{keyword}||'%'
						</when>
					</choose>
				</trim>
			</foreach>
		</trim>
      
  <![CDATA[    
      rownum <= #{pageNum} * #{amount}
      )
  where rn > (#{pageNum} -1) * #{amount}   
  ]]>
	</select>

	<select id="getTotalCount" resultType="int">
		select count(*) from tbl_board where 
		
		<include refid="criteria"></include> 
		
		bno > 0
		
	</select>

</mapper>

🅱️ BoardServiceImpl.java

서비스(Service)에서 마이바티스(MyBatis)의 Mapper를 호출

= "서비스가 실제로 데이터베이스(DB)에서 값을 가져오거나 저장하려고 Mapper한테 부탁하는 것"

@AllArgsConstructor: 모든 필드 넣는 생성자 자동 생성

  • private Mapper mapper가 있으면, 생성자에 포함됨
  • Spring이 이 생성자를 이용해서 의존성 주입 해줌
  • 즉, 우리가 직접 생성자 만들거나 @Autowired 안 써도 됨
@Service
@Log4j
@AllArgsConstructor // 알아서 mapper 주입해줌
public class BoardServiceImpl **implements BoardService** {
	
	// 마이바티스 호출을 위해!!
	private BoardMapper mapper;
	
	@Override
	public void register(BoardVO board) {
		log.info("register.........");
		mapper.insertSelectKey(board);
	}
	
	@Override
	public List<BoardVO> getList() {
		log.info("getList.............");
		return mapper.getList();
	}

	@Override
	public BoardVO get(Long bno) {
		log.info("get.............");
		return mapper.read(bno);
	}

	@Override
	public boolean modify(BoardVO board) {
		log.info("modify.............");
		return mapper.update(board) == 1;
	}

	@Override
	public boolean remove(Long bno) {
		log.info("remove.............");
		return mapper.delete(bno) == 1;
	}
}

🧑‍💼 BoardController

작성순서

  1. @Controller 어노테이션
  2. @AllArgsConstructor 모든 필드 넣는 생성자 자동 생성을 위해
  3. @RequestMapping("/board/*") 특정경로 매핑해놓기
  4. @Log4j
  5. service
  6. @GetMapping("/register")
    • void : url경로 그대로 jsp를 찾아간다!
    • string : return "jsp 이름";
      • redirect:/ 하는 경우 무조건 사용
@Controller
@Log4j
@RequestMapping("/board/*") // board경로인 애들 다 매핑
@AllArgsConstructor
public class BoardController {
	
	private BoardServiceImpl service;
	
	@GetMapping("/register")
	public void register() {}
	
	@PostMapping("/register")
	public String register(BoardVO board) {
		service.register(board);
		
		return "redirect:/board/list";
	}
	
	@GetMapping("/list")
	// 목록 가져올 데이터가 있을때 Model이라고 선언해주기!~!~!
	public void getList(Model model) { 
	    model.addAttribute("list", service.getList());
	}
	
	@GetMapping("/get")
	public void get(@RequestParam("bno") Long bno, Model model) {
		model.addAttribute("board", service.get(bno));
	}
	
	@GetMapping("/modify")
	public void modify(@RequestParam("bno") Long bno, Model model) {
		model.addAttribute("board", service.get(bno));
	}
	
	@PostMapping("/modify")
	public String modify(BoardVO board) {
		service.modify(board);
		
		return "redirect:/board/list";
	}
	
	@PostMapping("/remove")
	public String remove(Long bno) {
		service.remove(bno);
		
		return "redirect:/board/list";
	}
}

📺 register.jsp

<form role="form" action="/board/register" method="post">
  <div class="form-group">
    <label>Title</label> <input class="form-control" name='title'>
  </div>

  <div class="form-group">
    <label>Text area</label>
    <textarea class="form-control" rows="3" name='content'></textarea>
  </div>

  <div class="form-group">
    <label>Writer</label> <input class="form-control" name='writer'>
  </div>
  <button type="submit" class="btn btn-default">Submit
    Button</button>
  <button type="reset" class="btn btn-default">Reset Button</button>
</form>

0개의 댓글