DBMS에 데이터를 정의하고 저장된 데이터를 읽어와 데이터를 변경하는 프로그램을 작성하는 과정
방법
1) SQL 전용 언어 사용하기
2) 일반 프로그래밍 언어에 SQL을 삽입하여 사용하기 : 삽입된 SQL문은 DBMS 컴파일러가 처리
3) 웹 프로그래밍 언어에 SQL을 삽입하여 사용하기
4) 4GL : GUI 기반 소프트웨어 개발 도구 사용


CREATE PROCEDURE문 사용하여 정의
프로시저 = 선언부 + 실행부
선언부 : 변수, 매개변수 선언 / 실행부 : 프로그램 로직 구현
매개변수 : 저장 프로시저가 호출될 때 그 프로시저에 전달되는 값
변수 : 저장 프로시저나 트리거 내에서 사용되는 값
delimiter // --프로시저 정의 시작
CREATE PROCEDURE 프로시저이름(
OUT ....)
BEGIN
SELECT ...
FROM ...
WHERE ...;
END // --프로시저 정의 종료
delimiter;
DELIMITER 뒤에 오는 기호는 자유롭게 정할 수 있음 (시작과 끝이 동일하게만!)
테이블에 대해 특정 동작이 수행될 때 자동으로 실행되는 저장된 프로그램
사용 목적
주의사항
예시)
Q. person 테이블에 새로운 행이 삽입될 때, 같은 이름이 이미 존재하면 로그 테이블에 기록하는 트리거

개발자가 직접 작성하여 SQL 내에서 호출할 수 있는 함수
기본 제공 함수로 해결하기 어려운 로직을 캡슐화할 때 유용
종류
장점
단점
SOLID 원칙과 factory 패턴 적용해서 리팩토링 해보기
자바2 공부할 때 배웠던 내용 기억해서 정리해보자

위의 코드를 Service와 DB 나누어서 리팩토링 해보면
1) StudentService



2) DBManager

이렇게 분리 가능
더 나아가서
학생 DAO(StudetDAO) / 모델(Student) / 메인 흐름 관리(StudentTest) / DB 연결 관리(DBConnector)의 네가지 class로 분리도 가능
DBConnector
package student;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DBConnector {
private static final String URL = "jdbc:mysql://localhost:3306/test";
private static final String USER = "stdUser";
private static final String PASS = "wkvmtlf2";
public Connection getConnection() throws SQLException {
return DriverManager.getConnection(URL, USER, PASS);
}
}
Student
package student;
public class Student {
private int no;
private String dept;
private String sid;
private String name;
public Student() {}
public Student(String dept, String sid, String name) {
this.dept = dept;
this.sid = sid;
this.name = name;
}
public int getNo() {return no;}
public String getDept() {turn dept;}
public String getSid() {return sid;}
public String getName() {return name;}
public void setNo(int no) {this.no = no;}
public void setDept(String dept) {this.dept = dept;}
public void setSid(String sid) {this.sid = sid;}
public void setName(String name) {this.name = name;}
}
StudentDAO
package student;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
// 학생 정보를 DB에 삽입, 조회하는 DAO 클래스
public class StudentDao {
private final DatabaseConnector connector;
// DatabaseConnector를 받아와 DB 연결 사용
public StudentDao(DatabaseConnector connector) {
this.connector = connector;
}
// 학생 정보 INSERT 하는 메서드
public void insertStudent(Student student) {
// int nextNo = getNextNo();
String sql = "INSERT INTO student (dept, stdID, name) VALUES (?, ?, ?)";
try (Connection conn = connector.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
// SQL 쿼리에 값 바인딩
pstmt.setString(1, student.getDept());
pstmt.setString(2, student.getSid());
pstmt.setString(3, student.getName());
// 쿼리 실행
pstmt.executeUpdate();
// 자동 증가된 키 처리
try (ResultSet generatedKeys = pstmt.getGeneratedKeys()) {
if (generatedKeys.next()) {
int no = generatedKeys.getInt(1);
student.setNo(no);
System.out.println(no + " 학생 정보가 추가되었습니다.");
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
// DB에서 모든 학생을 가져오는 메서드
public List<Student> getAllStudents() {
List<Student> students = new ArrayList<>();
String sql = "SELECT * FROM student order by no ASC ";
try (Connection conn = connector.getConnection();
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql)) {
// 결과셋(ResultSet) 반복하면서 Student 객체 생성 및 리스트에 추가
while (rs.next()) {
Student s = new Student();
s.setNo(rs.getInt("no")); // 자동 증가 ID
s.setDept(rs.getString("dept"));
s.setSid(rs.getString("stdID"));
s.setName(rs.getString("name"));
students.add(s);
}
} catch (SQLException e) { // SQL 예외 처리
e.printStackTrace();
}
return students; // 조회한 학생 리스트 반환
}
}
StudentTest
package student;
import java.util.List;
public class StudentTest {
public static void main(String[] args) {
// 연결
DatabaseConnector connector = new DatabaseConnector();
StudentDao dao = new StudentDao(connector);
dao.insertStudent(new Student("떡잎마을학과", "20240129", "철수"));
List<Student> students = dao.getAllStudents();
for (Student s : students) {
System.out.printf(
"No: %d, 학과: %s, 학번: %s 이름: %s%n",
s.getNo(), s.getDept(), s.getSid(), s.getName()
);
}
}
}
1) 새로운 프로젝트 생성 : SpringBootDB
2) build.grade에 Spring Data JPA, MySQL, Driver 의존성 추가
3) application.properties에 데이터베이스 연결정보 추가
spring.application.name=SpringBootDB
spring.datasource.hikari.jdbc-url=jdbc:mariadb://localhost:3306/test
spring.datasource.hikari.username=stdUser
spring.datasource.hikari.password=wkvmtlf2
spring.datasource.hikari.driver-class-name=org.mariadb.jdbc.Driver
spring.jpa.show-sql=true
4) User클래스에 @Entity와 @Id 어노테이션 붙이기(기본생성자 넣기)
5) UserRepository 인터페이스 만들고 JpaRepository 상속받기
-> 바로 DAO 구현 끝
package kr.ac.ewha.java2.repository;
import org.springframework.data.jpa.repository.*;
import org.springframework.stereotype.Repository;
import kr.ac.ewha.java2.entity.User;
@Repository
public interface UserRepository extends JpaRepository<User, Integer> {
}
6) UserService와 DBController 구현
UserService : UserRepository 주입받은 후 CRUD 로직 구현
DBController : UserService 호출 후 CRUD가 DB와 연동되도록 완성
7) DBConfiguration 생성
8) input.html 입력폼 생성
9) SpringBootDBApplication 실행
class 분리로 구조화되어있음 -> 수정 / 확장 훨씬 용이하다
