본문 바로가기

스프링부트를 이용한 웹페이지 만들기 도전!!/인텔리J

IntelliJ를 이용해서 스프링부트를 시작해보자!! (6) - Dto, Dao, Service

오늘은 아래 작업을 진행 할겁니다.

 

1. Dto와 Dao, Service를 작성

 

2. 회원가입 창 작성

 

3. 회원가입 창에서 id, pw, 성별을 입력하고 "확인"을 누르면 중복 id가 있는지 확인하고 없다면 DB에 추가하고 

가입완료 alert출력

 

4. 가입되어있는 회원의 목록을 웹페이지내에 출력

 

 

 

간단하게 "회원가입" 기능을 만들어보겠다는 얘기입니다.

 

가장먼저 Dto, Dao, Service를 만들어 보겠습니다.

 

맨처음에 설명했던걸 다시 설명하면 Dto는 Class 입니다.

 

Data Transfer Object의 약자이죠.

 

이클립스 버전에서 설명할때는 UserDto와 BoardDto를 둘 다 사용했습니다.

 

"회원"이라는 개념도 있고 "게시물" 이라는 개념도 있었기 때문이죠.

 

하지만, Board는 생략하고 "회원가입" 과 "회원목록"만 출력하게끔 간단하게 진행하겠습니다.

 

회원의 Dto를 UserDto라고 칭하겠습니다. UserDto에는 회원의 id, pw, 성별이 들어가야 합니다.

 

id와 pw는 String으로 하고 성별은 boolean으로 선언하고 true이면 남성, false면 여성으로 하겠습니다.

 

Dto폴더를 만들고 안에 UserDto라는 클래스 파일을 만들어주세요.

그리고, id, pw, 성별을 선언하고 getter와 setter 코드를 만들겁니다.

 

package com.example.demo.Dto;
public class UserDto {
    private String Id;
    private String Pw;
    private boolean Gender;

    public String getId() {
        return Id;
    }

    public void setId(String id) {
        Id = id;
    }

    public String getPw() {
        return Pw;
    }

    public void setPw(String pw) {
        Pw = pw;
    }

    public boolean isGender() {
        return Gender;
    }

    public void setGender(boolean gender) {
        Gender = gender;
    }

}

 

 

 

 

참고로 거의 모든 IDE에서 그렇듯이 getter 코드와 setter 코드를 직접 만드실 필요는없습니다.

 

 

 

 

 

 

 

 

이렇게 해주면 IDE가 자동으로 get코드와 set코드를 만들어줍니다.

 

Dto의 사용은 Dao, Service의 설명을 듣다보시면 어떤건지 감이 오실겁니다.

 

 

Dao는 앞에서 만들어놓은 Dto를 실제로 DB에 Insert, Delete, Update, Select하는 구문을 작성합니다.

 

Dao는 Data Access Object의 약자입니다. 이전까지는 JDBC를 사용했었습니다.

 

하지만 JDBC는 SQL 및 DB연결, JAVA언어를 모두 사용해야하므로 재사용성이 좋지 않습니다.

 

MyBatis는 이러한 불편한점을 해소하기 위해 나온 방법으로,  SQL문과 함수를 Mapping 해주는 Mapper를 만들고,

 

MyBatis.config파일에서 이러한 Mapper를 MapperScan 해주면 우리는,

 

Mapper.Select(UserId) Mapper.Delete(UserId, UserPw) 이런식으로 매우 간단하게 SQL명령을 수행할 수 있습니다.

 

생산성이 굉장히 좋아지겠죠??

 

결국 Dao를 만든다는 것은, Mapper를 만든다는 것이고, 이러한 Mapper를 인식시켜주는 Mybatis.config파일도 만들어

 

야 한다는 사실을 아시면 될 것 같습니다.  

 

 

 

 

 

 

Config폴더와 Dao폴더를 만들어 주세요.

 

그리고 Config파일은 클래스로, Dao파일은 인터페이스로 만들어 주세요.

 

 

package com.example.demo.Config;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;

