프로그래밍 2017. 3. 16. 11:30

공지사항 등록 비즈니스 로직


1. Controller 구현

 - request 등록을 수행하는 regNotice 메소드의 return 값은 정상적으로 처리하면 "redirect:/notice/공지사항목록화면"으로 처리해야 됩니다. 공지사항 목록화면 구현 후 수정하시면 됩니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package com.devdic.board.controller;
 
import javax.servlet.http.HttpServletRequest;
 
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
 
import com.devdic.board.service.NoticeService;
import com.devdic.board.vo.NoticeVO;
 
@Controller
public class NoticeController {
    
    @Autowired
    public NoticeService noticeService;
    
    private static final Logger logger = LoggerFactory.getLogger(NoticeController.class);
    
    // 등록화면 보여주기
    @RequestMapping(value="/regNoticeView")
    public String regNoticeView(HttpServletRequest request) throws Throwable {
        
        return "/notice/regNotice";
    }
    
    // request정보 등록
    @RequestMapping(value="/regNotice")
    public String regNotice(HttpServletRequest request, NoticeVO noticeVO) throws Throwable {
        noticeService.regNotice(request, noticeVO);
        return "/notice/regNotice";
    }
}
 
cs


2. Service 구현(interface제외)

 - 공지사항 등록이 비즈니스 로직을 담당


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
package com.devdic.board.service.impl;
 
import java.util.List;
 
import javax.servlet.http.HttpServletRequest;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
 
import com.devdic.board.dao.NoticeDao;
import com.devdic.board.service.NoticeService;
import com.devdic.board.vo.NoticeVO;
import com.devdic.util.file.FileUpload;
 
@Service
public class NoticeServiceImpl implements NoticeService{
    
    @Autowired
    public NoticeDao noticeDao;
 
    @Override
    public int regNotice(HttpServletRequest req, NoticeVO noticeVO) throws Exception {
        // TODO Auto-generated method stub
        
        // 공지사항 정보 등록
        insertNotice(noticeVO);
        
        FileUpload fileUpload = new FileUpload();
        List<NoticeVO> list= fileUpload.parseInsertFileInfo(req);
        int i = 0;
        for(NoticeVO fileList: list){
            i++;
            noticeVO.setAttFileId(i);
            noticeVO.setAttFileNm(fileList.getAttFileNm());
            noticeVO.setAttFileSaveNm(fileList.getAttFileSaveNm());
            noticeVO.setAttFileSize(fileList.getAttFileSize());
            noticeVO.setDelYn("N");
            // 첨부파일 등록
            insertAttFile(noticeVO);
        }
        return 0;
    }
    
    private int insertNotice(NoticeVO noticeVO) throws Exception{
        return noticeDao.insertNotice(noticeVO);
    }
    
    private int insertAttFile(NoticeVO notieceVO) throws Exception{
        return noticeDao.insertAttFile(notieceVO);
    }
 
}
 
cs


3. Repository(DAO) 구현(interface제외)

 - namespace는 mapper(notice.xml)에 정의된 namespace 값입니다.

 - 4.SQL작성의 notice.xml을 확인하세요!


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package com.devdic.board.dao.impl;
 
import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
 
import com.devdic.board.dao.NoticeDao;
import com.devdic.board.vo.NoticeVO;
 
@Repository
public class NoticeDaoImpl implements NoticeDao{
    
    @Autowired
    private SqlSessionTemplate sqlSession;
    
    private final String namespace = "SqlMapNoticeDao";
    
    public int insertNotice(NoticeVO noticeVO) throws Exception{
        return sqlSession.insert(namespace+".insertNotice", noticeVO);
    }
    
    public int insertAttFile(NoticeVO noticeVO) throws Exception{
        return sqlSession.insert(namespace+".insertAttFile", noticeVO);
    }
 
}
 
cs


4. SQL 작성

 - root-context.xml 설정파일에서 mybatis 설정부분을 보면...

   mapper(SQL) 파일의 경로를 설정한 것이 기억나시죠^^

   

1
2
<!-- SQL(mapper) 경로 지정 -->
<property name="mapperLocations" value="classpath:sqlMap/**/*.xml"/>
cs


아래의 그림처럼 공지사항과 관련된 SQL을 작성하기 위한 notice.xml 파일을 하나 생성합니다.



