파라미터의 결정

 

Spring MVC는 메소드의 파라미터와 리턴타입을 설계할 때 정하고 작성해야 합니다.

 

- 파라미터의 수집은 Spring MVC에서 자동으로 하기 때문에, 파라미터의 수집이 필요하면 원하는 객체를 파라미터로 정한다.

 

- 예외적인 상황이 아니라면 VO 또는 DTO 클래스를 파라미터로 사용하는 것이 용이합니다.

 

- 브라우저에서 들어오는 요청이 자동으로 파라미터로 지정한 클래스의 객체 속성값으로 처리되는데 이를 바인딩(binding)이라고 합니다.

 

- Model 객체는 해당 메서드에서 리턴하는 뷰에 필요한 데이터를 전달하는 용도로 사용합니다.

 

 

 

'JAVA > blog' 카테고리의 다른 글

controller redirect  (0) 2020.07.09
controller 구현  (0) 2020.07.08
비즈니스 계층(service)  (0) 2020.07.08
persistence 계층(영속 계층)  (0) 2020.07.08
게시판 project 초기설정  (0) 2020.07.08

비즈니스 계층

 

비즈니스 계층은 사용자(고객)의 요구사항이 반영되는 영역입니다.

비즈니스 계층은 로직에 필요한 데이터베이스와 관련된 객체들을 자신이 원하는 일을 처리하도록 하는 용도로 사용됩니다.

이해가 되도록 말하자면 controller와 dao사이의 이어주는 역할을 한다고 이해하시면 됩니다.

 

 

개발 순서는 요구사항을 메소드로 인터페이스를 정의하고, 그 인터페이스를 구현하여 만들어 줍니다.

 

root-context.xml에 service 패키지를 알아서 인식할 수 있도록 합니다.

 

<!-- kr.co.web.persistence 패키지를 자동으로 인식 -->
	<context:component-scan base-package="kr.co.web.persistence">
	</context:component-scan>

 

 

인터페이스 BoardService 작성

 

package kr.co.web.service;

import java.util.List;

import kr.co.web.domain.BoardVO;

public interface BoardService {
	
	public void create(BoardVO board) throws Exception;
	
	public BoardVO read(Integer board_number) throws Exception;
	
	public void update(BoardVO board) throws Exception;
	
	public void delete(Integer board_number) throws Exception;
	
	public List<BoardVO> listAll() throws Exception;
}

 

이제 BoardService를 구현하기 위해 BoardServiceImpl.class를 작성하겠습니다.

 

package kr.co.web.service;

import java.util.List;

import javax.inject.Inject;

import org.springframework.stereotype.Service;

import kr.co.web.domain.BoardVO;
import kr.co.web.persistence.BoardDAO;

@Service
public class BoardServiceImpl implements BoardService{
	
	@Inject
	private BoardDAO boardDAO;
	
   	@Override
	public void create(BoardVO board) throws Exception {
		boardDAO.create(board);
	}
	
    	@Override
	public BoardVO read(Integer board_number) throws Exception {
		return boardDAO.read(board_number);
	}
	
    	@Override
	public void update(BoardVO board) throws Exception {
		boardDAO.update(board);
	}
	
   	@Override
	public void delete(Integer board_number) throws Exception {
		boardDAO.delete(board_number);
	}
	
    	@Override
	public List<BoardVO> listAll() throws Exception {
		return boardDAO.listAll();
	}

}

 

service 계층까지 작성했으니 이제 controller를 다룰 차례입니다!

'JAVA > blog' 카테고리의 다른 글

controller 구현  (0) 2020.07.08
controller를 작성하기 전에 알아야 할 사항  (0) 2020.07.08
persistence 계층(영속 계층)  (0) 2020.07.08
게시판 project 초기설정  (0) 2020.07.08
프로젝트 생성 후 character encoding setting  (0) 2020.07.06

persistence 계층에서는 DB에 접근하여 SQL문을 실행하고, 데이터를 VO형태로 읽고 쓸 수 있는 DAO(Data Acess Object)을 구현하는 작업을 수행 합니다.

 

Mybatis 초기설정

 

DAO를 구현하기 위해 최초 1회 설정해야하는 DB와의 연동 작업을 수행합니다.

- DataSource 등록

 

mysql 서버에 연결할 때 필요한 정보를 가지고 있는 DataSource를 root_context.xml에 추가 합니다.

 

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
	    <property name="driverClassName" value="com.mysql.jdbc.Driver"></property> 
	    <property name="url" value="jdbc:mysql://127.0.0.1:3306/blog?serverTimezone=UTC"></property>
	    <property name="username" value="root"></property>
	    <property name="password" value="1234"></property>
	</bean>

 

- DataSource Test

 

DataSource 객체가 제대로 생성이 되었는지 테스트 합니다.

 

