이번 포스팅의 목차는 다음과 같다.
1. DB연동 초기설정
1) Mysql
2) 오라클
3) JDBCUtil
2. Board테이블
1) VO
2) DAO
3) service
4) 결과
3. Member테이블
1) VO
2) DAO
3) service
4) 결과
1. DB연동 초기설정
현재까지 DB연동을 위한 초기 설정으로 jar파일을 라이브러리에 추가하는 방식으로 진행하였는데, 스프링에서는 pom.xml설정 파일을 통해 라이브러리를 설정할 수 있다.
보편적으로 아래의 경로를 통해 pom.xml파일을 확인할 수 있다.
해당 파일에서 16번 라인을 보면 <dependencies>태그를 확인할 수 있는데, 이 태그 내부에서 라이브러리 관련 설정을 마칠 수 있다.
1) Mysql
드래그 된 부분에 해당 코드를 추가하는 것 만으로 라이브러리를 적용할 수 있다.
코드는 다음과 같다.
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.45</version>
</dependency>
2) 오라클
설정과 내용들은 모두 위와 같으며, 코드의 내용만 달라지게 되는데 오라클인 경우 코드는 다음과 같다.
<dependency>
<groupId>com.oracle.database.jdbc</groupId>
<artifactId>ojdbc6</artifactId>
<version>11.2.0.4</version>
</dependency>
3) JDBCUtil
이전 작업과 마찬가지로 DB의 연결, 해제와 관련하여 반복되는 로직을 별도로 생성하여 관리한다.
테이블의 종류와 상관없이 공통적으로 들어갈 로직이기에 common패키지를 생성한다.
코드의 내용은 다음과 같다.
package com.test.app.common;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class JDBCUtil {
static final String driverName="com.mysql.cj.jdbc.Driver";
static final String url="jdbc:mysql://localhost:3306/hamdb"; //hamdb부분은 본인이 사용중인 db이름 입력
static final String user="root";
static final String passwd="12341234";
// DB연결
public static Connection connect() {
Connection conn = null;
try {
Class.forName(driverName);
conn = DriverManager.getConnection(url, user, passwd);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return conn;
}
//DB연결끊기
public static void disconnect(PreparedStatement pstmt,Connection conn) {
try {
pstmt.close();
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
* sql *
mysql을 사용하였으며, 생성된 테이블은 아래와 같다.
create table member(
id varchar(20) primary key,
password varchar(20),
name varchar(30),
role varchar(20)
);
insert into member values('test','1234','테스트','USER');
insert into member values('admin','1234','관리자','ADMIN');
delete from member where id='test';
update member set password='1234',name='테스트' where id='test';
select * from member;
create table board(
bid int primary key auto_increment,
title varchar(50),
writer varchar(30),
content varchar(100)
);
insert into board (title, writer, content) values('제목 테스트','관리자','내용 테스트');
select * from board;
drop table board;
2. Board테이블
1) VO
board테이블 관련된 작업에 대하여 두개의 패키지를 생성하였는데, board 패키지에는 그저 내용만을 담고 있는 파일들을 관리하고 board.impl패키지에는 실질적으로 DB와 관련하여 무언가를 수행하는 파일을 관리할 목적이다.
쉽게 말해 impl에 담긴 파일만이 스프링 컨테이너의 관리하에 있을 예정이다.
생성 경로는 아래와 같다.
vo파일은 board패키지에 해당한다.
코드의 첨부이다.
package com.test.app.board;
public class BoardVO {
private int bid;
private String title;
private String writer;
private String content;
public int getBid() {
return bid;
}
public void setBid(int bid) {
this.bid = bid;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getWriter() {
return writer;
}
public void setWriter(String writer) {
this.writer = writer;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
@Override
public String toString() {
return "BoardVO [bid=" + bid + ", title=" + title + ", writer=" + writer + ", content=" + content + "]";
}
}
2) DAO
dao는 실제 수행해야 할 메서드들이 담겨있으므로 impl패키지에 담아 관리한다. 이전 실습의 내용을 참고해 예시를 들자면 dao가 리모컨이나 워치의 역할을 하는 셈이다. 어노테이션에 대한 내용은 아래 단락에서 설명 예정이다.
package com.test.app.board.impl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Repository;
import com.test.app.board.BoardVO;
import com.test.app.common.JDBCUtil;
@Repository("boardDAO") // 컴포넌트 대신 ! DB와 관련된 작업을 하는 컴포넌트
public class BoardDAO {
private Connection conn=null;
private PreparedStatement pstmt=null;
private ResultSet rs= null;
private final String BOARD_INSERT="insert into board (title, writer, content) values(?,?,?)";
private final String BOARD_SELECTONE="select * from board where bid=?";
private final String BOARD_SELECTALL="select * from board order by bid desc";
private final String BOARD_UPDATE="update board set title=?,content=? where bid=?";
private final String BOARD_DELETE="delete board where bid=?";
public void insertBoard(BoardVO vo) {
conn=JDBCUtil.connect();
try {
pstmt=conn.prepareStatement(BOARD_INSERT);
pstmt.setString(1, vo.getTitle());
pstmt.setString(2, vo.getWriter());
pstmt.setString(3, vo.getContent());
pstmt.executeUpdate();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
JDBCUtil.disconnect(pstmt, conn);
}
}
public BoardVO getBoard(BoardVO vo) {
BoardVO data=null;
conn=JDBCUtil.connect();
try {
pstmt=conn.prepareStatement(BOARD_SELECTONE);
pstmt.setInt(1, vo.getBid());
rs=pstmt.executeQuery();
if(rs.next()) {
data=new BoardVO();
data.setBid(rs.getInt("bid"));
data.setContent(rs.getString("content"));
data.setTitle(rs.getString("title"));
data.setWriter(rs.getString("writer"));
}
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
JDBCUtil.disconnect(pstmt, conn);
}
return data;
}
public List<BoardVO> getBoardList(BoardVO vo) {
List<BoardVO> datas=new ArrayList<BoardVO>();
conn=JDBCUtil.connect();
try {
pstmt=conn.prepareStatement(BOARD_SELECTALL);
rs=pstmt.executeQuery();
while(rs.next()) {
BoardVO data=new BoardVO();
data.setBid(rs.getInt("bid"));
data.setContent(rs.getString("content"));
data.setTitle(rs.getString("title"));
data.setWriter(rs.getString("writer"));
datas.add(data);
}
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
JDBCUtil.disconnect(pstmt, conn);
}
return datas;
}
public void updateBoard(BoardVO vo) {
conn=JDBCUtil.connect();
try {
pstmt=conn.prepareStatement(BOARD_UPDATE);
pstmt.setString(1, vo.getTitle());
pstmt.setString(2, vo.getContent());
pstmt.setInt(3, vo.getBid());
pstmt.executeUpdate();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
JDBCUtil.disconnect(pstmt, conn);
}
}
public void deleteBoard(BoardVO vo) {
conn=JDBCUtil.connect();
try {
pstmt=conn.prepareStatement(BOARD_DELETE);
pstmt.setInt(1, vo.getBid());
pstmt.executeUpdate();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
JDBCUtil.disconnect(pstmt, conn);
}
}
}
3) service
dao의 로직을 main메서드에서 곧장 수행하지 않고, service클래스를 거칠 예정이다.
즉, DAO(M)와 Main(V)를 연결해주는 중간다리(C)의 역할을 수행할 클래스라고 정리할 수 있다.
service클래스(TV)에서 dao(Remote)의 핵심로직을 수행할 메서드(soundUp,Down)를 생성하고, 각각의 메서드들이 실제 dao의 핵심로직을 사용하는 방향으로 구현된다. 이때, service클래스들의 메서드명은 dao의 메서드명과 같아야할 필요가 있다. 때문에 메서드명을 강제하기 위하여 interface를 생성한다. 해당 클래스는 로직에 대한 내용이 없기에 board패키지에서 관리된다.
package com.test.app.board;
import java.util.List;
public interface BoardService {
public void insertBoard(BoardVO vo);
public BoardVO getBoard(BoardVO vo);
public List<BoardVO> getBoardList(BoardVO vo);
public void updateBoard(BoardVO vo);
public void deleteBoard(BoardVO vo);
}
어노테이션을 활용하기 전에 아래와 같은 설정을 마친다. "com.test.app.어쩌구"라는 패키지명들을 참조하는 코드이다.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd">
<context:component-scan base-package="com.test.app"/><!-- 어노테이션 사용 가능해짐 -->
</beans>
강제된 메서드를 사용할 클래스를 생성한다. 이때 각 메서드들이 dao의 메서드를 수행하기 위해서는 dao객체가 필요하게 되므로 멤버변수로 선언해준다. 의존성을 주입하기 위해 어노테이션을 활용하게 된다. BoardServiceImpl이라는 클래스가 BoardDAO의 메서드를 사용해야하므로 두 클래스를 객체화(초기화:new)할 필요가 있다. 때문에 @Component를 사용할 수 있지만, @Component의 하위(상속관계)에 있는 @Service를 사용함으로써, 비즈니스 로직을 수행하는 Class라는 것을 명시할 수 있다. 해당 어노테이션의 사용으로 프로그램을 수행할때 필요한 만큼만 메모리를 생성 및 관리한다. 주로 Service Class에서 쓰인다.
추가로 멤버변수 상단에 @Autowired를 사용하여 의존성을 주입한다.
package com.test.app.board.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.test.app.board.BoardService;
import com.test.app.board.BoardVO;
@Service("boardService")
public class BoardServicimpl implements BoardService {
@Autowired
private BoardDAO boardDAO;
@Override
public void insertBoard(BoardVO vo) {
boardDAO.insertBoard(vo);
}
@Override
public BoardVO getBoard(BoardVO vo) {
return boardDAO.getBoard(vo);
}
@Override
public List<BoardVO> getBoardList(BoardVO vo) {
return boardDAO.getBoardList(vo);
}
@Override
public void updateBoard(BoardVO vo) {
boardDAO.updateBoard(vo);
}
@Override
public void deleteBoard(BoardVO vo) {
boardDAO.deleteBoard(vo);
}
}
BoardDAO를 초기화할 목적으로, 객체화 할 클래스메서드 상단에 @Component를 작성할 수 있지만, 마찬가지로 @Component의 하위(상속관계)에 있는 @Repository를 사용한다. 해당 어노테이션은 DAO class에서 사용되며, DataBase에 접근하는 method를 가지고 있는 Class에서 쓰인다. 사용 목적은 위와 동일하게 객체를 명확히 설정하여 메모리 관리를 용이하게 할 목적이다.
4) 결과
Client.class
주석을 통해 내용을 파악할 수 있다.
package com.test.app.board;
import java.util.List;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;
import com.test.app.member.MemberService;
import com.test.app.member.MemberVO;
public class Client { // 클라이언트,사용자,브라우저
public static void main(String[] args) {
// 설정정보 파일에 접근
AbstractApplicationContext factory=new GenericXmlApplicationContext("applicationContext.xml");
// 스프링 컨테이너에 객체를 요청
BoardService bs=(BoardService)factory.getBean("boardService");
//메서드에 사용될 인자를 정의하기 위한 작업
BoardVO boardVO=new BoardVO();
boardVO.setTitle("어노테이션 실습");
boardVO.setContent("진짜되나??");
boardVO.setWriter("작은 티모");
bs.insertBoard(boardVO);//해당 객체가 메서드를 사용
//toString되어있기에 해당 작업으로 DB정보 조회 가능
List<BoardVO> datas=bs.getBoardList(boardVO);
for(BoardVO v:datas) {
System.out.println(v);
}
factory.close();
}
}
정상수행됨을 확인할 수 있다.
3. Member테이블
1) VO
board의 실습에서와 마찬가지이며 멤버와 관련된 두개의 패키지 중 memberVO는 member패키지에서 관리한다.
코드는 아래와 같다.
package com.test.app.member;
public class MemberVO {
private String id;
private String password;
private String name;
private String role;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
@Override
public String toString() {
return "MemberVO [id=" + id + ", password=" + password + ", name=" + name + ", role=" + role + "]";
}
}
2) DAO
모델과 관련된 패키지 중 model.impl에 저장되어 관리한다.
package com.test.app.member.impl;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Repository;
import com.test.app.common.JDBCUtil;
import com.test.app.member.MemberVO;
@Repository("memberDAO")
public class MemberDAO {
private Connection conn=null;
private PreparedStatement pstmt=null;
private ResultSet rs= null;
private final String MEMBER_INSERT="insert into member values(?,?,?,?)";
private final String MEMBER_SELECTONE="select * from member where id=?";
private final String MEMBER_SELECTALL="select * from member";
private final String MEMBER_UPDATE="update member set password=?,name=?,role=? where id=?";
private final String MEMBER_DELETE="delete from member where id=?";
public void insertMember(MemberVO vo) {
conn=JDBCUtil.connect();
try {
pstmt=conn.prepareStatement(MEMBER_INSERT);
pstmt.setString(1, vo.getId());
pstmt.setString(2, vo.getPassword());
pstmt.setString(3, vo.getName());
pstmt.setString(4, vo.getRole());
pstmt.executeUpdate();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
JDBCUtil.disconnect(pstmt, conn);
}
}
public MemberVO getMember(MemberVO vo) {
MemberVO data=null;
conn=JDBCUtil.connect();
try {
pstmt=conn.prepareStatement(MEMBER_SELECTONE);
pstmt.setString(1, vo.getId());
rs=pstmt.executeQuery();
if(rs.next()) {
data=new MemberVO();
data.setId(rs.getString("id"));
data.setPassword(rs.getString("password"));
data.setName(rs.getString("name"));
data.setRole(rs.getString("role"));
}
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
JDBCUtil.disconnect(pstmt, conn);
}
return data;
}
public List<MemberVO> getMemberList(MemberVO vo) {
List<MemberVO> datas=new ArrayList<MemberVO>();
conn=JDBCUtil.connect();
try {
pstmt=conn.prepareStatement(MEMBER_SELECTALL);
rs=pstmt.executeQuery();
while(rs.next()) {
MemberVO data=new MemberVO();
data.setId(rs.getString("id"));
data.setPassword(rs.getString("password"));
data.setName(rs.getString("name"));
data.setRole(rs.getString("role"));
datas.add(data);
}
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
JDBCUtil.disconnect(pstmt, conn);
}
return datas;
}
public void updateMember(MemberVO vo) {
conn=JDBCUtil.connect();
try {
pstmt=conn.prepareStatement(MEMBER_UPDATE);
pstmt.setString(1, vo.getPassword());
pstmt.setString(2, vo.getName());
pstmt.setString(3, vo.getRole());
pstmt.setString(4, vo.getId());
pstmt.executeUpdate();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
JDBCUtil.disconnect(pstmt, conn);
}
}
public void deleteMember(MemberVO vo) {
conn=JDBCUtil.connect();
try {
pstmt=conn.prepareStatement(MEMBER_DELETE);
pstmt.setString(1, vo.getId());
pstmt.executeUpdate();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
JDBCUtil.disconnect(pstmt, conn);
}
}
}
3) service
controller의 역할을 수행할 수 있도록 클래스를 생성하여 member service클래스 객체의 메서드가 dao의 메서드를 수행할 수 있도록 할 예정이다. 이때 dao와 service의 메서드명이 같을 수 있도록 interface를 활용하여 메서드명을 강제한다.
package com.test.app.member;
import java.util.List;
public interface MemberService {
public void insertMember(MemberVO vo);
public MemberVO getMember(MemberVO vo);
public List<MemberVO> getMemberList(MemberVO vo);
public void updateMember(MemberVO vo);
public void deleteMember(MemberVO vo);
}
@Service를 통해 memberService라는 객체를 초기화 하였으며, @Autowired를 통해 의존성을 주입한다. memberDAO의 객체 초기화는 memberDAO의 클래스 메서드 상단에 @Repository를 통해 진행한다.
package com.test.app.member.impl;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.test.app.member.MemberService;
import com.test.app.member.MemberVO;
@Service("memberService")
public class MemberServiceImpl implements MemberService {
@Autowired
private MemberDAO memberDAO;
@Override
public void insertMember(MemberVO vo) {
memberDAO.insertMember(vo);
}
@Override
public MemberVO getMember(MemberVO vo) {
return memberDAO.getMember(vo);
}
@Override
public List<MemberVO> getMemberList(MemberVO vo) {
return memberDAO.getMemberList(vo);
}
@Override
public void updateMember(MemberVO vo) {
memberDAO.updateMember(vo);
}
@Override
public void deleteMember(MemberVO vo) {
memberDAO.deleteMember(vo);
}
}
4) 결과
Client.class
스프링 컨테이너에 접근, 객체 생성을 요청, 객체 사용(필요 타입 초기화 및 값 설정)하여 정상적으로 DB에 저장됨을 확인할 수 있다.
package com.test.app.board;
import java.util.List;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;
import com.test.app.member.MemberService;
import com.test.app.member.MemberVO;
public class Client { // 클라이언트,사용자,브라우저
public static void main(String[] args) {
AbstractApplicationContext factory=new GenericXmlApplicationContext("applicationContext.xml");
MemberService ms=(MemberService)factory.getBean("memberService");
MemberVO memberVO=new MemberVO();
memberVO.setId("asdf");
memberVO.setPassword("1234");
memberVO.setName("김빡구");
memberVO.setRole("USER");
ms.insertMember(memberVO);
List<MemberVO> datass=ms.getMemberList(memberVO);
for(MemberVO a:datass) {
System.out.println(a);
}
factory.close();
}
}
로그를 활용한 확인
실제 DB에 저장된 내용
'Spring' 카테고리의 다른 글
[IoC] XML파일 @로 바꾸기 : Controller_2 (0) | 2022.04.01 |
---|---|
[IoC] MVC패턴 이해 실습_2 : Spring제공 클래스 사용 (0) | 2022.03.31 |
[IoC] MVC패턴 이해 실습_1 (0) | 2022.03.30 |
[IoC] 의존성 주입과 어노테이션 (0) | 2022.03.29 |
[개요] 설치와 Spring Framwork의 이해 (0) | 2022.03.28 |