1️⃣ DB 생성
테이블 생성
제목, 이미지, 내용, 등록 날짜와 시간으로 구성되는 뉴스 기사를 구분하기 위해
기본키로 aid 칼럼을 둘것이다.
DB는 MariaDB이다.
CREATE DATABASE `spring`;
CREATE TABLE news (
aid INT(11) NOT NULL PRIMARY KEY AUTO_INCREMENT,
title VARCHAR(50) NOT NULL,
img VARCHAR(50) NOT NULL,
date TIMESTAMP,
content VARCHAR(50) NOT NULL
);
만든 결과는 아래와 같다.
2️⃣ News 클래스 구현
뉴스 데이터 구조를 표현하기 위한 DO 클래스이다.
테이블 구조와 일치해야한다!
하지만 화면에 보이는 날짜와 시간정보를 처리하기 위해선 Date타입보다 문자열이 유리하다.
따라서 news클래스에선 날짜시간정보를 문자열로 처리할것이다.
java > ch10 패키지에 News클래스를 만든후 아래처럼 코딩해주자.
package ch10;
public class News {
private int aid;
private String title;
private String img;
private String date;
private String content;
public int getAid() {
return aid;
}
public void setAid(int aid) {
this.aid = aid;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getImg() {
return img;
}
public void setImg(String img) {
this.img = img;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
3️⃣ NewsDAO 클래스 구현
news 테이블과 연동해서 뉴스등록, 목록 가져오기, 삭제기능을 제공하기 위한 클래스다.
위 기능 외에 추가적인 기능이 필요하면 이 클래스에서 메서드를 추가해 사용하면된다.
Open() 메서드 구현
DB연결을 위한 클래스 기본구조 작성을 할것이다.
JDBC 관련 패키지를 import 할때는 java.sql을 사용하면된다.
package ch10;
import java.sql.Connection;
import java.sql.DriverManager;
public class NewsDAO {
final String JDBC_DRIVER = "org.mariadb.jdbc.Driver";
final String JDBC_URL = "jdbc:mariadb://localhost:3306/news";
public Connection open() {
Connection conn = null;
try {
Class.forName(JDBC_DRIVER);
conn = DriverManager.getConnection(JDBC_URL, "root", "root");
}
catch (Exception e) {
e.printStackTrace();
}
return conn;
}
}
실제 프로젝트에서는 매번 DB와 연결을 만드는게 아니라 커넥션 풀을 통해 미리 생성된 연결을 받아 사용한다.
그러나 이번 프로젝트에선 각각의 메서드마다 연결을 만들고 해제할것이다.
즉, DB연결을 위한 open()메서드를 만들고 Connection객체를 리턴하는 구조다.
또한 DB연결 종료는 conn.close()와 같은 명시적인 연결 종료가 필요하지만
java 9버젼 이상부턴 try-with-resource 기법을 통해 자동으로 리소스가 종료가 가능해졌다.
따라서 연결 종료 메서드는 구현하지 않을것이다.
try-with-resource는 다음 addNews()에서 구현해볼것이다.
addNews() 메서드 구현
뉴스를 추가하는 메서드.
인자로 DO클래스에서 News타입을 받아 SQL을 완성해 실행하는 구조로 만들것이다.
public void addNews(News n) throws Exception {
Connection conn = open();
String sql = "insert into news(title, img, date, content) values(?,?,CURRENT_TIMESTAMP(), ?)";
PreparedStatement pstmt = conn.prepareStatement(sql);
try(conn; pstmt) {
pstmt.setString(1, n.getTitle());
pstmt.setString(2, n.getImg());
pstmt.setString(3, n.getContent());
pstmt.executeUpdate();
}
}
- try(conn; pstmt) : try-with-resource 기법 적용됨. 예외 발생시 해당리소스 자동으로 close함.
getAll() 메서드 구현
뉴스 기사 목록 전체를 가지고 오기위한 getAll() 메서드다.
뉴스 목록을 컨트롤러로 전달하기 위해 List로 리턴해줄것이다.
public List<News> getAll() throws Exception {
Connection conn = open();
List<News> newsList = new ArrayList<>();
String sql = "select aid, title, STR_TO_DATE(date, '%Y-%m-%d %H:%i:%S') as cdate from news";
PreparedStatement pstmt = conn.prepareStatement(sql);
ResultSet rs = pstmt.executeQuery();
try (conn; pstmt; rs) {
while(rs.next()) {
News n = new News();
n.setAid(rs.getInt("aid"));
n.setTitle(rs.getString("title"));
n.setDate(rs.getString("cdate"));
newsList.add(n);
}
}
return newsList;
}
SQL 쿼리에서 날짜 시간부분은 화면에 보기 좋게 형식을 지정한 다음 문자열로 변환해서 가져오는것이좋다.
그냥 가져오면 프로그램에서 직접 날짜 형식을 변환하는 코드를 구현해야 하기 때문.
try-with-resource 부분에 resultset이 추가되었고, 전체 뉴스 기사를 하나씩 News 타입으로 만들어 List에 추가하는 형식으로 구현됬다.
4️⃣ getNews() 메서드 구현
뉴스 목록에서 뉴스를 선택했을때 늑정 뉴스기사의 세부 내용을 보여주기 위한 메서드다.
선택한 기사의 aid(PK)를 인자로 받아 News 타입을 리턴하며
모든 필드 항목을 포함한다.
getAll()과 비슷한 구조이지만 검색결과는 하나이므로 ResultSet에서 newt()메소드는 한번만 호출하고 데이터를 받아온다.
getNews()를 호출할때 aid가 잘못되는 경우는 없지만, 문제가 발생했을 경우를 대비해
예외를 발생시킬수있다. if(rs.next() == null) 인 경우 등.
public News getNews(int aid) throws SQLException {
Connection conn = open();
News n = new News();
String sql = "select aid, title, img, STR_TO_DATE(date, '%Y-%m-%d %H:%i:%S') cdate, content from news where aid = ?";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, aid);
ResultSet rs = pstmt.executeQuery();
rs.next();
try(conn; pstmt; rs) {
n.setAid(rs.getInt("aid"));
n.setTitle(rs.getString("title"));
n.setImg(rs.getString("img"));
n.setDate(rs.getString("cdate"));
n.setContent(rs.getString("content"));
pstmt.executeQuery();
return n;
}
}
코드 구조는 SQL부분을 제외하면 getAll()과 동일하기 때문에 설명은 생략.
이제 뉴스 삭제를 위한 delNews()메서드도 만들어줄것이다.
삭제할 뉴스의 aid를 받아 뉴스를 삭제할것이다.
리턴은 없으며, aid가 없을경우 예외를 발생시켜 컨트롤러에서 문제 발생처리를 할수있도록 할것이다.
public void delNews(int aid) throws SQLException {
Connection conn = open();
String sql = "delete from news where aid = ?";
PreparedStatement pstmt = conn.prepareStatement(sql);
try(conn; pstmt) {
pstmt.setInt(1, aid);
//삭제할 aid가 없는경우
if(pstmt.executeUpdate() == 0) {
throw new SQLException("DB에러 발생");
}
}
}
이제 전체 코드를 살펴보겠다.
package ch10;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public class NewsDAO {
final String JDBC_DRIVER = "org.mariadb.jdbc.Driver";
final String JDBC_URL = "jdbc:mariadb://localhost:3306/spring"; //spring내부에 news 테이블
//DB연결
public Connection open() {
Connection conn = null;
try {
Class.forName(JDBC_DRIVER);
conn = DriverManager.getConnection(JDBC_URL, "root", "root");
}
catch (Exception e) {
e.printStackTrace();
}
return conn;
}
//뉴스추가
public void addNews(News n) throws Exception {
Connection conn = open();
String sql = "insert into news(title, img, date, content) values(?,?,CURRENT_TIMESTAMP(), ?)";
PreparedStatement pstmt = conn.prepareStatement(sql);
try(conn; pstmt) {
pstmt.setString(1, n.getTitle());
pstmt.setString(2, n.getImg());
pstmt.setString(3, n.getContent());
pstmt.executeUpdate();
}
}
//뉴스기사 목록전체 가져오기
public List<News> getAll() throws Exception {
Connection conn = open();
List<News> newsList = new ArrayList<>();
String sql = "select aid, title, STR_TO_DATE(date, '%Y-%m-%d %H:%i:%S') as cdate from news";
PreparedStatement pstmt = conn.prepareStatement(sql);
ResultSet rs = pstmt.executeQuery();
try (conn; pstmt; rs) {
while(rs.next()) {
News n = new News();
n.setAid(rs.getInt("aid"));
n.setTitle(rs.getString("title"));
n.setDate(rs.getString("cdate"));
newsList.add(n);
}
}
return newsList;
}
//뉴스 선택시 세부내용 출력
public News getNews(int aid) throws SQLException {
Connection conn = open();
News n = new News();
String sql = "select aid, title, img, STR_TO_DATE(date, '%Y-%m-%d %H:%i:%S') cdate, content from news where aid = ?";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setInt(1, aid);
ResultSet rs = pstmt.executeQuery();
rs.next();
try(conn; pstmt; rs) {
n.setAid(rs.getInt("aid"));
n.setTitle(rs.getString("title"));
n.setImg(rs.getString("img"));
n.setDate(rs.getString("cdate"));
n.setContent(rs.getString("content"));
pstmt.executeQuery();
return n;
}
}
//뉴스 삭제
public void delNews(int aid) throws SQLException {
Connection conn = open();
String sql = "delete from news where aid = ?";
PreparedStatement pstmt = conn.prepareStatement(sql);
try(conn; pstmt) {
pstmt.setInt(1, aid);
//삭제할 aid가 없는경우
if(pstmt.executeUpdate() == 0) {
throw new SQLException("DB에러 발생");
}
}
}
}
[메인으로 돌아가기]
'Java Spring > 책공부 1 (JSP와 스프링)' 카테고리의 다른 글
20. 뷰 구현 (0) | 2022.07.15 |
---|---|
19. 컨트롤러 구현 (0) | 2022.07.14 |
17. 뉴스기사 관리 서비스 설계 (0) | 2022.07.14 |
16. JDBC 종합 : 학생정보 조회와 등록 (0) | 2022.07.13 |
15. SQL : 학생정보 목록 생성 (0) | 2022.07.12 |