호쌤
호쌤 Just For Fun

[Java,Spring] Service 패턴

크리에이티브 커먼즈 라이선스 ITPAPER(호쌤,쭈쌤)에 의해 작성된 ≪[Java,Spring] Service 패턴≫은(는) 크리에이티브 커먼즈 저작자표시-비영리-동일조건변경허락 4.0 국제 라이선스에 따라 이용할 수 있습니다.
이 라이선스의 범위 이외의 이용허락을 얻기 위해서는 leekh4232@gmail.com으로 문의하십시오.

[Java,Spring] Service 패턴

서비스 패턴이란 DB를 통해 수행되는 비지니스 로직을 구현하는 계층을 의미합니다. 요구사항 정의 과정에서 도출되는 기능들을 명시하고 구현하는 계층이라 이해할 수 있습니다.

#01. Service 계층의 구조

service

#02. Serivce 정의 과정

1) 수행해야 할 기능을 요구사항에 맞게 인터페이스로 정의

프로젝트 기획단계에서 도출되는 요구사항에 따라 정의되지만 기본적으로 목록조회, 상세조회, 데이터 갯수 조회, 입력, 수정, 삭제의 기능은 필수적으로 요구된다.

Service 인터페이스의 기본 패턴

아래의 코드 패턴에서 패키지 이름을 확인하고 {DTO} 라는 키워드를 사용하고자 하는 클래스 이름으로 일괄 변경해서 사용한다.

{DTO}Service.java
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
package ###################;

import java.util.List;

/** {DTO} 데이터 관리 기능을 제공하기 위한 Service 계층. */
public interface {DTO}Service {
    /**
     * {DTO} 데이터 상세 조회
     * @param   input   조회할 {DTO}의 일련번호를 담고 있는 Beans
     * @return  조회된 데이터가 저장된 Beans
     * @throws  Exception
     */
    public {DTO} get{DTO}Item({DTO} input) throws Exception;

    /**
     * {DTO} 데이터 목록 조회
     * @param   input   검색 조건을 담고 있는 Beans
     * @return  조회 결과에 대한 컬렉션
     * @throws  Exception
     */
    public List<{DTO}> get{DTO}List({DTO} input) throws Exception;

    /**
     * {DTO} 데이터가 저장되어 있는 갯수 조회
     * @param   input   검색 조건을 담고 있는 Beans
     * @return  저장되어 있는 데이터 수
     * @throws  Exception
     */
    public int get{DTO}Count({DTO} input) throws Exception;

    /**
     * {DTO} 데이터 등록하기
     * @param   input   저장할 데이터들을 담고 있는 Beans
     * @return  저장된 데이터 수
     * @throws  Exception
     */
    public int add{DTO}({DTO} input) throws Exception;

    /**
     * {DTO} 데이터 수정하기
     * @param   input   수정할 데이터들을 담고 있는 Beans
     * @return  수정된 데이터 수
     * @throws  Exception
     */
    public int edit{DTO}({DTO} input) throws Exception;

    /**
     * {DTO} 데이터 삭제하기
     * @param   input   삭제할 데이터의 조건값을 담고 있는 Beans
     * @return  삭제된 데이터 수
     * @throws  Exception
     */
    public int delete{DTO}({DTO} input) throws Exception;
}

#03. 인터페이스에 대한 구현체 정의

1) Java 콘솔, Jsp, Servlet의 경우

클래스 재정의 후 MyBatis sqlSession 객체를 멤버변수로 주입받기 위한 생성자를 추가해야 한다.

아래의 코드 패턴에서 패키지 이름을 확인하고 {DTO} 라는 키워드를 사용하고자 하는 클래스 이름으로 일괄 변경해서 사용한다.

{DTO}ServiceImpl.java
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
package ###################.impl;

import java.util.List;

import org.apache.ibatis.session.SqlSession;

import ###################.{DTO}Service;

public class {DTO}ServiceImpl implements {DTO}Service {

    // SqlSession 객체
    SqlSession sqlSession;

    public {DTO}ServiceImpl(SqlSession sqlSession) {
        this.sqlSession = sqlSession;
    }

    @Override
    public {DTO} get{DTO}Item({DTO} input) throws Exception {
        return null;
    }

    @Override
    public List<{DTO}> get{DTO}List({DTO} input) throws Exception {
        return null;
    }

    @Override
    public int get{DTO}Count({DTO} input) throws Exception {
        return 0;
    }

