[Spring] 학사 정보 시스템

2023. 10. 7. 01:38학부 강의/웹프로그래밍 (Spring)

0. 출처

 

아직 배우고 있는 중이라 부정확한 정보가 포함되어 있을 수 있습니다!
주의하세요!

 

올인원 스프링 프레임워크 참고.

 

올인원 스프링 프레임워크 : 네이버 도서

네이버 도서 상세정보를 제공합니다.

search.shopping.naver.com

 


1. 학사 정보 시스템

 

학교에서 사용하는 학사 관리 시스템(EMS)에서 학생 관리(학생 등록, 조회, 수정, 삭제 등) 부분을 구현한다.

 

필요에 의해서 다른 용도의 관리 시스템으로 수정해서 사용할 수 있다.

 

  • 학생의 샘플 데이터를 데이터베이스에 등록한다.
  • 전체 학생 정보를 출력한다.
  • 새로운 학생 정보를 등록한다.
  • 학생 정보를 수정한다.
  • 학생 정보를 삭제한다.
  • 시스템 정보를 출력한다.

 

 

코드 : https://github.com/ramen4598/Study_JavaSpring/tree/main/project/ch04_pjt_01

 


가. DAO

 

  • DAO
    : 데이터 접근 객체 (Data access object)
    : 일부 종류의 데이터베이스나 기타 퍼시스턴스 매커니즘에 접근하여 데이터의 CRUD 처리를 담당하는 객체나 패턴.
    : 비즈니스 로직과 데이터베이스 연결 로직을 분리시킬 수 있다. (단일 책임 원칙)

 

IoC 컨테이너는 각종 서비스 객체를 생성하고 필요한 DAO 객체를 주입한다.

 

출처 : https://ko.wikipedia.org/wiki/데이터_접근_객체

 


2. 클래스

 

클래스 다이어그램 이렇게 그리는 것 맞나?

 

 

클래스의 대부분의 필드는 getter, setter가 존재하고 이는 외부에서 값을 초기화, 수정하기 위해서 사용된다.

(<property> 태그를 사용하기 위해서 필요. 아래에서 자세히 설명)

 

클래스의 메서드는 각 클래스 고유의 기능을 구현한다.

 

 


3. applicationContext

 

아래의 Bean을 applicationContext에 추가한다.

 

Bean 설명
initSampleData 샘플 데이터 초기화
studentDao DAO
studentRegisterService 학생 정보 등록
studentModifyService 학생 정보 수정
studentDeleteService 학생 정보 삭제
studentSelectService 학생 정보 조회
studentAllSelectService 전체 학생 정보 조회
printStudentInformationService 학생 정보 출력
dev_DBConnectionInfoDev 개발용 데이터베이스 정보
real_DBConnectionInfo 실제 서비스용 데이터베이스 정보
eMSInformationService 학새 정보 시스템 정보

 

 

자세한 코드는 다음 링크에서 확인할 수 있다.

https://github.com/ramen4598/Study_JavaSpring/tree/main/project/ch04_pjt_01

 


가. InitSampleData 필드 초기화

 

학사 정보 시스템의 샘플 데이터를 관리하는 클래스다.

 