package kr.co.web;

import java.sql.Connection;

import javax.inject.Inject;
import javax.sql.DataSource;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

//Runner 클래스(테스트 메소드를 실행하는 클래스) 를 SpringJUnit4ClassRunner로 함
@RunWith(SpringJUnit4ClassRunner.class)
//location 속성 경로에 있는 xml 파일을 이용해서 스프링이 로딩됨
@ContextConfiguration("file:src/main/webapp/WEB-INF/spring/**/root-context.xml")

public class DataSourceTest {
	
	//DataSource의 객체를  new를 사용해 따로 생성해줄 필요없이 스프링이 생성해서 주입해줌
	@Inject
	private DataSource ds;
	
	@Test
	public void testConnection() throws Exception{
		try(Connection con = ds.getConnection()){
			System.out.println(con);
		}catch(Exception e) {
			e.printStackTrace();
		}
	}
}

 

 

 

- XML 네임스페이스 추가

 

root-context.xml의 NameSpaces를 다른 확장자도 사용할 수 있도록 추가합니다.

 

 

 

- mybatis-config.xml 추가

mybatis의 별도 설정을 담당하기 위한 파일로 mybatis-config.xml 파일을 src/main/resource에 추가

 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
    PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

</configuration>

 

 

- root-context.xml에 SqlSessionFactory, SqlSessionTemplate 추가

 

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
	    <property name="dataSource" ref="dataSource"></property>
	    <property name="configLocation" value="classpath:/mybatis-config.xml"></property>
	    <property name="mapperLocations" value="classpath:mappers/**/*Mapper.xml"></property>
	</bean>
	
	<!-- sqlSessionTemplate -->
	<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"
	    destroy-method="clearCache">
	    <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"></constructor-arg>
	</bean>
	
	<!-- kr.co.web.persistence 패키지를 자동으로 인식 -->
	<context:component-scan base-package="kr.co.web.persistence">
	</context:component-scan>

 

 

- MyBatis Test

 

MyBatis와 Mysql이 제대로 연결 되었는지 테스트

 

package kr.co.web;

import javax.inject.Inject;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

//Runner 클래스(테스트 메소드를 실행하는 클래스) 를 SpringJUnit4ClassRunner로 함
@RunWith(SpringJUnit4ClassRunner.class)
//location 속성 경로에 있는 xml 파일을 이용해서 스프링이 로딩됨
@ContextConfiguration("file:src/main/webapp/WEB-INF/spring/**/root-context.xml")

public class MyBatisTest {
	
	//SqlSessionFactory 객체를 자동으로 생성
	@Inject
	private SqlSessionFactory sqlFactory;
	
	//SqlSessionFactory 객체가 제대로 만들어졌는지 Test
	@Test
	public void testFactory() {
		System.out.println(sqlFactory);
	}
	
	//MyBatis와 Mysql 서버가 제대로 연결되었는지 Test
	@Test
	public void testSession() throws Exception{
		try(SqlSession session = sqlFactory.openSession()){
			System.out.println(session);
		}catch(Exception e) {
			e.printStackTrace();
		}
	}
}

 

 

 

 

Board 테이블 생성

 

워크벤치에 board 테이블을 생성(워크벤츠 사용법은 어렵지 않기 떄문에 검색!)

 

CREATE TABLE board (
    board_number int NOT NULL AUTO_INCREMENT,
    title varchar(200) NOT NULL,
    contents text,
    name VARCHAR(30) NOT NULL,
    create_date timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
    view_count int DEFAULT 0,
    PRIMARY KEY (board_number)
    );

 

 

정상적으로 테이블이 생성되었습니다.

 

이제 SQL을 실행할 boardMapper.xml을 추가합니다.

 

<!-- /resource/mappers/boardMapper.xml -->

<?xml version="1.0" encoding="UTF-8"?>

<!-- DTD 선언 -->
<!DOCTYPE mapper
	PUBLIC "-//mybatis.org/DTD Mapper 3.0//EN"
	"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
	
<mapper namespace="BoardMapper">

	<!-- 데이터 삽입 -->
	<insert id="create">
		insert into board (title, contents, name)
		values( #{title}, #{contents}, #{name})
	</insert>
	
	<!-- 행 검색 -->
	<select id="read" resultType="kr.co.web.domain.BoardVO">
		select *
		from board
		where board_number = #{board_number}
	</select>
    
	<!-- 행 수정 -->
	<update id="update">
		update board
		set title = #{title}, contents = #{contents}
		where board_number = #{board_number}
	</update>
    
	<!-- 행 삭제 -->
	<delete id="delete">
		delete from board where board_number = #{board_number}
	</delete>
    
	<!-- board 전체 행 조회 -->
	<select id="listAll" resultType="kr.co.web.domain.BoardVO">
		select *
		from board
		order by board_number desc, regdate desc
	</select>
    
	<!-- bno 최대 구하기 -->
	<select id="getMaxBno" resultType="Integer">
		select max(board_number) from board
	</select>	
    
</mapper>

 

resultType 

- resultType을 사용하게 되면 결과 값을 BoardVO의 setter에 값을 넣어주고, 이용자는 getter를 통해 해당 데이터를 이용할 수 있다.

 

 

BoardVO 구현

 

DB를 이용할 때 데이터를 넣고 데이터를 가져와서 사용하기 위해 데이터를 담을 공간인 BoardVO를 작성합니다.

 

package kr.co.web.domain;

import java.util.Date;

public class BoardVO {
	private Integer board_number;
	private String title;
	private String contents;
	private String name;
	private Date create_date;
	private int view_count;
	
	public Integer getBoard_number() {
		return board_number;
	}
	
	public void setBoard_number(Integer board_number) {
		this.board_number = board_number;
	}
	
	public String getTitle() {
		return title;
	}
	
	public void setTitle(String title) {
		this.title = title;
	}
	
	public String getContents() {
		return contents;
	}
	
	public void setContents(String contents) {
		this.contents = contents;
	}
	
	public String getName() {
		return name;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	public Date getCreate_date() {
		return create_date;
	}
	
	public void setCreate_date(Date create_date) {
		this.create_date = create_date;
	}
	
	public int getView_count() {
		return view_count;
	}
	
	public void setView_count(int view_count) {
		this.view_count = view_count;
	}
	
	@Override
	public String toString() {
		return "BoardVO [board_number=" + board_number + ", title=" + title + ", contents=" + contents + ", name=" + name + ", create_date="
				+ create_date + ", view_count=" + view_count + "]";
	}
}

 

 

DAO 인터페이스 작성

 

 

좀전에 만들었던 BoardMapper.xml에 SQL문을 실제로 실행하기 위해 

BoardDAO.java 인터페이스를 kr.co.web.persistence에 작성합니다.

 

package kr.co.web.persistence;

import java.util.List;

import kr.co.web.domain.BoardVO;

public interface BoardDAO {

	public void create(BoardVO board) throws Exception;
	
	public BoardVO read(Integer board_number) throws Exception;
	
	public void update(BoardVO board) throws Exception;
	
	public void delete(Integer board_number) throws Exception;
	
	public List<BoardVO> listAll() throws Exception;
	
	public Integer getMaxBoard_number() throws Exception;
}

 

이제 BoardDAO 인터페이스의 메소드를 구현합니다.

 

package kr.co.web.persistence;

import java.util.List;

import javax.inject.Inject;

import org.apache.ibatis.session.SqlSession;

import kr.co.web.domain.BoardVO;

@Repository
public class BoardDAOImpl implements BoardDAO{

	// SQL문을 실행하는 메소드를 가지고 있는 SqlSession을 구현한 SqlSessionTemplate을 찾아서 객체를 자동으로 생성
	@Inject
	private SqlSession session;
	
	private static String NS = "BoardMapper";
	private static String CREATE = NS + ".create";
	private static String READ = NS + ".read";
	private static String UPDATE = NS + ".update";
	private static String DELETE = NS + ".delete";
	private static String LISTALL = NS + ".listAll";
	private static String GETMAXBOARD_NUMBER = NS + ".getMaxBno";
	
	@Override
	public void create(BoardVO board) throws Exception {
		session.insert(CREATE, board);
		// 글을 작성할 때 입력한 값을 boardVO에 넣어주기 위해 파라미터값을 board로 함
	}
	
	@Override
	public BoardVO read(Integer board_number) throws Exception {
		return session.selectOne(READ, board_number);
		// 글을 읽기 위해 mapper에 where절에 게시글번호가 필요하기 때문에 board_number로 설정하고 boardVO를 리턴값으로 설정
	}
	
	@Override
	public void update(BoardVO board) throws Exception {
		session.update(UPDATE, board);
	}
	
	@Override
	public void delete(Integer board_number) throws Exception {
		session.delete(DELETE, board_number);
	}
	
	@Override
	public List<BoardVO> listAll() throws Exception {
		return session.selectList(LISTALL);
	}
	
	@Override
	public Integer getMaxBoard_number() throws Exception {
		return session.selectOne(GETMAXBOARD_NUMBER);
	}
}

 

 

typeAliases 적용

 

BoardMapper.xml에 있는 쿼리문에서 resultType을 패키지명과 같이 작성하였는데

MyBatis의 설정 파일인 mybatis-config.xml을 이용하여 typeAliases를 사용하면

resultType에 패키지명을 붙이지 않아도 됩니다.

 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
    PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	
	<typeAliases>
		<package name="kr.co.web.domain" />
	</typeAliases>
	
</configuration>

 

+ Recent posts