    @Override
    public int add{DTO}({DTO} input) throws Exception {
        return 0;
    }

    @Override
    public int edit{DTO}({DTO} input) throws Exception {
        return 0;
    }

    @Override
    public int delete{DTO}({DTO} input) throws Exception {
        return 0;
    }
}

2) Spring의 경우

Spring은 SqlSession 객체를 제어반전에 의해 Framework로부터 주입받기 때문에 생성자가 필요 없다. 다만, SqlSession 객체에 대한 멤버변수를 선언할 때 @Autowired 어노테이션을 추가한다.

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
package ###################.impl;

import java.util.List;

import org.apache.ibatis.session.SqlSession;

import ###################.{DTO}Service;

public class {DTO}ServiceImpl implements {DTO}Service {

    // SqlSession 객체
    @Autowired
    SqlSession sqlSession;

    @Override
    public {DTO} get{DTO}Item({DTO} input) throws Exception {
        return null;
    }

    @Override
    public List<{DTO}> get{DTO}List({DTO} input) throws Exception {
        return null;
    }

    @Override
    public int get{DTO}Count({DTO} input) throws Exception {
        return 0;
    }

    @Override
    public int add{DTO}({DTO} input) throws Exception {
        return 0;
    }

    @Override
    public int edit{DTO}({DTO} input) throws Exception {
        return 0;
    }

    @Override
    public int delete{DTO}({DTO} input) throws Exception {
        return 0;
    }
}

#04. 구현체 클래스의 각 메서드별 구현 패턴

1) 단일행 데이터 조회 기능에 대한 구현 패턴

Log4j를 사용하지 않는 경우 아래 패턴에서 log.error(e.getLocalizedMessage());라는 구문을 e.printStackTrace()로 수정해야 합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{DTO} result = null;

try {
    result = sqlSession.selectOne("################", input);

    if (result == null) {
        throw new NullPointerException("result=null");
    }
} catch (NullPointerException e) {
    log.error(e.getLocalizedMessage());
    throw new Exception("조회된 데이터가 없습니다.");
} catch (Exception e) {
    log.error(e.getLocalizedMessage());
    throw new Exception("데이터 조회에 실패했습니다.");
}

return result;

2) 다중행 데이터 조회 기능에 대한 구현 패턴

Log4j를 사용하지 않는 경우 아래 패턴에서 log.error(e.getLocalizedMessage());라는 구문을 e.printStackTrace()로 수정해야 합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
List<{DTO}> result = null;

try {
    result = sqlSession.selectList("################", input);

    if (result == null) {
        throw new NullPointerException("result=null");
    }
} catch (NullPointerException e) {
    log.error(e.getLocalizedMessage());
    throw new Exception("조회된 데이터가 없습니다.");
} catch (Exception e) {
    log.error(e.getLocalizedMessage());
    throw new Exception("데이터 조회에 실패했습니다.");
}

return result;

3) 데이터 수 조회 기능에 대한 구현 패턴

Log4j를 사용하지 않는 경우 아래 패턴에서 log.error(e.getLocalizedMessage());라는 구문을 e.printStackTrace()로 수정해야 합니다.

1
2
3
4
5
6
7
8
9
10
int result = 0;

try {
    result = sqlSession.selectOne("################", input);
} catch (Exception e) {
    log.error(e.getLocalizedMessage());
    throw new Exception("데이터 조회에 실패했습니다.");
}

return result;

4) 입력, 수정, 삭제 기능에 대한 구현 패턴

Java Console, JSP, Servlet의 경우

트랜젝션에 대한 commit(), rollback() 처리가 필요하다.

  1. insert, update, delete중 선택적으로 메서드 이름 사용.
  2. 사용하고자 하는 Mapper의 기능 명시
  3. 처리된 데이터가 없는 경우의 메시지

    ex) 저장된 데이터가 없습니다.

  4. 예외가 발생한 경우의 메시지

    ex) 데이터 저장에 실패했습니다.

Log4j를 사용하지 않는 경우 아래 패턴에서 log.error(e.getLocalizedMessage());라는 구문을 e.printStackTrace()로 수정해야 합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
int result = 0;

try {
    result = sqlSession.###(1)###("#########(2)###########", input);

    if (result == 0) {
        throw new NullPointerException("result=0");
    }
} catch (NullPointerException e) {
    sqlSession.rollback();
    log.error(e.getLocalizedMessage());
    throw new Exception("###(3)###된 데이터가 없습니다.");
} catch (Exception e) {
    sqlSession.rollback();
    log.error(e.getLocalizedMessage());
    throw new Exception("데이터 ###(4)###에 실패했습니다.");
} finally {
    sqlSession.commit();
}

return result;

Spring의 경우

Spring Framework의 제어반전에 의해 트랜젝션이 자동화 되므로 commit(), rollback() 처리가 필요 없다.

  1. insert, update, delete중 선택적으로 메서드 이름 사용.
  2. 사용하고자 하는 Mapper의 기능 명시
  3. 처리된 데이터가 없는 경우의 메시지

    ex) 저장된 데이터가 없습니다.

  4. 예외가 발생한 경우의 메시지

    ex) 데이터 저장에 실패했습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
int result = 0;

try {
    result = sqlSession.###(1)###("#########(2)###########", input);

    if (result == 0) {
        throw new NullPointerException("result=0");
    }
} catch (NullPointerException e) {
    log.error(e.getLocalizedMessage());
    throw new Exception("###(3)###된 데이터가 없습니다.");
} catch (Exception e) {
    log.error(e.getLocalizedMessage());
    throw new Exception("데이터 ###(4)###에 실패했습니다.");
}

return result;

#05. 구현체의 최종 패턴

1) Java Console, JSP, Servlet

Log4j를 사용하지 않는 경우 아래 패턴에서 log.error(e.getLocalizedMessage());라는 구문을 e.printStackTrace()로 수정해야 합니다.

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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
package ###################.impl;

import java.util.List;

import org.apache.ibatis.session.SqlSession;

import ###################.{DTO}Service;

public class {DTO}ServiceImpl implements {DTO}Service {

    // SqlSession 객체
    SqlSession sqlSession;

    public {DTO}ServiceImpl(SqlSession sqlSession) {
        this.sqlSession = sqlSession;
    }

    @Override
    public {DTO} get{DTO}Item({DTO} input) throws Exception {
        {DTO} result = null;

        try {
            result = sqlSession.selectOne("################", input);

            if (result == null) {
                throw new NullPointerException("result=null");
            }
        } catch (NullPointerException e) {
            log.error(e.getLocalizedMessage());
            throw new Exception("조회된 데이터가 없습니다.");
        } catch (Exception e) {
            log.error(e.getLocalizedMessage());
            throw new Exception("데이터 조회에 실패했습니다.");
        }

        return result;
    }

    @Override
    public List<{DTO}> get{DTO}List({DTO} input) throws Exception {
        List<{DTO}> result = null;

        try {
            result = sqlSession.selectList("################", input);

            if (result == null) {
                throw new NullPointerException("result=null");
            }
        } catch (NullPointerException e) {
            log.error(e.getLocalizedMessage());
            throw new Exception("조회된 데이터가 없습니다.");
        } catch (Exception e) {
            log.error(e.getLocalizedMessage());
            throw new Exception("데이터 조회에 실패했습니다.");
        }

        return result;
    }

    @Override
    public int get{DTO}Count({DTO} input) throws Exception {
        int result = 0;

        try {
            result = sqlSession.selectOne("################", input);
        } catch (Exception e) {
            log.error(e.getLocalizedMessage());
            throw new Exception("데이터 조회에 실패했습니다.");
        }

        return result;
    }

    @Override
    public int add{DTO}({DTO} input) throws Exception {
        int result = 0;

        try {
            result = sqlSession.insert("####################", input);

            if (result == 0) {
                throw new NullPointerException("result=0");
            }
        } catch (NullPointerException e) {
            sqlSession.rollback();
            log.error(e.getLocalizedMessage());
            throw new Exception("저장된 데이터가 없습니다.");
        } catch (Exception e) {
            sqlSession.rollback();
            log.error(e.getLocalizedMessage());
            throw new Exception("데이터 저장에 실패했습니다.");
        } finally {
            sqlSession.commit();
        }

        return result;
    }

    @Override
    public int edit{DTO}({DTO} input) throws Exception {
        int result = 0;

        try {
            result = sqlSession.update("####################", input);

            if (result == 0) {
                throw new NullPointerException("result=0");
            }
        } catch (NullPointerException e) {
            sqlSession.rollback();
            log.error(e.getLocalizedMessage());
            throw new Exception("수정된 데이터가 없습니다.");
        } catch (Exception e) {
            sqlSession.rollback();
            log.error(e.getLocalizedMessage());
            throw new Exception("데이터 수정에 실패했습니다.");
        } finally {
            sqlSession.commit();
        }

        return result;
    }

