spring 회원등록

노건우·2023년 9월 21일
0

Spring

목록 보기
4/22

일단 처음은 스프링의 구조에 대해 알아야 이해가 쉬울 것이라 생각해 사진을 첨부한다.

사진을 보면 컨트롤러는 서비스에 종속되어 있고, 서비스는 리포지토리에 종속되어 있다.

⭐⭐따라서 패키지를 우선적으로 controller, service, repository 3개로 구성한다.

controller

package com.codingbox.core2.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;


import com.codingbox.core2.dto.Member;
import com.codingbox.core2.dto.MemberForm;
import com.codingbox.core2.service.MemberService;

@Controller
public class MemberController {
	
	//controller가 서비스에 의존한다고 표현한다. 그래서 서비스로 객체를 만든것
	//MemberService mService = new MemberService();
	
	// Service는 여러 컨트롤러에서 가져다 쓸 수 있기 때문에 
	//Spring container에 등록을 해야한다.
	//스프링의 장점을 이용해서 작업하자. 의존성 주입 작업
	private final MemberService memberService; //final은 수정 불가능하게 못 박아버리는 역할
	
	@Autowired
	public MemberController(MemberService memberService) {
		this.memberService = memberService;
	}
	@GetMapping("/members/new")
	public String createForm() {
		return "members/createMemberForm";
	}
	@PostMapping("/members/new")
	public String create(MemberForm form) {
		Member member = new Member();
		member.setName(form.getName());
		
		memberService.join(member);
		
		//회원가입 등록을 한 후에
		//홈 화면으로 돌린다.
		return "redirect:/";
	}
	// / members,getMapping
	//list(Model model),return "members/memberList"
	@GetMapping("/members")
	public String list(Model model) {
		List<Member> members = memberService.findMembers();
		model.addAttribute("members",members);
		return "members/memberList";
	}
	
}

이 부분에서 Autowired 어노테이션을 통해 서비스에 종속됨을 보여주고 있다.


웰컴페이지이다. 위의 코드를 보면 회원 가입의 경우 /members/new을 매핑하고, 회원 목록의 경우 /members을 매핑하고 있다.



이렇게 매핑이 잘 되어 있다.

service

package com.codingbox.core2.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.codingbox.core2.dto.Member;
import com.codingbox.core2.repository.MemberRepository;
import com.codingbox.core2.repository.MemoryMemberRepository;

import jakarta.transaction.Transactional;

@Service
@Transactional 
public class MemberService {

	//서비스는 리포지토리에 의존. 그래서 리포지토리 객체를 만든다.
	//MemoryMemberRepository memberRepository = new MemoryMemberRepository();
	
	//스프링스러운 의존성 주입
	private final MemberRepository memberRepository;
	
	@Autowired
	public MemberService(MemberRepository memberRepository) {
		this.memberRepository = memberRepository;
	}
	//회원가입
	public int join(Member member) {
		memberRepository.save(member);
		return member.getId();
	}
	//전체 회원 조회
	public List<Member> findMembers(){
		return memberRepository.findAll();
	}
}

⭐서비스는 리포지토리에 종속됨을 확인할 수 있다.

리포지토리에서 멤버변수를 저장하고, 전체 회원을 조회한다.

Repository

👊 여기서부터가 중요한데, jdbc를 이용하여 구현하는 방법과 jpa를 사용하여 보다 편리하게 repository를 구현하는 방식으로 나누어 본다.
일단 인터페이스로 save, findall 지정

package com.codingbox.core2.repository;

import java.util.List;

import com.codingbox.core2.dto.Member;

public interface MemberRepository {
	//회원 저장
	Member save(Member member);
	//전체 조회
	List<Member>findAll();
}

jdbc

package com.codingbox.core2.repository;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

import javax.sql.DataSource;

import org.springframework.stereotype.Repository;

import com.codingbox.core2.dto.Member;

@Repository
public class JdbcMemberRepository implements MemberRepository{

	private final DataSource dataSource;
	public JdbcMemberRepository(DataSource dataSource) {
		this.dataSource = dataSource;
	}
	
	@Override
	public Member save(Member member) {
		String sql = "INSERT INTO MEMBER values(member_seq.nextval,?)";
		
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		
		try {
			conn = dataSource.getConnection();
			String generatedColumns[]= {"ID"};
			pstmt = conn.prepareStatement(sql,generatedColumns);
			pstmt.setString(1, member.getName());
			pstmt.executeUpdate();
			rs = pstmt.getGeneratedKeys();
			
			if(rs.next()) {
				member.setId(rs.getInt(1));
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		} 
			
		
		
		
		return member;
	}

	@Override
	public List<Member> findAll() {
		String sql = "SELECT * FROM MEMBER";
		
		Connection conn = null;
		PreparedStatement pstm = null;
		ResultSet rs = null;
		List<Member> members = new ArrayList<>();
		
		try {
			conn = dataSource.getConnection();
			pstm = conn.prepareStatement(sql);
			rs = pstm.executeQuery();
			
			
			while(rs.next()) {
				Member member = new Member();
				member.setId(rs.getInt("id"));
				member.setName(rs.getString("name"));
				members.add(member);
			}
		} catch (Exception e) {
			
		}
		return members;
	}

}

어노테이션으로 리포지토리를 달았고 sql쿼리문을 그대로 복사 붙여넣기 해주는 마치 jsp와 같은 방식을 취하여 DB에 접근한다.(jpa로 구현할 땐 이 어노테이션을 제거해야 한다.)
save 같은 경우 회원가입이기에 데이터를 넣는 행위이다. 따라서 insert문이 들어간다.
findAll은 회원목록이기에 select문을 활용한다.

member는 배열로서 받아온다.

jpa

package com.codingbox.core2.repository;

import java.util.List;

import org.springframework.stereotype.Repository;

import com.codingbox.core2.dto.Member;

import jakarta.persistence.EntityManager;

@Repository
public class JpaMemberRepository implements MemberRepository {

	
	private final EntityManager em;
	public JpaMemberRepository(EntityManager em) {
		this.em = em;
	}
	
	@Override
	public Member save(Member member) {
		em.persist(member);
		return member;
	}
	
	@Override
	public List<Member> findAll() {
		
		return em.createQuery("select m from Member m",Member.class).getResultList();
	}
}

중요한 것에 비해 생각보다 코드가 간소하다.
하나하나 뜯어보면, JpaMemberRepository도 MemberRepository를 취하며,public JpaMemberRepository(EntityManager em) {
this.em = em;
}
즉 리포지토리 자체에 의존성을 둔다.
⭐save를 보면, 스프링 자체에서 save를 해주고 별다른 예외 처리가 필요없다.
⭐findAll 도 상당히 간소화 되었다.

html

<!DOCTYPE html>
<html>
<html xmlns:th="http://www.thymeleaf.org">
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
	<table>
		<thead>
			<tr>
				<th>no</th>
				<th>이름</th>
			</tr>
		</thead>
		<tbody>
			<tr th:each="member : ${members}">
				<td th:text="${member.id}"></td>
				<td th:text="${member.name}"></td>
			</tr>
		</tbody>
	</table>
</body>
</html>

${members}이 부분이 멤버가 연결되는 부분이다. 컨트롤러에서의 model.addAttribute("members",members); 이 코드와 연결된다.



추가적인 세팅

profile
초보 개발자 이야기

0개의 댓글

관련 채용 정보