notice.xml을 아래의 코드를 참조하여 작성합니다.

mybatis의 바인드 처리는 "#"으로 처리하시면 됩니다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.2//EN" "http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
 
<mapper namespace="SqlMapNoticeDao">
 
    <insert id="insertNotice" parameterType = "com.devdic.board.vo.NoticeVO">
    <selectKey keyProperty="noticeId" resultType="int" order="BEFORE">
        SELECT NVL(MAX(NOTICE_ID) + 1, 1) AS NOTICE_ID FROM TB_NOTICE 
    </selectKey>
    INSERT INTO TB_NOTICE(NOTICE_ID, NOTICE_TITLE, NOTICE_CONTENT, DEL_YN)
    VALUES(#{noticeId}, #{noticeTitle}, #{noticeContent}, #{delYn})
    </insert>
    
    <insert id="insertAttFile" parameterType = "com.devdic.board.vo.NoticeVO">
    INSERT INTO TB_ATT_FILE(NOTICE_ID, FILE_ID, ATT_FILE_SAVE_NM, ATT_FILE_NM, ATT_FILE_SIZE, DEL_YN)
    VALUES(#{noticeId}, #{attFileId}, #{attFileSaveNm}, #{attFileNm}, #{attFileSize}, #{delYn})
    </insert>
    
</mapper>
 
cs



공지사항 등록을 위한 소스구현은 되었으니, 테스트를 해봐야죠~~~

posted by 생각퍼즐
:
프로그래밍 2017. 2. 21. 00:59


Request 정보 처리를 위한 설정


사용자가 공지사항 등록화면에서 입력한 정보와 첨부파일 정보를 저장할 테이블을 생성하고 DB연동을 위한 Datasource 설정, Mybatis연동 설정, Transaction설정, 파일처리를 위한 multipartResolver 설정을 차례대로 설명하겠습니다.


1. Database 테이블 생성


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
/*
    공지사항 정보 저장
*/
CREATE TABLE SCOTT.TB_NOTICE(
NOTICE_ID       NUMBER(10),
NOTICE_TITLE    VARCHAR2(200),
NOTICE_CONTENT  VARCHAR2(4000),
DEL_YN          CHAR(1)
)
TABLESPACE USERS
STORAGE
(
    INITIAL 64K
    NEXT 1M
)
NOCOMPRESS;
 
/*
    공지사항 첨부파일 정보 저장
*/
CREATE TABLE SCOTT.TB_ATT_FILE(
NOTICE_ID           NUMBER(10),
FILE_ID             NUMBER(3),
ATT_FILE_SAVE_NM    VARCHAR2(200),
ATT_FILE_NM         VARCHAR2(4000),
ATT_FILE_SIZE       NUMBER(10),
DEL_YN              CHAR(1)
)
TABLESPACE USERS
STORAGE
(
    INITIAL 64K
    NEXT 1M
)
NOCOMPRESS;
 
ALTER TABLE SCOTT.TB_NOTICE
ADD CONSTRAINT PK_TB_NOTICE PRIMARY KEY (NOTICE_ID);
 
ALTER TABLE SCOTT.TB_ATT_FILE
ADD CONSTRAINT PK_TB_ATT_FILE PRIMARY KEY (NOTICE_ID, FILE_ID);
 
ALTER TABLE SCOTT.TB_ATT_FILE
ADD CONSTRAINT FK_TB_ATT_FILE FOREIGN KEY (NOTICE_ID) REFERENCES SCOTT.TB_NOTICE (NOTICE_ID);
cs



2. Datasource 및 Transaction 설정

 - root-context.xml 파일을 참조하여 네임스페이스와 설정 정보를 추가합니다.

 - oracle Driver를 찾지 못하는 error가 발생하면, 오라클 설치 폴더에서 ojdbc를 찾아 JAVA를 설치한 곳으로 복사하면 error가 해결됩니다.

=> 오라클홈 -> jdbc -> lib -> ojdbc6.jar 파일을

=> 자바설치폴더 -> jre -> lib -> ext 폴더로 복사


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
<?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:tx="http://www.springframework.org/schema/tx"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
                        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
                        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
                        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
    
    <!--  
        @Service, @Repository 스트레오타입 어노테이션이 선언된 클래스를 빈으로 등록한다.
    -->
     <context:component-scan base-package="com.devdic.board">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Service"/>
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>
    
    <context:annotation-config/>
    
    <!-- 
    datasource 설정에 필요한 라이브러리 추가를 위해 아래의 내용을 pom.xml에 추가필요
    <dependency>
        <groupId>commons-dbcp</groupId>
        <artifactId>commons-dbcp</artifactId>
        <version>1.3</version>
    </dependency>
    -->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
        <property name="url" value="jdbc:oracle:thin@127.0.0.1:1521:orcl" />
        <property name="username" value="SCOTT"/>
        <property name="password" value="SCOTT"/>
    </bean>
    
    <!-- Transaction 설정 -->
    <!-- 
    Transaction 설정에 필요한 라이브러리 추가를 위해 아래의 내용을 pom.xml에 추가
    <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>${org.springframework-version}</version>
    </dependency>  
     -->
     <!-- dataSource를 활용하는 트랜잭션 매니저를 등록 -->
     <!-- dataSource 빈을 DataSourceTransactionManager 트랜잭션 매니저의 dataSource 속성에 지정  -->
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    
    <!-- AOP advisor 를 활용하여 트랜잭션을 처리함
        아래의 dependency를 pom.xml에 추가 
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.9</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.8.9</version>
        </dependency>
    -->
     <tx:advice id="txAdvice" transaction-manager="txManager">
       <tx:attributes>
       <!--
            모든 메소드에 대해서 트랜잭션을 REQUIRED 으로 지정하고
            Exception 발생 시 롤백 지정
        -->
       <tx:method name="*" propagation="REQUIRED" rollback-for="Exception"/>
       </tx:attributes>
    </tx:advice>
    <!-- 
    com.devdic.board 아래의 클래스 명이 ~~~ServiceImpl로 끝나는
    클래스 내의 모든 메소드는 트랜재션 처리가 된다.
     -->
    <aop:config><!-- execution(* *..service.impl.*ServiceImpl.*(..)) -->
        <aop:pointcut id="requiredTx" expression="execution(* com.devdic.board..*ServiceImpl.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="requiredTx" />
    </aop:config>
cs


3. myBatis 연동

 3.1  root-context.xml에 아래의 myBatis 연동 설정 정보 추가


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<!--  Mybatis 연동
    pom.xml 추가
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.4.1</version>
    </dependency>
    
    마이바티스 스프링 연동 모듈
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis-spring</artifactId>
        <version>1.3.0</version>
    </dependency>
    -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <!-- mybatis config파일 경로 지정 -->
        <property name="configLocation" value="/WEB-INF/config/mybatis-config.xml"/>
        
        <!-- SQL(mapper) 경로 지정 -->
        <property name="mapperLocations" value="classpath:sqlMap/**/*.xml"/>
    </bean>
    
    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
          <constructor-arg ref="sqlSessionFactory" />
    </bean>
cs


3.2 WEB-INF -> config(폴더생성) -> mybatis-config.xml(파일 추가)

 - mybatis-config.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.2//EN" "HTTP://mybatis.org/dtd/mybatis-3-config.dtd">
 
<configuration>
    <settings>
        <setting name="cacheEnabled" value="false" />
        <setting name="useGeneratedKeys" value="true" />
        <setting name="defaultExecutorType" value="BATCH" />
        <setting name="jdbcTypeForNull" value="NULL" />
        <setting name="callSettersOnNulls" value="true" />
    </settings>
 
    <typeAliases>
        <typeAlias type="java.util.Map" alias="map"/>
    </typeAliases>
 
    <mappers>
    </mappers>
</configuration>
cs



4. 첨부파일 처리를 위한 multipartResolver 설정
  - root-context.xml 파일에 아래와 같이 추가합니다.
  - dependency 추가를 위한 정보는 주석부분을 참조하세요!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    <!-- MultipartResolver -->
    <!-- 
        <dependency>
            <groupId>commons-fileupload</groupId>
                <artifactId>commons-fileupload</artifactId>
            <version>1.3.1</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.4</version>
        </dependency>
     -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">   
<property name="maxUploadSize" value="50000000"></property>
    </bean>
 
cs


posted by 생각퍼즐
: