Project/javachip

[Portfolio] 커뮤니티 기반 크라우드 펀딩 사이트

ParkYeseul 2024. 11. 25. 13:18

 

🔹프로젝트 기간

2024.08.14 - 2024.08.29 (2주)

 

🔹프로젝트 주제

커뮤니티 중심 크라우드 펀딩 사이트

 

🔹담당 역할

  • 문서 총괄(수행 계획서, 요구사항 분석서)
  • 노션 회의 기록
  • 펀딩 페이지 
  • 리뷰 페이지

🔹사용 기술 환경

react, javascript, java, oracle, tomcat, node.js, spring boot, eclipse, DBeaver

 

💭프로젝트에서 배운 점

개발 시작 후 가장 어렵게 느껴졌던 프론트와 백엔드 그리고 데이터베이스 연결 구조였습니다.

가시적으로 보이는 것이 아니기 때문에 막연하게만 느껴졌었고, 명쾌한 이해가 잘 되지 않았던 상태였습니다.

 

이 프로젝트를 진행하면서

프론트엔드와 백엔드 그리고 데이터베이스 연결 구조와 각 역할에 대해 배울 수 있었고 그 부분이 가장 큰 수확이었습니다.

 

예를 들어 React를 통해 프론트엔드를 구성하면 fetch를 통해  Controller에서 제공하는 API에 HTTP 요청을 보내고

Controller가 받은 요청을 처리하며 해당하는 service를 호출하여 데이터를 처리합니다.

Service 계층에서 기능적 요구사항을 처리 및 수행하고, DAO와 Mapper 계층을 호출하여 데이터를 가져옵니다. 

그럼 Mapper로 SQL 쿼리를 실행해 데이터베이스에서 데이터를 입력하거나 가져오고, 

가져온 데이터를 controller ⇾React로 반환시킵니다.

 

 

🤝프로젝트 Review

개발을 시작한 후 첫 프로젝트는 막연하고 어려움이 많았습니다.

당시에는 "시간을 많이 투자하는 것만이 해결책"이라고 생각해 매일매일 도전에 부딪혔습니다.

최종 결과물을 보았을 때는 비록 힘들었지만, 만족스러운 성취감을 느꼈던 기억이 납니다.

 

이 프로젝트는 팀원들과 함께했기에 가능했다고 생각합니다.
매일 의견을 공유하고 해결 방법을 모색하며, 한 달처럼 느껴질 만큼 바쁜 2주를 보냈습니다.
이 과정에서 서로의 역량을 발휘하고, 프로젝트를 성공적으로 완수할 수 있었습니다.

1차 팀 프로젝트를 통해 스스로를 돌아보는 소중한 시간이 되었습니다.

왜냐하면 짧은 시간 안에 저의 장점과 단점을 명확히 알게 되었기 때문입니다.

 

제가 느끼는 저의 장점

두뇌회전이 빠르고, 팀원들의 장점과 역량을 정확하게 짚어 그 역량을 끌어낼 수 있도록 하는 점과 

시간 관리 및 프로젝트 효율성을 높이는 데 기여했다는 점입니다.

 

하지만, '잘하려는 마음'에만 집중했던 점이 단점으로 작용했습니다.
프로젝트를 진행하면서 결과물을 내는 것에 급급해 무작정 해결하려다 보니,
소스 코드나 공부하며 더 배울 수 있음에도 성장하는 데 크게 도움이 되지 못했고,
시간이 지나면 잊혀져 버리는 결과물을 남기게 되었습니다.

개발 프로젝트는 배운 언어를 내 것으로 만드는 과정이 진정한 성과라는 사실을 뒤늦게 알게 되었습니다.
하지만 당시에는 당장 눈앞의 문제를 해결하는 데만 몰두했던 점이 아쉽습니다.

 

 

회고와 성장

프로젝트가 끝난 후 돌아보니 아쉬움과 부족함이 많이 느껴졌습니다.
하지만, 이런 아쉬움이야말로 제가 성장하고 있다는 증거라고 생각합니다.
앞으로는 과정에 더 집중하며, 결과뿐 아니라 배우는 것을 놓치지 않는 개발자가 되고자 합니다. 😊

 

 

 

 


 

 

 

🔸PPT 슬라이드 일부 발췌

javachip's frtst project- 펀딩할래

 

 

 

역할

 

사용 기술 환경

 

프로젝트 소개

 

주요 페이지

 

직면했던 문제점 및 해결방안

 

첫 프로젝트 후기

 

 

 

 

 


 

 

🔸실제 구현 화면 일부 페이지

 

메인페이지

 

펀딩페이지 상단

 

펀딩페이지 하단

 

 

 

커뮤니티 탭

 

후기 탭

 

 

 

 

 


 

 

 

 

🔸시연 영상 

 

 

 


 

🔸백엔드 주요 소스 코드

 

🚩ReviewController

review controller


@RestController
@RequestMapping("/reviews")
public class ReviewsController {
	
	@Autowired
	private final ReviewsService reviewsService;

    @Autowired
    public ReviewsController(ReviewsService reviewsService) {
    	this.reviewsService = reviewsService;
    }

    @PostMapping("/{gubun}")
    public ResponseEntity<ReviewsDTO> addReviews(@PathVariable("gubun") int gubun, @RequestBody ReviewsDTO reviews) {
    		try {
    			reviews.setGubun(gubun);
    	        reviewsService.insertReviews(reviews); // 서비스 계층을 통해 리뷰를 DB에 삽입
    	        return ResponseEntity.ok(reviews); // 성공적으로 삽입되면 200 OK 응답 반환
    	    } catch (Exception e) {
    	        // 예외가 발생하면 500 Internal Server Error 응답 반환
    	        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
    	    }
    }

    @GetMapping("/{gubun}/{id}") //특정 리뷰 조회
    public ResponseEntity<ReviewsDTO> getReviewById(@PathVariable("gubun") int gubun, @PathVariable("id") int id) {
        ReviewsDTO review = reviewsService.getReviewsById(id, gubun);
        if (review != null && review.getGubun() == gubun) {
            return ResponseEntity.ok(review);
        } else {
            return ResponseEntity.notFound().build();
        }
    }
    

    @PutMapping("/{gubun}/{id}") //리뷰 업데이트
    public ResponseEntity<ReviewsDTO> updateReview(@PathVariable("gubun") int gubun,@PathVariable("id") int id, @RequestBody ReviewsDTO review) {
        try {
            review.setId(id); // ID 설정
            review.setGubun(gubun);
            int updated = reviewsService.updateReview(review);
            if (updated > 0) {
                return ResponseEntity.ok(review); // 성공적으로 업데이트된 리뷰 반환
            } else {
                return ResponseEntity.notFound().build(); // 해당 ID의 리뷰를 찾지 못한 경우
            }
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); // 서버 오류 처리
        } 
    }

    
    @DeleteMapping("/{gubun}/{id}")
    public ResponseEntity<Void> deleteReview(@PathVariable("gubun") int gubun, @PathVariable("id") int id) {
        try {
            int deleted = reviewsService.deleteReview(id, gubun);
            if (deleted > 0) {
                return ResponseEntity.ok().build(); // 성공 시 빈 응답
            } else {
                return ResponseEntity.notFound().build(); // 찾을 수 없는 경우
            }
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build(); // 서버 오류
        }
    }
    

    @GetMapping("/{gubun}") //모든 리뷰 조회
    public ResponseEntity<List<ReviewsDTO>> getAllReviews(@PathVariable("gubun") int gubun) {
        List<ReviewsDTO> reviews = reviewsService.getAllReviews(gubun);
        return ResponseEntity.ok(reviews);
    }
}

 

 

 

 

🚩ReviewserviceImpl

reviewserviceimpl


@Service
public class ReviewServiceImpl implements ReviewsService {

    @Autowired
    private ReviewsMapper reviewsDAO; // 데이터 접근 객체(DAO)를 자동으로 주입받음

    @Override
    public int insertReviews(ReviewsDTO dto) {	
        // 리뷰를 삽입하는 메서드
        return reviewsDAO.insertReviews(dto);
    }

    @Override
    public ReviewsDTO getReviewsById(int id, int gubun) {
        // ID와 구분 값으로 리뷰를 가져오는 메서드
        return reviewsDAO.getReviewById(id, gubun);
    }

    @Override
    public int updateReview(ReviewsDTO dto) {
        // 리뷰를 업데이트하는 메서드
        return reviewsDAO.updateReview(dto);
    }

    @Override
    public int deleteReview(int id, int gubun) {
        // ID와 구분 값으로 리뷰를 삭제하는 메서드
        return reviewsDAO.deleteReview(id, gubun);
    }

    @Override
    public List<ReviewsDTO> getAllReviews(int gubun) {
        // 특정 구분 값에 해당하는 모든 리뷰를 가져오는 메서드
        return reviewsDAO.getAllReviews(gubun);
    }
}

 

 

 


🚩ReviewMapper

reviewsMapper


<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.example.demo.dao.ReviewsMapper">

    <insert id="insertReviews" parameterType="com.example.demo.dto.ReviewsDTO">
        INSERT INTO reviews (id, username, text, gubun)
        VALUES (reviews_seq.NEXTVAL, #{username}, #{text}, #{gubun})
    </insert>

    <!-- 특정 gubun의 모든 리뷰 가져오기 -->
    <select id="getAllReviews" parameterType="int" resultType="com.example.demo.dto.ReviewsDTO">
        SELECT id, username, text, created_at AS createdAt, gubun
        FROM reviews
        WHERE gubun = #{gubun}
        ORDER BY created_at DESC 
    </select>
    

    <!-- 특정 id와 gubun에 해당하는 리뷰 가져오기 -->
    <select id="getReviewById" parameterType="map" resultType="com.example.demo.dto.ReviewsDTO">
        SELECT id, username, text, created_at AS createdAt, gubun
        FROM reviews
        WHERE id = #{id} AND gubun = #{gubun}
    </select>

    <!-- 댓글 수정 -->
    <update id="updateReview" parameterType="com.example.demo.dto.ReviewsDTO">
        UPDATE reviews
        SET text = #{text}, created_at = CURRENT_TIMESTAMP
        WHERE id = #{id} AND gubun = #{gubun}
    </update>

    <!-- 댓글 삭제 -->
    <delete id="deleteReview" parameterType="map">
        DELETE FROM reviews
        WHERE id = #{id} AND gubun = #{gubun}
    </delete>
    
</mapper>