[Spring 10-1] Spring DAO 기능을 이용하여 DAO 클래스 작성

임승현·2023년 2월 20일

Spring

목록 보기
25/46

🌈VO 클래스 생성

📃Student.java

※ xyz.itwill08.dao 패키지에 Student.java 클래스 생성

package xyz.itwill08.dao;
//
import lombok.Data;
/*
이름       널?       유형            
-------- -------- ------------- 
NO       NOT NULL NUMBER(4)     
NAME              VARCHAR2(50)  
PHONE             VARCHAR2(20)  
ADDRESS           VARCHAR2(100) 
BIRTHDAY          DATE 
 */
//학생정보를 저장하기 위한 클래스 - VO 클래스(DTO 클래스)
@Data
public class Student {
	private int no;
	private String name;
	private String phone;
	private String address;
	private String birthday;
}

🌈DAO 인터페이스 생성

📃StudentDAO.java

※ xyz.itwill08.dao 패키지에 Student.java 인터페이스 생성

package xyz.itwill08.dao;
//
import java.util.List;
//
public interface StudentDAO {
	int insertStudent(Student student);
	int updateStudent(Student student);
	int deleteStudent(int no);
	Student seleteStudent(int no);
	List<Student> seleteStudentList();
}

🌈DAOImplOne 클래스 생성

📃StudentDAOImpleOne.java

※ xyz.itwill08.dao 패키지에 StudentDAOImpleOne.java 클래스 생성

package xyz.itwill08.dao;
//
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import lombok.Setter;
//
//Spring DAO 기능을 이용하여 DAO 클래스 작성 - spring-jdbc 라이브러리를 프로젝트에 빌드 처리
//→ JdbcTemple 객체의 템플릿 메소드를 호출하여 DAO 클래스의 메소드 작성
// JdbcTemple 객체를 제공받아 사용하는 방법
//1. DI(Dependency Injection)를 이용하여 JdbcTemple 객체를 제공받아 필드에 저장하여 사용
//2. JdbcDaoSupport 클래스를 상속받아 JdbcTemple 객체를 Getter 메소드를 호출하여 사용
//
@Setter
public class StudentDAOImplOne implements StudentDAO {
	//JdbcTemplate 객체를 저장하기 위한 필드
	//→ Spring Bean Configuration File에서 클래스를 Spring Bean으로 등록할 때 JdbcTemplate 클래스의 
	//	Spring Bean을 제공받아 의존관계 구현 - Setter 메소드를 이용한의존성 주입
	private JdbcTemplate jdbcTemplate;
	//
	@Override
	public int insertStudent(Student student) {
		String sql="insert into student values(?,?,?,?,?)";
		//jdbcTemplate.update(String sql, Object ... args) : SQL 명령(INSERT,UPDATE,DELETE)을 DBMS 서버에 전달하여 실행하는 메소드 - 조작행의 갯수 반환
		//→ 매개변수에는 DBMS 서버에 전달할 SQL 명령과 SQL 명령의 InParameter(?)에 대신 표현될 값을 차례대로 나열하여 제공
		//→ SQL 명령의 InParameter(?) 갯수만큼 반드시 args 매개변수에 값을 전달
		return jdbcTemplate.update(sql, student.getNo(), student.getName(), student.getPhone(), student.getAddress(), student.getBirthday());
	}
	//
	@Override
	public int updateStudent(Student student) {
		String sql="update student set name=?,phone=?,address=?,birthday=? where no=?";
		return jdbcTemplate.update(sql, student.getName(), student.getPhone(), student.getAddress(), student.getBirthday(), student.getNo());
	}
	//
	@Override
	public int deleteStudent(int no) {
		return jdbcTemplate.update("delete from student where no=?", no);
	}
	//
	@Override
	public Student seleteStudent(int no) {
		try {
			String sql="select * from student where no=?";
			//JdbcTemplate.queryForObject(String sql, RowMapper<T> rowMapper, Object ... args)
			//→ SQL 명령(SELECT)을 DBMS 서버에 전달하여 실행하는 메소드
			//→ 단일행의 검색결과를 하나의 Java 객체로 반환받기 위해 사용
			//→ 매개변수에는 DBMS 서버에 전달할 SQL 명령과 검색행을 Java 객체로 변환하기 위한 매핑정보를 저장한 RowMapper 객체와 
			//	SQL 명령의 InParameter(?)에 대신 표현될 값을 차례대로 나열하여 제공
			//RowMapper 객체 : 검색행의 컬럼값을 Java 객체의 필드값으로 저장하여 반환하기 위한 정보를 제공하는 객체
			//→ RowMapper 인터페이스를 상속받은 익명의 내부클래스(Anonymous Inner Class)로 객체 생성
			//→ RowMapper 인터페이스의 제네릭에는 RowMapper 객체가 매핑하여 반환할 Java 객체의 자료형(클래스)을 설정
			//→ RowMapper 인터페이스 mapRow 추상메소드를 반드시 오버라이드 선언
			//→ mapRow 메소드 : 검색행의 컬럼값을 객체 필드에 매핑되도록 설정 - 매개변수로 검색결과를 제공받아 사용 가능
			return jdbcTemplate.queryForObject(sql, new RowMapper<Student>() {
				@Override
				public Student mapRow(ResultSet rs, int rowNum) throws SQLException {
					Student student=new Student();
					student.setNo(rs.getInt("no"));
					student.setName(rs.getString("name"));
					student.setPhone(rs.getString("phone"));
					student.setAddress(rs.getString("address"));
					student.setBirthday(rs.getString("birthday"));
					return student;
				}
			}, no);
		} catch (EmptyResultDataAccessException e) {
			//EmptyResultDataAccessException : queryForObject() 메소드에 의해 검색된 행이
			//없는 경우 발생되는 예외
			return null;
		}
	}
	//
	@Override
	public List<Student> seleteStudentList() {
		String sql="select * from student order by no";
		//JdbcTemplate.query(String sql, RowMapper<T> rowMapper, Object ... args)
		// => SQL 명령(SELECT)을 DBMS 서버에 전달하여 실행하는 메소드
		// => 다수행의 검색결과를 List 객체로 반환받기 위해 사용 - 하나의 검색행은 List 객체의 요소로 추가
		// => 매개변수에는 DBMS 서버에 전달한 SQL 명령과 검색행을 Java 객체로 변환하기 위한 매핑정보를 
		//저장한 RowMapper 객체와 SQL 명령의 InParameter(?) 대신 표현될 값을 차례대로 나열하여 제공
		return jdbcTemplate.query(sql, new RowMapper<Student>() {
			@Override
			public Student mapRow(ResultSet rs, int rowNum) throws SQLException {
				Student student=new Student();
				student.setNo(rs.getInt("no"));
				student.setName(rs.getString("name"));
				student.setPhone(rs.getString("phone"));
				student.setAddress(rs.getString("address"));
				student.setBirthday(rs.getString("birthday"));
				return student;
			}
		});
	}
}

🌈Service 인터페이스 생성

📃StudentService.java

※ xyz.itwill08.dao 패키지에 StudentService.java 인터페이스 생성

package xyz.itwill08.dao;
//
import java.util.List;
//
public interface StudentService {
	//5개의 메소드 생성
	void addStudent(Student student);
	void modifyStudent(Student student);
	void removeStudent(int no);
	Student getStudent(int no);
	List<Student> getStudentList();
}

🌈ServiceImpl 클래스 생성

📃StudentServiceImple.java

※ xyz.itwill08.dao 패키지에 StudentServiceImple.java 클래스 생성

