Spring를 이용한 회원정보관리

Back-End/Spring 2019. 5. 31. 18:21
728x90
반응형

-회원관리 전체적인 구조 (오라클과 mybatis 연동 할 예정)-


MVC 패턴이지만 Controller과 Model 사이에 Service를 추가해서 트랜잭션 처리를 원할하게 할 예정


  

  Controller

  ㄴMemberController.java



  Service

  ㄴMemberService.java 인터페이스

  ㄴMemberServicelmpl.java 구현클래스



  Model

  ㄴMemberDAO.java 인터페이스

  ㄴMemberDAOlmpl.java 구현 클래스

  ㄴMemberDTO.java 회원 정보 저장 클래스

  ㄴmemberMapper.xml sql매퍼



  View

  ㄴmember_list.jsp (회원 목록 출력)

  ㄴwrite.jsp (회원 등록)

  ㄴview.jsp (회원 정보 상세보기 보기)




Oracle SQL로 회원정보를 관리하는 member 테이블 생성

1
2
3
4
5
6
7
create table member(
userid varchar2(50) not null primary key, //유저 아이디를 속성 생성, null값 방지, 다른 속성을 식별할 수 있는 기본키로 설정
passwd varchar2(50) not null, //유저 비밀번호 속성 생성, null값 방지
name varchar2(50) not null, //이름 속성 생성, null값 방지
email varchar2(50), //이메일 속성 생성
join_date date default sysdate  //날짜와 시간을 저장하는 date 타입에 sysdate로 기본값(현재의 날짜가 들어가게끔)을 부여한 join_date 속성을 생성
//join_date는 따로 값을 지정해서 넣지 않아도 다른 값들을 다 집어넣었을 시에 자동으로 값을 집어넣은 날짜가 들어간다.
);
cs



member 테이블에 회원정보 삽입

1
2
3
4
insert into member (userid,passwd,name,email) values
('kim','1234','김철수','kim@gmail.com');
 
select * from member;
cs



Insert로 4개의 값만 집어넣었지만 join_date가 자동적으로 오늘 날짜가 들어가 있는것을 확인할 수 있었다.



수정작업을 다 끝낸 후에는 commit; 을 입력해야 저장이 된다.

1
commit;
cs



-Mybatis란?-


1. 자바의 관계형 데이터 베이스 프로그래밍을 좀 더 쉽게 할 수 있게 도와주는 개발 프레임 워크


2. 자바에선 데이터베이스 프로그래밍을 하기 위해 JDBC (자바에서 제공하는 데이터베이스 API)를 제공


3. JDBC는 관계형 데이터 베이스를 사용하기 위해 다양한 API를 제공


4. 다양한 관계형 데이터베이스를 지원하기 위해 JDBC는 세부적인 작업이 가능하게 작업별로 각각의 메소드를

   호출하게 된다. 하지만 이러한 사항들은 다수의 메소드를 호출하고 관련된 객체를 해제해야 하는 단점이 존재한다.


--> Mybatis는 JDBC보다 좀 더 편하게 사용하기 위해 개발되었음




