[개념]_Spring _DB 연동

728x90

1. 기존 JDBC API 활용한 JDBC 프로그래밍 처리 절차

                                           -> try-catch 구문 불필요한 구문 구조의 불필요한 반복

(1) JDBC 클래스 지정
(2) Connection 객체 생성
(3) Statement 객체 생성
(4) SQL 실행/결과 반환
(5) 결과 정보 조회
(6) 연결 닫기
public class JdbcExample {  // 기존 JDBC 프로그래밍 
	
	public static void main(String[] args) {
			//커넥션 객체 변수
			Connection conn = null; 
			//실행문 객체 변수 
			Statement stmt = null;
			
			try{
			//(1) JDBC 클래스 지정 
				
			Class.forName("com.mysql.cj.jdbc.Driver");
			//(2) 커넥션 객체 연결 생성 
			conn =DriverManager.getConnection("jdbc:mysql://localhost/spring5fs?" + 
			"characterEncoding=utf-8&serverTimezone=UTC","spring5","spring5");
			
            //(3) Statement 객체 생성 
			stmt = conn.createStatement();
				
			//(4) SQL문 실행 
		     String sql = "SELECT * FROM Member";  //실행문 작성
		     ResultSet rs = stmt.executeQuery(sql);  //실행문 실행 후 ResultSet으로 결과 반환 받음 
			 	
		            //(5) sql 결과 정보 차례로 조회 
			while(rs.next()){
			      String email = rs.getString("email");
		                  String name = rs.getString("name");
			        System.out.println("Email: " + email + ", Name: " + name);
			 }	
		           //(6) 연결 닫기 
			rs.close();
			stmt.close();
			conn.close();
			
			} catch(SQLException se) { 
				se.printStackTrace();
			} catch(Exception e){
				e.printStackTrace();
			} finally{ 
				try{
				if(stmt!=null) 
					stmt.close();
				} catch(SQLException se2){ 
					
				}
				try{
					if(conn!=null) 
						conn.close();
					}catch(SQLException se){ 
						se.printStackTrace(); }
					}
			}
		}

2. Spring JDBC 기능 사용 절차

                                   -> 기존 JDBC 프로그래밍의 단점 보완함

(1) 데이터베이스와 연결 : DataSource 객체에 연결 정보 세팅 후 연결함
                                 *커넥션 풀로‘DataSource객체 사용함
(2) sql 쿼리문 실행 : JdbcTemplate 제공하는 쿼리문으로 간단히 실행
(3) 결과 받기 : RowMapper로 결과 반환받음

[스프링의 DB 사용 절차]

프로젝트 생성 및 관련 모듈 추가

- pom.xml 에 추가해야 할 모듈 : spring-jdbc / tomcat-jdbc / myspl-connector-java

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.6.7</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.example</groupId>
	<artifactId>DB1</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>DB1</name>
	<description>Day 0503 실습</description>
	<properties>
		<java.version>1.8</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jdbc</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-jdbc</artifactId>
		</dependency>
		<dependency>
			<groupId>org.mybatis.spring.boot</groupId>
			<artifactId>mybatis-spring-boot-starter</artifactId>
			<version>2.2.2</version>
		</dependency>

		<dependency>
			<groupId>org.apache.tomcat</groupId>
			<artifactId>tomcat-jdbc</artifactId>
		</dependency>

		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>

	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

DB 테이블 생성 + 사용할 데이터 추가

//  MySQl DB에 spring5 계정 생성 
create user 'spring5'@'localhost' identified by 'spring5';
// 데이터베이스 생성 
create database spring5fs character set=utf8;
// 위 계정이 DB에 접근 가능 궈한 부여 
grant all privileges on spring5fs.* to 'spring5'@'localhost';

// DB 테이블 생성 
create table spring5fs.MEMBER (
    ID int auto_increment primary key,
    EMAIL varchar(255),
    PASSWORD varchar(100),
    NAME varchar(100),
    REGDATE datetime,
    unique key (EMAIL) 
) engine=InnoDB character set = utf8;

// 데이터 추가
insert into MEMBER (EMAIL, PASSWORD, NAME, REGDATE)
values (‘madvirus@madvirus,net’, ‘1234’, ‘cbk’, now() );

 

DataSource 객체 생성

- 커넥션 풀로서 이 객체를 사용한다.
- 이 객체를 빈으로 등록 시, DB 연결 정보를 세팅해준다.
- (JDBC Driver/ URL/ 사용자 계정 Username. password) 등을 설정
- 추가로 커넥션풀 set() 메소드로 초기화 설정 필요한 것 있다면 알아서 설정함
- 연결정보를 세팅한 DataSource 객체를 이용해서 DB 연동한다.

JdbcTemplate을 이용한 쿼리 실행

< RowMapper의 역할 : 결과 반환용 >
-검색한 Recored 하나 당 객체 하나를 생성하는 mapRow() 함수를 recore들 개수 N개 만큼 호출함
-그 결과 N개의 객체 List가 생성되어 반환받음

     (1) 조회(query) 쿼리 실행

- 여러 결과 조회 : JdbcTemplate.query() 사용

List<T> query(String sql, RowMapper<T> rowMapper)
List<T> query(String sql, Object[] args, RowMapper<T> rowMapper)
List<T> query(String sql, RowMapper<T> rowMapper, Object ... args)

- 1개의 결과 조회 : JdbcTemplate.queryForObject() 사용

T queryForObject(String sql, Class<T> requiredType)
T queryForObject(String sql, Class<T> requiredType, Objectargs)
T queryForObject(String sql, RowMapepr<T> rowMapper)
T queryForObject(String sql, RowMapepr<T> rowMapper, Objectargs)

     (2) 변경 (INSERT / UPDATE / DELETE ) 쿼리 실행

-JdbcTemplate.update() 함수는 쿼리 실행 결과로 변경된 행의 개수반환함

int update(String sql)
int update(String sql, Object...args)

[ update() '쿼리' 실행 방식  : 2가지 ]

   ⓐ 쿼리 인덱스 파라미터의 값을 ? 에 인자로 전달

public void update(Member member) {

	jdbcTemplate.update(
	"update MEMBER set NAME = ?, PASSWORD = ? where EMAIL = ?",
	member.getName(), member.getPassword(), member.getEmail());
}

   ⓑ PreparedStatementCreator 이용

- PreparedStatementset메소드 사용해서 '직접' 인덱스 파라미터 값 설정

jdbcTemplate.update(new PreparedStatementCreator() {
	@Override
	public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
		//파라미터로 전달받은 Connection 을 이용하여 PreparedStatement 생성 
		PreparedStatement pstmt = con.prepareStatement(
		 "insert into MEMBER(EMAIL, PASSWORD, NAME, REGDATE) values(?, ?, ?, ?) ");
		// 인덱스 파라미터 값 차례로 설정
		pstmt.setString(1, member.getEmail());
		pstmt.setSString(2, member.getPassword());
		pstmt.setString(3, member.getName());
		pstmt.setTimestamp(4, Timestamp.valueOf(member.getRegisterDateTime()));
		return pstmt;
	}
});

[레코드 추가하기 ]

- DB 테이블의 column 중에서 “ID” 값은 일반적으로 자동 생성됨

- mySql은 레코드 삽입 시 ID를 자동으로 생성함. 따라서 ID 필드값 필요 X


[자동 생성된 키값 구하기] : KeyHolder 이용

- DB 테이블 생성 시, ID의 경우 auto_increment 로 지정했기 때문에 자동 증가 칼럼

- 자동 증가 칼럼에 값 삽잆 시, 해당 칼럼 값은 자동으로 생성되므로 따로 값 지정 필요 X

- 그런데, 쿼리 실행 후 자동생성된 키 값을 알고 싶을 때는 KeyHolder 사용한다.

- JdbcTemplateupdate() 메소드는 PreparedStatement를 실행한 후 자동 생성된 킷값을 KeyHolder에 보관한다. 따라서 KeyHoldergetKey() 메소드 사용하여 킷값 구하면 된다.


[스프링 Exception 변환 처리]

스프링은 데이터 접근 시 발생하는 Exception을 모두 DataAccessException 타입으로 변환시켜서 처리한다.

-동일한 코드로 익셉션 일괄 처리 목적 


728x90