package xyz.itwill08.dao;
//
import java.util.List;
import lombok.Setter;
//StudentService 인터페이스의 메소드를 오버라이드
@Setter
public class StudentServiceImpl implements StudentService {
	//studentDAO 인터페이스를 상속받은 자식클래스의 객체를 저장하기 위한 필드
	//→ Spring Bean Configuration File에서 Service 클래스를 Spring Bean으로 등록할 때 DAO 클래스의 Spring Bean를 제공받아 의존관계 구현 - Setter 메소드를 이용한 의존성 주입
	private StudentDAO studentDAO;
	//
	@Override
	public void addStudent(Student student) {
		studentDAO.insertStudent(student);		
	}
	@Override
	public void modifyStudent(Student student) {
		studentDAO.updateStudent(student);
	}
	@Override
	public void removeStudent(int no) {
		studentDAO.deleteStudent(no);
	}
	@Override
	public Student getStudent(int no) {
		return studentDAO.seleteStudent(no);
	}
	@Override
	public List<Student> getStudentList() {
		return studentDAO.seleteStudentList();
	}
}

🌈프로그램 생성

📃StudentApp.java

※ xyz.itwill08.dao 패키지에 StudentApp.java 클래스 생성

package xyz.itwill08.dao;
//
import java.util.List;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
//
public class StudentApp {
	public static void main(String[] args) {
		ApplicationContext context=new ClassPathXmlApplicationContext("08_dao.xml");
		StudentService service=context.getBean("studentService", StudentService.class);
		System.out.println("================================================================");
		/*
		//새로운 학생정보를 Student 테이블에 삽입되는지 확인용 코드 
		Student newStudent=new Student();
		newStudent.setNo(6000);
		newStudent.setName("홍경례");
		newStudent.setPhone("010-4687-1311");
		newStudent.setAddress("서울시 도봉구");
		newStudent.setBirthday("1999-05-05");
		service.addStudent(newStudent);
		*/
		/*
		//학생의 이름, 생년월일을 변경하는 코드
		Student searchStudent=service.getStudent(6000);
		//System.out.println(searchStudent);
		searchStudent.setName("로빈훗");
		searchStudent.setBirthday("1999-02-05");
		service.modifyStudent(searchStudent);
		*/
		/*
		//학번이 6000인 학생을 삭제하는 코드
		service.removeStudent(6000);
		*/
		List<Student> studentList=service.getStudentList();
		for(Student student:studentList) {
			System.out.println("학번 = "+student.getNo()+", 이름 = "+student.getName()+", 전화번호 = "+student.getPhone()
			+", 주소 = "+student.getAddress()+", 생년월일 = "+student.getBirthday().substring(0, 10));
		}
		System.out.println("================================================================");
		((ClassPathXmlApplicationContext)context).close();
	}
}

🌈환경설정파일 생성

📃08_dao.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
	<!-- ================================================================================ -->
	<!-- Spring Framework의 spring-jdbc 라이브러리의 DriverManagerDataSource 클래스를 Spring Bean으로 등록 -->
	<!-- → DBCP(DataBase Connection Pool) 기능을 제공하는 DataSource 객체 생성 -->
	<!-- → DataSource 객체 필드에 Connection 객체를 생성하기 위한 값을 전달하여 저장 - Setter Injection -->
	<bean class="org.springframework.jdbc.datasource.DriverManagerDataSource" id="dataSource">
		<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
		<property name="url" value="jdbc:oracle:thin:@localhost:1521:xe"/>
		<property name="username" value="scott"/>
		<property name="password" value="tiger"/>
	</bean>
	<!-- ================================================================================ -->
	<!-- ================================================================================ -->
	<!-- JdbcTemplate 클래스를 Spring Bean으로 등록 -->
	<!-- dataSource 필드에 DataSource 인터페이스를 상속받은 자식클래스의 Spring Bean을 제공받아 의존성 주입 - Setter Injection -->
	<bean class="org.springframework.jdbc.core.JdbcTemplate" id="jdbcTemplate">
		<property name="dataSource" ref="dataSource"></property>
	</bean>
	<!--                                                                                 -->
	<!-- StudentDAO 인터페이스를 상속받은 자식클래스를 Spring Bean으로 등록 -->
	<!-- → jdbcTemplate 필드에 JdbcTemplate 클래스의 Spring Bean을 제공받아 의존성 주입 - Setter Injection -->
	<bean class="xyz.itwill08.dao.StudentDAOImplOne" id="studentDAOImplOne">
		<property name="jdbcTemplate" ref="jdbcTemplate"/>
	</bean>
	<bean class="xyz.itwill08.dao.StudentDAOImplTwo" id="studentDAOImplTwo">
		<property name="jdbcTemplate" ref="jdbcTemplate"/>
	</bean>
	<!--                                                                                 -->
	<!-- StudentService 인터페이스를 상속받은 자식클래스를 Spring Bean으로 등록 -->
	<!-- → studentDAO 필드에 StudentDAO 인터페이스를 상속받은 자식클래스의 Spring Bean을 제공받아 의존성 주입 - Setter Injection -->
	<bean class="xyz.itwill08.dao.StudentServiceImpl" id="studentService">
		<!-- <property name="studentDAO" ref="studentDAOImplOne"/> -->
		<property name="studentDAO" ref="studentDAOImplTwo"/>
	</bean>