@Configuration
@MapperScan(basePackages = "com.example.demo.Dao")
public class MyBatisConfig {
    @Bean
    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception{
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSource);
        sqlSessionFactoryBean.setTypeAliasesPackage("com.example.demo.Dto");
        return sqlSessionFactoryBean.getObject();
    }
    @Bean
    public SqlSessionTemplate sqlSession(SqlSessionFactory sqlSessionFactory){
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

 

 

 

MyBatisConfig는 이렇게 만드시면 됩니다. 한번 만들어놓기만 하면, 모든 Dao와 Dto파일을 정해진 위치에만 만든다는 가정하에 수정하실 필요는 없습니다. 

 

 

 

package com.example.demo.Dao;

import com.example.demo.Dto.UserDto;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;

import java.util.List;

@Mapper
public interface UserMapper {
    @Insert("INSERT INTO user VALUES (#{Id}, #{Pw}, #{Gender})")
    void InsertUser(UserDto dto);
    @Select("SELECT * FROM user WHERE Id=#{Id}")
    UserDto selectOneUser(String Id);
    @Select("SELECT * FROM user")
    List<UserDto> selectAllUser();
}

 

 

 

 

Dao (Mapper)는 단순하게 만들었습니다.

 

이제 우리는 다른 복잡한 생각은 할 필요가 없습니다. 그저 Insert를 하고싶으면 Mapper.InserUser(UserDto)하면되고

 

Select하고싶으면 Mapper.selectOndeUser(UserId) 하면 됩니다. DB와 연결을 생각할 필요도 없고 SQL문도 생각하실

 

필요가 없습니다. 이미 선언이 되어있기 때문이죠.

 

 

 

Service는 이제, 본격적으로 Dao와 Dto를 사용해서 기능을 구현하는 것입니다!!

 

예를들면 이런거죠. 로그인을 하면 UserDto의 입력을 받습니다.

 

그리고, 그 Dto의 UserId가 DB에 있는지 확인을 하겠죠.

 

그리고, Id가 Db에 없다면 정상처리 하고 DB에 Insert 해줄겁니다.

 

실제로는 이보다 복잡한 작업들이 있겠지만 우리는 단순하게 이러한 기능을 Login이라고 정하는 겁니다.

 

이렇게 로그인, 회원탈퇴, 회원정보 수정 등의 실제적인 기능을 구현하는게 Service입니다.

 

이번에도 간단하게만 만들어 보겠습니다.

 

Service는 인터페이스, 클래스로 나누어서 만들겠습니다. 

 

 

 

package com.example.demo.Service;

import com.example.demo.Dto.UserDto;

import java.util.List;

public interface UserService {
    public boolean join(UserDto user);
    public List<UserDto> getUserList();
}

 

 

 

로그인, 회원목록 출력을 선언했습니다.

 

로그인은 Dto를 받아서 True / False를 반환 할 것이고

 

회원출력은 DB로부터 모든 Dto의 리스트를 받아 올 것입니다.

 

인터페이스는 구현해주는 implement 코드가 필요합니다. 

 

 

 

package com.example.demo.Service;

import com.example.demo.Dao.UserMapper;
import com.example.demo.Dto.UserDto;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Override
    public boolean join(UserDto dto) {

        UserDto user = userMapper.selectOneUser(dto.getId());
        if(user != null)
        {
            return false;
        }
        else
        {
            userMapper.InsertUser(dto);
            return true;
        }
    }

    @Override
    public List<UserDto> getUserList() {
        return userMapper.selectAllUser();
    }
}

 

 

 

 

입력받은 dto의 id로 먼저 DB에 SELECT 해봅니다. 값이 존재한다면 이미 DB에 등록된 ID라는 것이겠죠

 

그러면 false를 반환합니다. ID가 없었다면 true를 반환합니다. true이면 회원가입에 성공했습니다!를 띄우고 DB에 등록

 

하면 될 것이고 false이면 DB에 등록은 생략하고 중복된 아이디가 존재합니다. 를 띄울겁니다. 메세지를 띄우는건 컨트롤

 

러에서 작업하면 되고 일단 서비스에서는 DB에 넣는 작업만 추가합니다.

 

getUserList는 그냥 단순하게 DB안의 모든 Dto목록을 리턴해주는 함수입니다. 출력에 쓰이겠죠.

 

이제 기능이 추가되었으니 html 파일과 컨트롤러도 약간의 수정이 필요합니다.

 