    @Override
    public int delete{DTO}({DTO} input) throws Exception {
        int result = 0;

        try {
            result = sqlSession.delete("####################", input);

            if (result == 0) {
                throw new NullPointerException("result=0");
            }
        } catch (NullPointerException e) {
            sqlSession.rollback();
            log.error(e.getLocalizedMessage());
            throw new Exception("삭제된 데이터가 없습니다.");
        } catch (Exception e) {
            sqlSession.rollback();
            log.error(e.getLocalizedMessage());
            throw new Exception("데이터 삭제에 실패했습니다.");
        } finally {
            sqlSession.commit();
        }

        return result;
    }
}

2) Spring

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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package ###################.impl;

import java.util.List;

import org.apache.ibatis.session.SqlSession;

import ###################.{DTO}Service;

public class {DTO}ServiceImpl implements {DTO}Service {

    // SqlSession 객체
    @Autowired
    SqlSession sqlSession;

    @Override
    public {DTO} get{DTO}Item({DTO} input) throws Exception {
        {DTO} result = null;

        try {
            result = sqlSession.selectOne("################", input);

            if (result == null) {
                throw new NullPointerException("result=null");
            }
        } catch (NullPointerException e) {
            log.error(e.getLocalizedMessage());
            throw new Exception("조회된 데이터가 없습니다.");
        } catch (Exception e) {
            log.error(e.getLocalizedMessage());
            throw new Exception("데이터 조회에 실패했습니다.");
        }

        return result;
    }

    @Override
    public List<{DTO}> get{DTO}List({DTO} input) throws Exception {
        List<{DTO}> result = null;

        try {
            result = sqlSession.selectList("################", input);

            if (result == null) {
                throw new NullPointerException("result=null");
            }
        } catch (NullPointerException e) {
            log.error(e.getLocalizedMessage());
            throw new Exception("조회된 데이터가 없습니다.");
        } catch (Exception e) {
            log.error(e.getLocalizedMessage());
            throw new Exception("데이터 조회에 실패했습니다.");
        }

        return result;
    }

    @Override
    public int get{DTO}Count({DTO} input) throws Exception {
        int result = 0;

        try {
            result = sqlSession.selectOne("################", input);
        } catch (Exception e) {
            log.error(e.getLocalizedMessage());
            throw new Exception("데이터 조회에 실패했습니다.");
        }

        return result;
    }

    @Override
    public int add{DTO}({DTO} input) throws Exception {
        int result = 0;

        try {
            result = sqlSession.insert("####################", input);

            if (result == 0) {
                throw new NullPointerException("result=0");
            }
        } catch (NullPointerException e) {
            log.error(e.getLocalizedMessage());
            throw new Exception("저장된 데이터가 없습니다.");
        } catch (Exception e) {
            log.error(e.getLocalizedMessage());
            throw new Exception("데이터 저장에 실패했습니다.");
        }

        return result;
    }

    @Override
    public int edit{DTO}({DTO} input) throws Exception {
        int result = 0;

        try {
            result = sqlSession.update("####################", input);

            if (result == 0) {
                throw new NullPointerException("result=0");
            }
        } catch (NullPointerException e) {
            log.error(e.getLocalizedMessage());
            throw new Exception("수정된 데이터가 없습니다.");
        } catch (Exception e) {
            log.error(e.getLocalizedMessage());
            throw new Exception("데이터 수정에 실패했습니다.");
        }

        return result;
    }

    @Override
    public int delete{DTO}({DTO} input) throws Exception {
        int result = 0;

        try {
            result = sqlSession.delete("####################", input);

            if (result == 0) {
                throw new NullPointerException("result=0");
            }
        } catch (NullPointerException e) {
            log.error(e.getLocalizedMessage());
            throw new Exception("삭제된 데이터가 없습니다.");
        } catch (Exception e) {
            log.error(e.getLocalizedMessage());
            throw new Exception("데이터 삭제에 실패했습니다.");
        }

        return result;
    }
}
Rating:

크리에이티브 커먼즈 라이선스 ITPAPER(호쌤,쭈쌤)에 의해 작성된 ≪[Java,Spring] Service 패턴≫은(는) 크리에이티브 커먼즈 저작자표시-비영리-동일조건변경허락 4.0 국제 라이선스에 따라 이용할 수 있습니다.
이 라이선스의 범위 이외의 이용허락을 얻기 위해서는 leekh4232@gmail.com으로 문의하십시오.

comments powered by Disqus