</beans>

🌈DAOImplTwo 클래스 생성

📃StudentDAOImpleTwo.java

※ xyz.itwill08.dao 패키지에 StudentDAOImpleTwo.java 클래스 생성

package xyz.itwill08.dao;
//
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.support.JdbcDaoSupport;
//
//JdbcDaoSupport 클래스를 상속받아 DAO 클래스 작성
//→ JdbcDaoSupport 클래스 : JdbcTemplate 객체를 포함하고 있는 클래스
public class StudentDAOImplTwo extends JdbcDaoSupport implements StudentDAO {
	@Override
	public int insertStudent(Student student) {
		String sql="insert into student values(?,?,?,?,?)";
		//JdbcDaoSupport 클래스의 getJdbcTemplate() 메소드를 호출하여 JdbcTemplate 객체를 
		//반환받아 템플릿 메소드 호출
		return getJdbcTemplate().update(sql, student.getNo(), student.getName()
				, student.getPhone(), student.getAddress(), student.getBirthday());
	}
	//
	@Override
	public int updateStudent(Student student) {
		String sql="update student set name=?,phone=?,address=?,birthday=? where no=?";
		return getJdbcTemplate().update(sql, student.getName(), student.getPhone()
				, student.getAddress(), student.getBirthday(), student.getNo());
	}
	//
	@Override
	public int deleteStudent(int no) {
		return getJdbcTemplate().update("delete from student where no=?", no);
	}
	//
	@Override
	public Student seleteStudent(int no) {
		try {
			String sql="select * from student where no=?";
			//RowMapper 인터페이스를 상속받은 자식클래스를 객체로 생성하여 매개변수에 전달
			//→ 중복된 코드를 최소화하여 유지보수의 효율성 증가
			return getJdbcTemplate().queryForObject(sql, new StudentRowMapper(), no);
		} catch (EmptyResultDataAccessException e) {
			return null;
		}
	}
	//
	@Override
	public List<Student> seleteStudentList() {
		String sql="select * from student order by no";
		return getJdbcTemplate().query(sql, new StudentRowMapper());
	}
	//
	//RowMapper 인터페이스를 상속받은 자식클래스 - 내부 클래스(Inner Class - Nested Class)
	//→ 검색행의 컬럼값을 객체 필드에 저장하는 매핑정보를 제공하여 객체를 반환하는 메소드
	public class StudentRowMapper implements RowMapper<Student> {
		@Override
		public Student mapRow(ResultSet rs, int rowNum) throws SQLException {
			Student student=new Student();
			student.setNo(rs.getInt("no"));
			student.setName(rs.getString("name"));
			student.setPhone(rs.getString("phone"));
			student.setAddress(rs.getString("address"));
			student.setBirthday(rs.getString("birthday"));
			return student;
		}
	}
}

0개의 댓글