-MyBatis의 특징-


 

  1. 간단하다 : 간단한 퍼시스턴스 프레임워크.


  퍼스스턴스 프레임워크란?


  직접 JDBC API를 호출하지 않고도 데이터베이스에 있는 데이터를 다룰수 있는 것.

  애플리케이션을 종료하고 다시 실행하더라도 이전에 저장한 데이터를 다시 불러올 수 있는 기술.



  2. 생산성 : JDBC보다 62%정도 코드가 줄어들고, 설정이 간단하다.


  3. 성능 : 구조적 강점 (데이터 접근 속도를 높여주는 Join 매핑)

  여러가지 방식의 데이터를 가져오기 전략 (가져오기 미루기, SQL 줄이기 기법)


  4. 작업의 분배 : 팀을 세분화하는 것을 도움


  5. SQL문이 애플리케이션 소스 코드로부터 완전히 분리


  6. 이식성 : 어떤 프로그래밍 언어로도 구현 가능 (자바, C# 등)


  7. 오픈소스이며 무료이다.





-Mybatis의 구성-


  

  1. 환경 설정 파일


  ㄱ. 매핑 설정이 어디 있는지?


  ㄴ. DB에 어떻게 접속할 건지?


  ㄷ. 사용할 모델클래스들에 대한 설명?




  2. 매핑 설정 파일


  ㄱ. 사용할 SQL문들에 대한 정의




  3. Session 빌드 및 사용


  ㄱ. 실제 SQL문 실행


  ㄴ. 설정 파일을 먹여서 Sql Session Factory Builder를 객체 생성


  ㄷ. Sql Session Factory Builder을 이용해서 Sql Session을 Open


  ㄹ. Sql Session을 통해서 원하는 Sql 구문의 id를 호출해서 사용함


  ㅁ. Sql Session을 close




* 용어 정리 *


   

  SqlSessionFactoryBuilder 클래스 : 설정 파일을 읽어서 SqlSessionFactory 객체를 생성


  - SqlSessionFactoryFactory 클래스 : SqlSession을 만드는 역할

(Dao는 Factory를 멤버로 유지하면서 필요할 때 SqlSession을 open해서 사용하고 다 쓰면 SqlSession을 close)


  - SqlSession 클래스 : Sql문을 실제 호출해주는 역할 (필요할 때 open 하고 close 해줘야 함)










-SqlSession 객체 구현-


MemberDAOImpl.java 중 일부(MemberDAO.java 인터페이스 구현 클래스)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Repository //현재 클래스가 서버가 올라올때 이 클래스를 자동으로 메모리로 올려주게 하는 어노테이션
            //원래 클래스는 개발자가 관리하지만 @Repository 어노테이션을 쓰면 스프링에서 알아서 관리하게끔 만들어준다.
            //이렇게 하면 new로 객체를 생성하지 않아도 inject 어노테이션을 사용해서 이 클래스를
            //사용 할 수 있다.
            //@controller어노테이션과 마찬가지이다.
 
//MemberDAO 인터페이스 클래스를 구현할 클래스.
public class MemberDAOImpl implements MemberDAO {
    
    //로깅 처리(정보를 기록하기 위한 처리) 를 위한 객체 선언
    //로그 저장소의 getLogger()메소드를 호출해서 MemberDAOImpl.class에 대한 로그를 Logger에 넣어준다.
    private static final Logger logger =
        LoggerFactory.getLogger(MemberDAOImpl.class);
    
    //sqlSession 객체를 개발자가 직접 생성하지 않고 스프링이 만든 객체를 연결시켜 준다.
    @Inject //이런 방식을 의존관계를 주입한다고 한다.
    SqlSession sqlSession;
            //만약 mybatis쪽에서 코드를 변경했다면 이쪽에서도 변경해야한다.
            //root-context.xml 파일에서 sqlSessionTemplate을 이용해서 sqlsession 객체를 만들고,
            //스프링이 실행될때 이미 이 코드가 실행되 sqlsession 객체가 생성되어서 의존주입이 되었기 때문에
            //궂이 여기서 다시 만들필요가 없다.
cs



root-context.xml

1
2
3
4
5
<!-- SqlSession 객체 주입 -->
    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"
        destroy-method="clearCache"> //자동으로 남아있는 캐시를 청소해준다.
        <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"></constructor-arg>
    </bean>
cs



-SqlSessionFactory 객체 구현-


memberMapper.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
<?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와 중복되지 않도록 네임스페이스 기재 -->
<mapper namespace="member">
    <select id = "memberList" 
    resultType = "memberDto"//밑에서 줄여놓은 경로를 적는다.
<!-- 자료형 틀리지 않도록 주의 -->
    select * from member
    order by name <!-- 이 쿼리는 세미콜론 찍지 않도록 주의 한다. -->
    </select>
</mapper>
cs



mybatis-config.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<?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
<!--typeAliases는 경로를 쓸때 경로가 너무 길어 쓰기 힘들때 줄여서 쓸수있는 줄임말을 정하는 태그이다.  -->
    <!-- type는 MemberDTO의 원래 경로이고,  alias는 경로의 줄임말을 무엇으로 할건지 설정하는 것-->
    <!-- 즉 경로가 너무 길어 일일이 쓰기 힘드니 줄임말을 쓰는것 -->
<typeAlias type = "com.example.spring01.medel.dto.MemberDTO" //원래 경로
alias="memberDto"/> //원래 경로를 수정 (줄인 경로)
    </typeAliases>
 
</configuration>
 
 
cs



root-context.xml

1
2
3
4
5
6
7
8
9
<!-- SqlSessionFactory 객체 주입 -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="configLocation"
        value="classpath:/mybatis-config.xml"></property>
        <property name="mapperLocations"
        value="classpath:mappers/**/*Mapper.xml"></property>
        <!-- *는 하위 디렉터리에 있는 파일들을 모두 포함한다는 뜻 . 즉 mappers 하위 파일들을 모두 포함-->
    </bean>
cs




회원정보 수정


비밀번호 입력시 테이블에 있는 비밀번호와 내가 입력한 비밀번호가 맞으면 수정, 틀리면 되돌아간다.



view.jsp 중 일부

1
2
3
4
5
6
//수정 버튼#은 id이고 btnUpedate태그 (Update 버튼)를 누르면 update.do로 넘어감

$(function(){
    $("#btnUpdate").click(function(){
        document.form1.action="${path}/member/update.do"; //update.do로 이동
        document.form1.submit();
    });





cs



MemberController.java 중 일부

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@RequestMapping("member/update.do")
    public String update(@ModelAttribute MemberDTO dto,Model model){
        boolean result=memberService.checkPw( //내가 입력한 비밀번호와 DB에 입력된 비밀번호를 비교해서 참, 거짓으로 리턴
                dto.getUserid()dto.getPasswd());
        logger.info("비밀번호 확인:"+result);
        
        if(result) { //비밀번호가 맞으면
            memberService.updateMember(dto); //레코드 수정
            return "redirect:/member/list.do"//목록으로 이동
        }else { //비밀번호가 틀리면
            MemberDTO dto2=memberService.viewMember(dto.getUserid());
            dto.setJoin_date(dto2.getJoin_date()); //날짜가 지워지지 않도록
            model.addAttribute("dto",dto);
            model.addAttribute("message""비밀번호가 일치하지 않습니다.");
            return "member/view"//수정 페이지로 되돌아감 
        }
    }
cs



MemberDAOImpl.java 중 일부

1
2
3
4
5
6
7
8
9
10
11
12
@Override
    public boolean checkPw(String userid, String passwd) {
        boolean result=false;
        //mapper에 넘길 값이 2개 이상인 경우 map으로 묶어서 전달 
        Map<String,String> map=new HashMap<>();
        map.put("userid", userid);
        map.put("passwd", passwd);
        int count=sqlSession.selectOne("member.checkPw", map);
        //리턴값이 1이면 true, 0이면 false 
        if(count==1) result=true;
        return result;
    }
cs



memberMapper.xml 중 일부

1
2
3
4
<select id="checkPw" resultType="int">
        select count(*) from member
        where userid=#{userid} and passwd=#{passwd}
//멤버 테이블에서 아이디와 비밀번호가 일치하는 유저의 개수(int값)를 확인해서 맞으면 1(명), 틀리면 0(명)이 넘어간다.
</select>

]









 cs



MemberController.java 중 일부

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
    
@RequestMapping("member/update.do")
    public String update(@ModelAttribute MemberDTO dto,Model model){
        boolean result=memberService.checkPw(
                dto.getUserid(), dto.getPasswd());
        logger.info("비밀번호 확인:"+result);
        
        if(result) { //비밀번호가 맞으면
            memberService.updateMember(dto); //레코드 수정
            return "redirect:/member/list.do"//목록으로 이동
        }else { //비밀번호가 틀리면
            MemberDTO dto2=memberService.viewMember(dto.getUserid());
            dto.setJoin_date(dto2.getJoin_date()); //날짜가 지워지지 않도록
            model.addAttribute("dto",dto);
            model.addAttribute("message""비밀번호가 일치하지 않습니다.");
            return "member/view"//수정 페이지로 되돌아감 
        }
    }
  
cs




src/test/java/MemberDAOTest.java


MemberDAO.java에서 우클릭한 후 테스트 케이스 생성

테스트하고자 하는 클래스에서 우클릭 - New - Other - JUnit Test Case New JUnit 4 test 선택

테스트케이스 클래스 이름 : 테스트할 클래스 이름 + Test

Class under test에 테스트할 클래스 선택


Test Case - 테스트할 클래스


Test Suite - Test Case가 여러개 모인것


지금 테스트해볼 클래스는 MemberDAO이고, 이 DAO 클래스는 MemberDAOImpl를 호출하기 때문에 아래 사진처럼 

Class under test를 설정해준다.




서비스와 DAO를 거쳐서 updateMember( )를 호출


위에서 아래로 내려감


controller - service - dao - mapper - view 순





728x90
반응형

'Back-End > Spring' 카테고리의 다른 글

스프링 프로젝트 살펴보기  (0) 2019.06.02
스프링 프레임워크 입문  (0) 2019.06.02
Controller와 View의 연결 방법  (0) 2019.05.29
Spring 데이터베이스 연결 테스트  (0) 2019.05.29
spring 로킹툴  (0) 2019.05.28
: