프로젝트/게시판 만들기

스프링 부트 - 게시판 만들기 3탄

반기반개퐝퐝 2024. 11. 20. 22:51

지난 회에 이어 3탄 시작합니다.

 

이번 과정은 도뎡님의 블로그 다섯 번째 게시물입니다.

https://congsong.tistory.com/15

 

스프링 부트(Spring Boot) - 게시판 CRUD 처리하기 [Thymeleaf, MariaDB, IntelliJ, Gradle, MyBatis]

본 게시판 프로젝트는 단계별(step by step)로 진행되니, 이전 단계를 진행하시는 것을 권장드립니다. 본 포스팅은 DBeaver를 기준으로 작성된 글이며, 만약 MariaDB가 설치되어 있지 않으시다면, 선행

congsong.tistory.com

 


5. 게시판 CRUD 처리하기

1. 게시판 테이블 생성하기

CREATE TABLE `tb_post`(
	`id`			bigint(20)		NOT NULL	AUTO_INCREMENT	COMMENT 'PK',
    `title`			varchar(20)		NOT NULL	COMMENT '제목',
    `content`		varchar(3000)	NOT NULL	COMMENT '내용',
    `writer`		varchar(20)	 	NOT NULL	COMMENT '작성자',
    `view_cnt		int(11)			NOT NULL	COMMENT	'조회수',
    `notice_yn`		tinyint(1)		NOT NULL	COMMENT	'공지글 조회',
    `delete_yn`		tinyint(1)		NOT NULL	COMMENT '삭제 여부',
	`created_date`	datetime		NOT NULL	DEFAULT current_timestamp()	COMMENT '생성 일시',
	`modified_date`	datetime		DEFAULT NULL	COMMENT '최종 수정 일시',
    PRIMARY KEY(`id`)
)	COMMENT '게시글'

 

2. 게시글 요청(Request) 클래스 생성하기

java/com/study/domain/post/PostRequest

package com.study.domain.post
import lombok.Getter
import lombok.Setter

@Getter
@Setter
public class PostRequest{
	private Long id; //PK
    private String title; //제목
    private String content; //내용
    private String writer; //작성자
    private Boolean noticeYn; //공지글 여부
}
  • Getter/Setter
    • 롬복(Lombok) 라이브러리 기능
    • getter와 setter 생성 역할

3. 게시글 응답(Response) 클래스 생성하기

com/study/domain/post/PostResponse

package com.study.domain.post;
import lombok.Getter
import java.time.LocalDateTime;

@Getter
public class PostResponse{
	private Long id;
    private String title;
    private String content;
    private String writer;
    private int viewCnt;
    private Boolean noticeYn;
    private Boolean deleteYn;
    private LocalDateTime createdDate;
    private LocalDateTime modifiedDate;
}

 

4. Mapper 인터페이스 생성하기

com/study/domain/post/PostMapper

package com.study.domain.post;

import org.apache.ibatis.annotations.Mapper;
import java.util.List;

@Mapper
public interface PostMapper{
	void save(PostRequest params); //게시글 저장
    PostResponse findById(Long id); //게시글 상세 정보 조회
    void update(PostRequest params); //게시글 수정
    void deleteById(Long id); //게시글 삭제
    List <PostResponse> findAll; //게시글 리스트 조회
    int count(); //게시글 수 카운트
}
  • Mapper
    • 과거에는 DAO(Data Access) 클래스에 @Repository 어노테이션 추가 --> DB와 통신 클래스 명시
    • MyBatis : Mapper 인터페이스와 XML Mapper(SQL 쿼리 파일) --> DB와의 통신
      • XML Mapper에 쿼리를 선언, Mapper를 통해 쿼리 실행
      • XML Mapper에서 동일한 메서드명의 SQL id 쿼리 실행
      • Mapper에는 @Mapper 어노테이션 필요
      • XML Mapper와 namespace 속성으로 연결

DAO란? (from GPT)

더보기

DAO (Data Access Object)란?

DAO는 소프트웨어 설계에서 데이터베이스와 애플리케이션 간의 데이터를 주고받는 역할을 하는 객체입니다.
쉽게 말해, 데이터베이스 작업(조회, 삽입, 수정, 삭제)을 전담하는 계층이라고 이해하면 됩니다.


DAO의 주요 특징

  1. 데이터베이스 작업의 캡슐화:
    • 데이터베이스와 직접 상호작용하는 코드를 하나의 클래스로 모아서 관리합니다.
    • 예를 들어, JDBC, MyBatis, JPA 등으로 SQL 쿼리를 실행하는 작업을 캡슐화합니다.
  2. 비즈니스 로직 분리:
    • DAO는 데이터 작업만 담당하고, 비즈니스 로직(애플리케이션의 주된 동작)은 Service 계층에서 처리합니다.
    • 이는 코드 재사용성과 유지보수를 용이하게 합니다.
  3. 표준화된 데이터 접근 방식:
    • DAO 계층을 사용하면 데이터베이스와의 작업을 구조화할 수 있습니다.
    • 예: findById(int id), save(Entity entity) 같은 표준 메서드를 사용.

DAO의 역할

  1. 데이터베이스에서 데이터 읽기
    • 예: 특정 조건에 맞는 데이터를 가져오기
  2. 데이터베이스에 데이터 쓰기
    • 예: 새로운 데이터를 삽입
  3. 데이터베이스에서 데이터 업데이트
    • 예: 기존 데이터를 수정
  4. 데이터베이스에서 데이터 삭제
    • 예: 특정 데이터를 삭제

DAO의 장점

  • 모듈화: 데이터 접근 코드를 분리함으로써 코드가 깔끔하고 명확해집니다.
  • 재사용성: DAO 객체를 재사용할 수 있어 중복 코드를 줄일 수 있습니다.
  • 유지보수성: 데이터베이스가 변경되어도 DAO 계층만 수정하면 됩니다.
  • 테스트 용이성: 데이터 접근 코드를 별도로 테스트할 수 있어 디버깅이 쉽습니다.

DAO의 예제

1. 기본 DAO 클래스 (JDBC 사용 예시)

java
코드 복사
public class UserDao { private Connection connection; public UserDao(Connection connection) { this.connection = connection; } // 데이터 조회 public User findById(int id) throws SQLException { String query = "SELECT * FROM users WHERE id = ?"; try (PreparedStatement stmt = connection.prepareStatement(query)) { stmt.setInt(1, id); ResultSet rs = stmt.executeQuery(); if (rs.next()) { return new User(rs.getInt("id"), rs.getString("name")); } } return null; } // 데이터 삽입 public void save(User user) throws SQLException { String query = "INSERT INTO users (name) VALUES (?)"; try (PreparedStatement stmt = connection.prepareStatement(query)) { stmt.setString(1, user.getName()); stmt.executeUpdate(); } } }

2. 사용 예

java
코드 복사
public class Main { public static void main(String[] args) throws SQLException { Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "user", "password"); UserDao userDao = new UserDao(connection); // 데이터 삽입 userDao.save(new User("John Doe")); // 데이터 조회 User user = userDao.findById(1); System.out.println(user.getName()); } }

정리

  • DAO란? 데이터베이스와 통신하는 코드를 모아놓은 객체입니다.
  • 왜 사용하는가?
    • 코드 재사용성 증가
    • 유지보수성 향상
    • 비즈니스 로직과 데이터 접근 코드 분리
  • 어떻게 동작하는가?
    • DAO 계층에서 SQL을 실행해 데이터를 읽고, 쓰고, 수정하고, 삭제합니다.

이를 통해 코드 구조가 명확해지고 데이터베이스와의 작업이 효율적으로 이루어집니다.

MyBatis란? (from. chat GPT)

더보기
 

MyBatis란?

MyBatis는 자바 기반의 SQL 매핑 프레임워크로, 데이터베이스와의 상호작용을 보다 쉽게 처리할 수 있도록 도와주는 도구입니다.
MyBatis는 SQL 쿼리를 기반으로 동작하며, 개발자가 직접 작성한 SQL 쿼리를 자바 객체와 매핑해줍니다.


MyBatis의 주요 특징

  1. SQL 중심의 데이터 액세스:
    • SQL 문장을 직접 작성하고 이를 데이터베이스에 전달합니다.
    • 복잡한 SQL 작업이 필요한 경우 유리합니다.
  2. ORM 대체 또는 보완:
    • JPA와 같은 ORM 프레임워크는 객체 중심으로 동작하지만, MyBatis는 SQL 중심으로 동작합니다.
    • SQL을 제어하고 싶은 경우 MyBatis가 더 적합합니다.
  3. 자동 매핑:
    • SQL 쿼리의 결과를 자바 객체(POJO)로 변환하거나, 자바 객체를 SQL의 파라미터로 자동으로 변환해줍니다.
  4. XML 또는 어노테이션 지원:
    • XML 파일로 SQL을 관리할 수 있고, 어노테이션으로도 간단한 SQL을 처리할 수 있습니다.

MyBatis의 동작 구조

MyBatis는 다음과 같은 구조로 동작합니다:

  1. Mapper:
    • SQL 쿼리와 자바 메서드를 연결해주는 인터페이스 또는 XML 파일.
  2. SQL Session:
    • 데이터베이스 연결을 관리하며 SQL 실행과 결과 처리를 담당.
  3. Configuration:
    • MyBatis 설정 파일에서 데이터베이스 연결 정보, Mapper 위치 등을 정의.

MyBatis 사용의 장점

  1. 직접적인 SQL 제어:
    • 개발자가 SQL을 직접 작성할 수 있으므로, 복잡한 쿼리도 제어 가능.
    • 데이터베이스 벤더에 따라 최적화된 SQL을 작성할 수 있음.
  2. 객체 매핑 기능:
    • SQL 실행 결과를 자바 객체로 쉽게 변환 가능.
  3. 재사용성 및 유지보수성:
    • XML 파일로 SQL을 관리하면, SQL 문을 재사용하거나 유지보수하기 쉬움.
  4. 간단한 설정 및 경량:
    • JPA보다 간단하게 설정 가능하며, 불필요한 기능이 없어 가볍게 동작.

MyBatis 사용 예제

1. Maven 의존성 추가

xml
코드 복사
<dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.13</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.34</version> </dependency>

2. MyBatis 설정 파일

xml
코드 복사
<!-- mybatis-config.xml --> <configuration> <environments default="development"> <environment id="development"> <transactionManager type="JDBC" /> <dataSource type="POOLED"> <property name="driver" value="com.mysql.cj.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/mydb" /> <property name="username" value="root" /> <property name="password" value="password" /> </dataSource> </environment> </environments> <mappers> <mapper resource="com/example/mapper/UserMapper.xml" /> </mappers> </configuration>

3. Mapper 인터페이스

java
코드 복사
public interface UserMapper { User getUserById(int id); void insertUser(User user); }

4. Mapper XML 파일

xml
코드 복사
<!-- UserMapper.xml --> <mapper namespace="com.example.mapper.UserMapper"> <select id="getUserById" resultType="User"> SELECT * FROM users WHERE id = #{id} </select> <insert id="insertUser"> INSERT INTO users (name, email) VALUES (#{name}, #{email}) </insert> </mapper>

5. MyBatis를 활용한 DAO

java
코드 복사
import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; public class UserDao { private SqlSessionFactory sqlSessionFactory; public UserDao() throws IOException { String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); } public User getUserById(int id) { try (SqlSession session = sqlSessionFactory.openSession()) { UserMapper mapper = session.getMapper(UserMapper.class); return mapper.getUserById(id); } } public void insertUser(User user) { try (SqlSession session = sqlSessionFactory.openSession()) { UserMapper mapper = session.getMapper(UserMapper.class); mapper.insertUser(user); session.commit(); } } }

6. 실행

java
코드 복사
public class Main { public static void main(String[] args) throws IOException { UserDao userDao = new UserDao(); // 데이터 삽입 User user = new User("John Doe", "john.doe@example.com"); userDao.insertUser(user); // 데이터 조회 User retrievedUser = userDao.getUserById(1); System.out.println("Retrieved User: " + retrievedUser.getName()); } }

MyBatis의 한계

  1. SQL 작성 부담:
    • 모든 SQL을 직접 작성해야 하므로, CRUD 작업이 많은 경우 코드가 많아질 수 있음.
  2. 복잡한 객체 매핑:
    • 객체 간의 관계를 매핑하는 작업이 복잡할 수 있음(JPA 같은 ORM보다 불편).
  3. 벤더 의존성:
    • SQL 문장이 데이터베이스 벤더에 따라 달라질 수 있음.

MyBatis vs JPA

특징MyBatisJPA
SQL 제어 직접 작성 (SQL 중심) 자동 생성 (JPQL 중심)
객체-테이블 매핑 간단한 매핑 복잡한 매핑 지원
사용 편의성 SQL 작성 필요, 간단한 설정 설정 복잡, 더 많은 학습 필요
유연성 높은 SQL 유연성 제한된 SQL 유연성

MyBatis는 SQL에 익숙하고 제어를 중요시하는 프로젝트에서 매우 유용합니다!

 


내용이 길어져서 오늘은 여기까지 하겠습니다!

요새 게시글이 적었는데 다시 힘내서 고고고