html에는 아이디, 비밀번호, 성별의 입력을 받아 제출하는 폼이 필요하고 또한 DB안의 값들을 출력해주는 부분도 필요

 

할 것입니다. 전체적인 코드는 다음과 같습니다.

 

 

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8"/>
    <title>My Web Page</title>
    <link type="text/css" rel="stylesheet" href="/css/style.css"/>
</head>
<body>
    <p> Hello World!! </p>
    <button id="btnTime">Time</button>
    <input id="btnAlert" type="button" value="Hello world" />
    <h1 id="time"></h1>
    <div class="container">
        <div>
            <h1>회원가입</h1>
            <form action="/" method="post">
                <table border="1">
                    <tr><th width="70">ID:</th><TD><INPUT type="text" name="Id" size="13"></TD></tr>
                    <tr><th width="70">PW:</th><TD><INPUT type="text" name="Pw" size="13"></TD></tr>
                    <tr><th width="70">Gender:</th><td><INPUT type="radio" name="Gender">IsMan?</td></tr>
                    <tr align="center">
                        <td colspan="2">
                            <input type="submit" value="submit">
                        </td>
                    </tr>
                </table>
            </form>
        </div>
        <div class="container-List">
            <table border = "1">
                <tr>
                    <th>Id</th>
                    <th>Pw</th>
                    <th>IsMan</th>
                </tr>
                <tr th:each="List : ${userList}">
                    <td th:text="${List.Id}" width="100"></td>
                    <td th:text="${List.Pw}" width="100"></td>
                    <td th:text="${List.Gender}" width="100"></td>
                </tr>
            </table>
        </div>
    </div>
    <script rel="script" type="text/javascript" src="/js/script.js"></script>
</body>
</html>

 

 

 

 

div에 class="container" 이렇게 되있는건 css에서 추가한겁니다. 

수직으로 요소가 배치되는데, 이를 수평으로 바꾸는 flex와 두 폼사이의 간격을 조절하는 margin을 줬습니다.

<form>~~</form> 사이의 내용들은 아이디,비밀번호,성별을 입력받아 제출하는 부분이고

밑에 th:text... 이렇게 되있는게 userList로부터 List를 하나씩 뽑아서 출력해주는 부분입니다.

 

 

 

.container {
    display: flex;
}

.container-List{
    margin-left: 100px;
}

 

 

 

목표는 이렇게 화면을 구성하는 것입니다.

 

ID, PW, 성별을 입력받아 submit을 누르면 오른쪽의 표에 즉각적으로 반영됩니다.

 

submit을 누르면 postMapping되어 컨트롤러에 넘겨주는데요, 이를 처리하는 부분은 컨트롤러에서 작성하면 됩니다.

 

 

 

    @PostMapping(value = "/")
    public String register(RedirectAttributes redirect, UserDto user)
    {
        if(uService.join(user))
            redirect.addAttribute("msg", "회원가입이 완료되었습니다");
        else
            redirect.addAttribute("msg", "중복된 아이디가 존재합니다.");
        return "redirect:result_alarm";
    }

    @RequestMapping(value = "/result_alarm")
    public String result_alarm(@RequestParam("msg") String param, Model model)
    {
        model.addAttribute("msg", param);
        return "result_alarm";
    }

 

 

 

 

넘겨받은 UserDto를 result_alarm.html로 넘겨주고 이게 DB에 있으면 msg = "중복된 아이디가 존재합니다" 가 되고

 

DB에 없으면 "회원가입이 완료되었습니다"가 msg가 될 것입니다.

 

result_alarm.html

 

 

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<span th:text="${msg}">message</span>
<br></br>
<form action="/" method="get">
    <button >돌아가기</button>
</form>
</body>
</html>

 

 

 

 

submit을 누르면 result_alarm페이지로 넘어가고 다시 돌아가기를 누르면 원래 페이지로 돌아갑니다.

 

 

 

https://github.com/haoun1/IntelliJ_Board

 

GitHub - haoun1/IntelliJ_Board

Contribute to haoun1/IntelliJ_Board development by creating an account on GitHub.

github.com

 

코드는 제 github에 올려져 있습니다. 궁금한게 있으시면 참고하세요