public class InitSampleData {
    private String[] sNums = {"hbs001", "hbs002", "hbs003", "hbs004", "hbs005", "hbs006"};
    private String[] sIds = {"rabbit", "happo", "raccoon", "elephant", "lion", "human"};
    private String[] sPws = {"96539", "64875", "15284", "48765", "28661", "11111"};
    private String[] sNames = {"agatha", "barbara", "chris", "doris", "elva", "tiredI"};
    private int[] sAges = {19, 22, 20, 27, 19, 23};
    private char[] sGenders = {'M', 'W', 'W', 'M', 'M', 'M'};
    private String[] sMajors = {"English Literature", "Korean Language and Literature", "French Language and Literature", "Philosophy", "History", "Computer Science"};
    ...

위는 일반 자바에서 필드를 초기화하는 방법이다.

 

<bean>의 필드를 IoC 컨테이너 내부에서 초기화하는 방법도 있다.

 

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

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="initSampleData" class="ch04_pjt_01.ems.utils.InitSampleData">
        <property name="sNums">
            <array>
                <value>hbs001</value>
                <value>hbs002</value>
                <value>hbs003</value>
                <value>hbs004</value>
                <value>hbs005</value>
                <value>hbs006</value>
            </array>
        </property>
        <property name="sIds">
            <array>
                <value>rabbit</value>
                <value>happo</value>
                <value>raccoon</value>
                <value>elephant</value>
                <value>lion</value>
                <value>human</value>
            </array>
        </property>
        <property name="sPws">
            <array>
                <value>96539</value>
                <value>64875</value>
                <value>15284</value>
                <value>48765</value>
                <value>28661</value>
                <value>11111</value>
            </array>
        </property>
        <property name="sNames">
            <array>
                <value>agatha</value>
                <value>barbara</value>
                <value>chris</value>
                <value>doris</value>
                <value>elva</value>
                <value>tiredI</value>
            </array>
        </property>
        <property name="sAges">
            <array>
                <value>19</value>
                <value>22</value>
                <value>20</value>
                <value>27</value>
                <value>19</value>
                <value>23</value>
            </array>
        </property>
        <property name="sGenders">
            <array>
                <value>M</value>
                <value>W</value>
                <value>W</value>
                <value>M</value>
                <value>M</value>
                <value>M</value>
            </array>
        </property>
        <property name="sMajors">
            <array>
                <value>English Literature</value>
                <value>Korean Language and Literature</value>
                <value>French Language and Literature</value>
                <value>Philosophy</value>
                <value>History</value>
                <value>Computer Science</value>
            </array>
        </property>
    </bean>
</beans>

샘플 데이터를 applicationContext에 추가하고 코드에서 삭제한다.

 

public class InitSampleData {
    private String[] sNums;
    private String[] sIds;
    private String[] sPws;
    private String[] sNames;
    private int[] sAges;
    private char[] sGenders;
    private String[] sMajors;
    ...

<bean>에는 클래스의 멤버 필드를 나타내는 하위 태그로 <property>가 있다.

 

이를 사용해서 필드를 초기화할 수 있다.

  • <property name="sNums"> : 필드의 이름
  • <array> : 필드가 배열인 경우. {} 와 같음.
  • <value>hbs001</value> : 값.

 

<property>는 필드를 초기화하기 위해서 내부적으로 필드의 setter 메서드를 호출한다.

 

이때 호출되는 setter 메서드의 이름은 set[필드이름]으로 약속되어 있다.

 


나. StudentDao, Service들

    <bean id="studentDao" class="ch04_pjt_01.ems.member.dao.StudentDao" />
    <bean id="studentRegisterService" class="ch04_pjt_01.ems.member.service.StudentRegisterService" >
        <constructor-arg ref="studentDao" />
    </bean>
    <bean id="studentModifyService" class="ch04_pjt_01.ems.member.service.StudentModifyService">
        <constructor-arg ref="studentDao" />
    </bean>
    <bean id="studentDeleteService" class="ch04_pjt_01.ems.member.service.StudentDeleteService">
        <constructor-arg ref="studentDao" />
    </bean>
    <bean id="studentSelectService" class="ch04_pjt_01.ems.member.service.StudentSelectService">
        <constructor-arg ref="studentDao" />
    </bean>
    <bean id="studentAllSelectService" class="ch04_pjt_01.ems.member.service.StudentAllSelectService">
        <constructor-arg ref="studentDao" />
    </bean>
    <bean id="printStudentInformationService" class="ch04_pjt_01.ems.member.service.PrintStudentInformationService">
        <constructor-arg ref="studentAllSelectService" />
    </bean>

 


다. DBConnectionInfo

 

데이터베이스 연결에 필요한 정보.

     <!-- DBConnectionInfo -->
    <!-- 개발자용 데이터 베이스 빈 생성 -->
    <bean id="dev_DBConnectionInfoDev" class="ch04_pjt_01.ems.member.DBConnectionInfo">
        <property name="url" value="000.000.000.000" />
        <property name="userId" value="admin" />
        <property name="userPw" value="0000" />
    </bean>
    <!-- 실제 서비스용 데이터 베이스 빈 생성 -->
    <bean id="real_DBConnectionInfo" class="ch04_pjt_01.ems.member.DBConnectionInfo">
        <property name="url" value="111.111.111.111" />
        <property name="userId" value="master" />
        <property name="userPw" value="1111" />
    </bean>

 


라. EMSInfomationService

<!-- EMSInformationService -->
    <bean id="eMSInformationService" class="ch04_pjt_01.ems.member.service.EMSInformationService" >
        <!-- info field initialize -->
        <property name="info" value="Education Management System program was developed in 2022." />
        <!-- copyRight field initialize -->
        <property name="copyRight" value="COPYRIGHT(C) 2022 EMS CO., LTD. ALL RIGHT RESERVED. CONTACT MASTER FOR MORE INFORMATION." />
        <!-- ver field initialize -->
        <property name="ver" value="The version is 1.0" />
        <!-- sYear field initialize -->
        <property name="sYear" value="2022" />
        <!-- sMonth field initialize -->
        <property name="sMonth" value="3" />
        <!-- sDay field initialize -->
        <property name="sDay" value="1" />
        <!-- eYear field initialize -->
        <property name="eYear" value="2022" />
        <!-- eMonth field initialize -->
        <property name="eMonth" value="4" />
        <!-- eDay field initialize -->
        <property name="eDay" value="30" />
        <property name="developers">
            <list>
                <value>Cheney.</value>
                <value>Eloy.</value>
                <value>Jasper.</value>
                <value>Dillon.</value>
                <value>Kian.</value>
            </list>
        </property>
        <property name="administrators">
            <map>
                <entry>
                    <key>
                        <value>Cheney</value>
                    </key>
                    <value>cheney@springPjt.org</value>
                </entry>
                <entry>
                    <key>
                        <value>Jasper</value>
                    </key>
                    <value>jasper@springPjt.org</value>
                </entry>
            </map>
        </property>
        <property name="dbInfos">
            <map>
                <entry>
                    <key>
                        <value>dev</value>
                    </key>
                    <ref bean="dev_DBConnectionInfoDev" />
                </entry>
                <entry>
                    <key>
                        <value>real</value>
                    </key>
                    <ref bean="real_DBConnectionInfo" />
                </entry>
            </map>
        </property>
    </bean>
</beans>

<property> value 간결하게 작성하는 방법이 있다.

 

<value> 태그를 사용하기보다 <property>value 속성을 사용한다.

 

<property name="info">
    <value>Education Management System program was developed in 2022.</value>
</property>
<property name="info" value="Education Management System program was developed in 2022." />

 

MapList <property> 작성법 예시, 설명

<!-- List -->
        <property name="developers">
            <list>
                <value>Cheney.</value>
                <value>Eloy.</value>
                <value>Jasper.</value>
                <value>Dillon.</value>
                <value>Kian.</value>
            </list>
        </property>
<!-- Map -->
        <property name="administrators">
            <map>
                <entry>
                    <key>
                        <value>Cheney</value>
                    </key>
                    <value>cheney@springPjt.org</value>
                </entry>
                <entry>
                    <key>
                        <value>Jasper</value>
                    </key>
                    <value>jasper@springPjt.org</value>
                </entry>
            </map>
        </property>
<!-- Map의 value로 bean을 사용하는 경우-->
        <property name="dbInfos">
            <map>
                <entry>
                    <key>
                        <value>dev</value>
                    </key>
                    <ref bean="dev_DBConnectionInfoDev" />
                </entry>
                <entry>
                    <key>
                        <value>real</value>
                    </key>
                    <ref bean="real_DBConnectionInfo" />
                </entry>
            </map>
        </property>

 


4. Maven 설정 파일

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>spring5</groupId>
  <artifactId>ch04_pjt_01</artifactId>
  <version>0.0.1-SNAPSHOT</version>

  <!-- spring-context module-->
  <dependencies>
      <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-context</artifactId>
          <version>5.2.9.RELEASE</version>
      </dependency>
  </dependencies>

  <!-- bulid config -->
  <build>
      <plugins>
          <plugin>
              <groupId>org.apache.maven.plugins</groupId>
              <artifactId>maven-compiler-plugin</artifactId>
              <version>3.11.0</version>
              <configuration>
                  <source>11</source>
                  <target>11</target>
                  <encoding>utf-8</encoding>
              </configuration>
          </plugin>
      </plugins>
  </build>

</project>

빌드에 필요한 정보(자바, JVM, 스프링 프레임워크의 버전)를 설정한다.

 


5. MainClass

package ch04_pjt_01.ems;
import org.springframework.context.support.GenericXmlApplicationContext;

import ch04_pjt_01.ems.member.Student;
import ch04_pjt_01.ems.member.service.EMSInformationService;
import ch04_pjt_01.ems.member.service.PrintStudentInformationService;
import ch04_pjt_01.ems.member.service.StudentDeleteService;
import ch04_pjt_01.ems.member.service.StudentModifyService;
import ch04_pjt_01.ems.member.service.StudentRegisterService;
import ch04_pjt_01.ems.member.service.StudentSelectService;
import ch04_pjt_01.ems.utils.InitSampleData;

public class MainClass {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        //IoC Container
        GenericXmlApplicationContext ctx = new GenericXmlApplicationContext("classpath:applicationContext.xml");
        //Sample Data
        InitSampleData initSampleData = ctx.getBean("initSampleData", InitSampleData.class);
        String[] sNums = initSampleData.getsNums();
        String[] sIds = initSampleData.getsIds();
        String[] sPws = initSampleData.getsPws();
        String[] sNames = initSampleData.getsNames();
        int[] sAges = initSampleData.getsAges();
        char[] sGenders = initSampleData.getsGenders();
        String[] sMajors = initSampleData.getsMajors();

        // 데이터베이스에 샘플 데이터 등록
        StudentRegisterService registerService = ctx.getBean("studentRegisterService", StudentRegisterService.class);
        for(int i = 0; i < sNums.length; i++) {
            registerService.register(new Student(sNums[i], sIds[i], sPws[i], sNames[i], sAges[i], sGenders[i], sMajors[i]));
        }

        //학생 리스트
        PrintStudentInformationService printStudentInformationService = ctx.getBean("printStudentInformationService", PrintStudentInformationService.class);
        printStudentInformationService.printStudentsInfo();
        //학생 등록
        registerService = ctx.getBean("studentRegisterService", StudentRegisterService.class);
        registerService.register(new Student("hbs007", "deer", "p007", "melissa", 26, 'W', "Music"));
        printStudentInformationService.printStudentsInfo();
        //학생 출력
        StudentSelectService selectService = ctx.getBean("studentSelectService", StudentSelectService.class);
        Student selectedstudent = selectService.select("hbs007");
        System.out.println("STUDENT START ---------------");
        System.out.print("sNum:" + selectedstudent.getsNum() + "\t");
        System.out.print("|sId:" + selectedstudent.getsId() + "\t");
        System.out.print("|sPw:" + selectedstudent.getsPw() + "\t");
        System.out.print("|sName:" + selectedstudent.getsName() + "\t");
        System.out.print("|sAge:" + selectedstudent.getsAge() + "\t");
        System.out.print("|sGender:" + selectedstudent.getsGender() + "\t");
        System.out.println("|sMajor:" + selectedstudent.getsMajor() + "\t");
        System.out.println("END -------------------------");
        //학생 수정
        StudentModifyService modifyService = ctx.getBean("studentModifyService", StudentModifyService.class);
        modifyService.modify(new Student("hbs007", "pig", "p0077", "melissa", 27, 'W', "Computer"));
        printStudentInformationService.printStudentsInfo();
        //학생 삭제
        StudentDeleteService deleteService = ctx.getBean("studentDeleteService", StudentDeleteService.class);
        deleteService.delete("hbs005");
        printStudentInformationService.printStudentsInfo();
        //시스템 정보
        EMSInformationService emsInformationService = ctx.getBean("eMSInformationService", EMSInformationService.class);
        emsInformationService.printEMSInformation();

        ctx.close();
    }
}

InitSampleData에서 샘플 데이터를 가져와서 register한다.

 

이후 데이터를 출력, 추가, 수정, 삭제한다.

 


6. applicationContext.xml 분리

 

간단한 예제에 불과하지만 applicationContext.xml이 벌써 복잡하다.

 

더 효율적으로 관리하기 위해서 applicationContext.xml을 분리해 보자.

 


가. IoC 컨테이너에서 조립

 

세 개로 분리한다.

  • appCtx1.xml : InitSampleData, Dao, Service bean만 남긴다.
  • appCtx2.xml : DBConnectionInfo bean만 남긴다.
  • appCtx3.xml : EMSInformationService bean만 남긴다.

 

//MainClass.java
GenericXmlApplicationContext ctx = new GenericXmlApplicationContext("classpath:appCtx1.xml", "classpath:appCtx2.xml", "classpath:appCtx3.xml");

//또는 배열로 정리
String[] appCtxs = {"classpath:appCtx1.xml", "classpath:appCtx2.xml", "classpath:appCtx3.xml"};

GenericXmlApplicationContext ctx = new GenericXmlApplicationContext(appCtxs);

 

MainClass를 수정한다.

 

 


나. import 태그 활용

 

appCtx1.xml을 복사해서 appCtxImport.xml 생성하고 나머지 2, 3을 import한다.

 

<!-- appCtxImport.xml-->
<import resource="classpath:appCtx2.xml"/>
<import resource="classpath:appCtx3.xml"/>

MainClass를 수정한다.

 

//MainClass.java
GenericXmlApplicationContext ctx = new GenericXmlApplicationContext("classpath:appCtxImport.xml");

 

 


 

'학부 강의 > 웹프로그래밍 (Spring)' 카테고리의 다른 글

[Spring] 의존 객체 자동 주입_1  (0) 2023.10.07
[Spring] Spring Bean Scope  (0) 2023.10.07
[Spring] 스프링으로 계산기 만들기  (0) 2023.09.22
[Spring] Maven  (0) 2023.09.14
[Spring] DI, DIP, IoC  (0) 2023.09.09