2022년 1월 8일 토요일

Spring Data JPA소개 및 Simple 예제 실습, JPA란? HelloWorld,자바학원/SQL학원/자바교육/SQL교육/JAVA학원/JAVA교육,자바동영상

 Spring Data JPA소개 및 Simple 예제 실습, JPA란? HelloWorld,자바학원/SQL학원/자바교육/SQL교육/JAVA학원/JAVA교육,자바동영상


https://www.youtube.com/watch?v=RdIPh1iGm5A&list=PLxU-iZCqT52AlV-Y7UlwSQp8N6pMjijFX&index=7 


https://www.youtube.com/watch?v=rwDOqrM2B9Q&list=PLxU-iZCqT52AlV-Y7UlwSQp8N6pMjijFX&index=2 

https://www.youtube.com/watch?v=pue8iaffaXM&list=PLxU-iZCqT52AlV-Y7UlwSQp8N6pMjijFX&index=3 

https://www.youtube.com/watch?v=w6XoZ3Luzus&list=PLxU-iZCqT52AlV-Y7UlwSQp8N6pMjijFX&index=4 


https://www.youtube.com/watch?v=2Ct32nlhBzA&list=PLxU-iZCqT52AlV-Y7UlwSQp8N6pMjijFX&index=1 




http://ojc.asia/bbs/board.php?bo_table=LecJpa&wr_id=361 


Spring Data JPA소개 및 Simple 예제 실습, JPA란? HelloWorld

Spring Data JPA소개 및 Simple 예제 실습, JPA란? HelloWorldSpring Data JPAJPA는 ORM 기술의 자바진영 표준 스펙입니다. JPA의 실현체로는 Hibernate가 가장 널리 사용되고 있습니다. 유료버전을 제외한다면 사실

ojc.asia

https://www.youtube.com/watch?v=Xb0OEOiZ3Rg&list=PLxU-iZCqT52AlV-Y7UlwSQp8N6pMjijFX&index=6 

Spring Data JPA

JPA는 ORM 기술의 자바진영 표준 스펙입니다. JPA의 실현체로는 Hibernate가 가장 널리 사용되고 있습니다. 유료버전을 제외한다면 사실 상 쓸만한 기술로는 Hibernate 뿐이라고 할 수 있습니다. 그러므로 일반적으로 JPA를 사용해서 개발한다고 말할 때는 Hibernate를 사용하여 데이터베이스 연동로직을 처리한다고 볼 수 있습니다. 


Hibernate는 스프링 없이 단독으로 사용할 수 있는 기술입니다. 하지만 대부분의 경우 스프링 기반에서 Hibernate를 연동해서 사용합니다. 이는 스프링의 기반 기술인 IoC, AOP, PSA의 장점을 이용하고 싶기 때문입니다. 더불어 스프링이 JPA를 보다 편리하게 사용할 수 있도록 서포트하는 기술인 Spring Data JPA 기술은 Hibernate를 스프링 기반에서 사용해야 하는 강력한 이유가 됩니다. 스프링이 제공하는 기술을 사용하면 반복적이고 뻔한 로직은 더 이상 개발자가 작성할 필요가 없고 스프링이 Hibernate와 협력하여 개발자 대신 처리 해 줍니다.


마이바티스와 JPA의 가장 큰 차이점은 다음과 같습니다. 마이바티스를 사용했을 때는 개발자가 SQL 쿼리를 직접 작성해서 알려주어야 하지만 Spring Data JPA를 사용하면 SQL 쿼리는 JPA의 구현체인 Hibernate가 작성해서 사용합니다. 마이바티스가 인터페이스의 구현체를 개발자 대신 만들어서 제공하는 기능을 스프링 역시 Spring Data JPA 기술을 사용하여 선보였습니다. 개발자를 대신해서 쿼리는 Hibernate가, 인터페이스 구현체는 스프링이 처리함으로서 개발자는 반복되는 뻔한 DAO 로직에서 점점 더 해방되어 가고 있습니다. 


Spring Data JPA 기술은 마이바티스보다 한 발 더 나아가서 스프링이 제안하는 인터페이스를 상속하기만 하면 스프링이 인터페이스에 미리 정의해 놓은 메소드들을 개발자의 DAO 인터페이스 구현체를 생성하면서 그 안에 넣어 주는 서비스를 제공합니다. 


스프링은 JDBC 기술을 보다 쉽게 사용하도록 Spring JDBC로 업그레이드 해서 제공하고 있는 것을 앞서 살펴 보았습니다. 프로젝트 관리성 측면을 고려한다면 JDBC를 업그레이드한 기술인 마이바티스를 선택할 수도 있었습니다. 이러한 데이터베이스 처리 기술들은 공통적으로 개발자가 직접 SQL 쿼리를 작성해야 합니다. 


그런데 SQL 쿼리는 데이터베이스마다 조금씩 달라서 만약 데이터베이스가 변경되어야 하는 큰 환경적인 변화가 있다면 쿼리들을 모두 개발자가 작성해서 사용하는 경우 큰 난관 봉착하는데 개발자가 직접 모든 쿼리를 수작업으로 변경해야만 하기 때문입니다.. 그래서 개발자들은 데이터베이스가 바뀔 때마다 개발자가 직접 쿼리를 수정하지 않고도 처리할 수 있는 방법을 찾게 되었습니다. 

객체로 테이블을 관리하는 ORM의 역사가 이렇게 시작되었습니다. 어찌보면 자바측에서는 Hibernate의 역사가 곧 ORM의 역사라고 할 수 있습니다. Hibernate의 설립자인 개빈 킹(Gavin King)이 JPA 스펙의 근간을 설계했습니다. 


ORM에 대한 이해를 돕기 위해서 예를 들어 보면 우리는 외국인과 대화하기 위해서 해당 국가의 언어를 직접 배운 후 대화해야 합니다. 그런데 만약 통역사를 고용할 수만 있다면 직접 외국어를 배우지 않고도 통역사를 통해서 대화할 수 있게 됩니다. 이는 통역사가 중간에서 번역 서비스를 제공하기 때문에 가능한 일입니다. 다국어를 구사하는 능력 있는 통역사만 있다면 우리가 사용해야 하는 외국어가 계속 늘어나도 전혀 걱정이 없습니다.


이 개념을 데이터베이스 처리기술에 도입한 것이 ORM기술입니다.
JPA의 EntityManager가 모델 객체와 데이터베이스 중간에 개입하여 SQL쿼리를 대신 작성하여 질의하고 결과를 돌려줍니다. 따라서 개발자는 직접 질의하는 SQL을 사용하지 않고 EntityManager에게 요청하기 위해서 SQL대신 JPA가 이해하는 JPQL을 사용합니다. SQL은 데이터베이스의 방언에 따라 바꿔서 사용해야 하지만 JPQL은 바뀌지 않습니다. 바로 우리가 통역사에게 한국어(JPQL)로만 얘기해도 괜찮은 것과 비슷합니다. 여러 외국어(SQL)로 바꿔서 처리하는 것은 통역사(EntityManager)의 몫 입니다.


EntityManager는 모델 클래스를 기반으로 데이터베이스와의 질의 및 결과처리를 수행합니다. 따라서 개발자는 모델 클래스와 관련된 테이블 스키마 정보를 설정해야 합니다. 이를 설정하는 방법은 XML과 어노테이션 방식이 있습니다. JPA에서는 어노테이션으로 설정하는 방식을 선호합니다. JPA를 사용한다면 개발자는 모델 객체를 조작해서 테이블 처리작업을 수행할 수 있습니다. 이는 마치 JPA라는 다국어에 능통한 통역사를 고용한 것과 같습니다.


쿼리를 처리하는 JPA 통역사는 스마트해서 반복적인 질의를 하게 되는 경우 매번 데이터베이스에 질의하는 행동을 하지 않습니다. JPA는 Persistence Context를 사용하여 데이터를 담고 있는 모델객체들을 보관합니다. 개발자가 모델클래스를 사용해서 JPQL로 EntityManager에게 질의하면, Persistence Context 내에 요청 받은 데이터를 갖고 있는 객체가 있는지 살펴보고 있다면 데이터베이스에 질의하지 않고 바로 갖고 있는 모델객체의 복사본을 만들어 돌려줍니다. 이러한 기능을 기존에 사용하던 ehcache 캐싱서비스 등과 구분하기 위해서 1차 캐싱 기능이라고 부릅니다.


간단하게 스프링 기반에서 JPA를 사용하는 방법을 살펴보겠습니다. 

새 프로젝트 생성

File > New > Spring Starter Project >

프로젝트 명: chapter1-4 > Next >

디펜던시 선택: Web, JDBC, MySQL, JPA > Finish


JDBC 디펜던시는 선택하지 않아도 됩니다.



프로젝트 환경설정

application.properties

# DATASOURCE

spring.datasource.platform=mariadb

spring.datasource.sqlScriptEncoding=UTF-8

spring.datasource.url=jdbc:mysql://localhost:3306/testdb?createDatabaseIfNotExist=true

spring.datasource.username=root

spring.datasource.password=1111

spring.datasource.driver-class-name=com.mysql.jdbc.Driver

# JPA

spring.jpa.hibernate.ddl-auto=create

spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect

spring.jpa.show-sql=true

spring.data.jpa.repositories.enabled=true


spring.jpa.hibernate.ddl-auto=create

프로젝트 기동 시 엔티티 클래스를 바탕으로 테이블을 생성합니다. 만약 테이블이 이미 존재한다면 삭제하고 다시 생성합니다.


  • create-drop : create설정 + 프로젝트 중지 시 생성한 테이블을 삭제합니다.
  • none : 아무것도 하지 않습니다.
  • update : 엔티티와 테이블을 비교하여 일치하지 않는 부분만 처리합니다.
  • validate : 엔티티와 테이블을 비교하여 일치하지 않으면 예외를 발생시킵니다.


spring.jpa.database-platform=org.hibernate.dialect.MySQL5InnoDBDialect

Maria DB는 MySQL 계열에 데이터베이스로써 MySQL5InnoDBDialect 방언을 지정합니다. 별도의 Maria DB 전용 지정 문자열은 존재하지 않습니다.


spring.jpa.show-sql=true

JPA가 생성하여 사용하는 SQL 쿼리를 로그에 출력합니다. 엔티티매니저가 SQL 쿼리를 적합하게 사용하는지 확인할 필요가 있기 때문에 개발중에는 true로 설정합니다.


spring.data.jpa.repositories.enabled=true

Spring Data JPA가 제안하는 인터페이스를 상속한 클래스가 있으니 처리하라고 요청합니다.



스캐폴딩

다음 그림을 보고 패키지 및 폴더를 생성합니다. com.example.employee 패키지 밑으로 하부 패키지 및 클래스 파일들을 생성합니다.


    모델 클래스

JPA 기술을 사용하면 모델클래스 정의가 곧 테이블 정의가 됩니다. @Entity 어노테이션은 JPA에게 이 클래스에 테이블 정의 정보가 있다고 알려줍니다.


Employee.java

package com.example.employee.model;


import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.GenerationType;

import javax.persistence.Id;


@Entity

public class Employee {

@Id

@GeneratedValue(strategy=GenerationType.AUTO)

private Long empno;

private String ename;

private String job;


public Employee() {}


public Employee(Long empno, String ename, String job) {

this.empno = empno;

this.ename = ename;

this.job = job;

}

// getter, setter 생략

}


테이블명 설정을 위한 @Table(name="employee") 어노테이션을 지정하지 않으면 클래스이름을 테이블명으로 사용합니다. 칼럼 설정을 위한 @Column(name="ename") 어노테이션을 지정하지 않으면 필드변수 이름을 칼럼명으로 사용하고 필드변수의 자료형을 취급할 수 있는 칼럼자료형을 환경설정으로 알려 준 데이터베이스에 맞게 자동으로 선택합니다.


전통적인 개발 순서는 먼저 업무분석을 통해 논리 모델을 만들고 데이터베이스에 따라 물리 모델을 만듭니다. 따라서 완성된 ERD가 존재하게 되며 테이블들은 모두 정의서가 있는 상태가 됩니다. 테이블 정의에 따라 개발자는 모델 클래스를 생성하고 다음으로 DAO 로직 클래스를 생성하는 순서로 개발이 진행됩니다.


JPA 기술을 사용하면 전통적인 bottom-up 개발방식의 순서를 따르지 않게 됩니다. JPA 기술을 사용하면 논리모델을 만드는 순서까지는 같지만 물리모델을 만들기 전에 모델 클래스를 생성합니다. 모델 클래스에 정의한 내용을 바탕으로 JPA가 DB에 접속하여 테이블을 생성합니다. 물리모델 ERD를 얻고 싶다면 리버스 엔지니어링을 통해 얻을 수 있습니다.


JPA를 사용한다고 해서 전통적인 개발순서를 따르지 못하는 것은 아닙니다. 이미 물리모델이 존재하는 경우 이를 바탕으로 엔티티 클래스들을 얻을 수 있습니다. 대표적인 기술로써 JBoss가 제공하는 Hibernate Tools가 있습니다. JPA를 사용하지 않고 개발된 기존 프로젝트에 JPA 기술을 도입하는 경우 이 방법이 적합할 것입니다.
자세한 사용법은 다음 사이트를 참고하세요. 

http://hibernate.org/tools/



     Persistence Layer

Spring Data JPA 기술을 사용할 때 가장 큰 변화가 있는 부분은 DAO 로직을 정의하는 클래스입니다. 스프링이 제안하는 인터페이스 JpaRepository를 상속하면 부모 인터페이스들에 정의된 추상메소드들의 유효범위를 연장한 것이므로 개발자가 이런 용도의 추상메소드들을 정의할 필요가 없습니다.


EmployeeRepository.java

package com.example.employee.repository;


import org.springframework.data.jpa.repository.JpaRepository;

import org.springframework.stereotype.Repository;

import com.example.employee.model.Employee;


public interface EmployeeRepository extends JpaRepository<Employee, Long>{

// nothing

}


<Employee, Long>

첫 번째 제네릭으로 모델 클래스를 지정하고 두 번째 제네릭으로 모델 클래스 안에 키 역할을 수행하는 필드변수의 자료형을 지정합니다. @Entity가 붙어 있는 클래스가 곧 테이블 스키마라고 볼 수 있으므로 @Id가 붙어 있는 필드변수가 곧 Primary Key가 됩니다. 엔티티매니저는 제네릭으로 객체형을 요구합니다. 그에 따라 필드변수 자료형을 Wrapper클래스 자료형인 Long으로 선언합니다.


// nothing

스프링이 제공하는 기본적인 CRUD 메소드들만 필요하다면 추가로 개발자가 해야 할 작업은 없습니다. 개발자의 판단에 따라 메소드들이 더 필요하다면 추가로 정의할 수 있습니다. 이 경우 정의 된 메소드가 사용할 쿼리를 개발자가 알려줄 필요가 있습니다. 이러한 경우를 염두에 두고 스프링은 스프링이 제안하는 메소드 작성법을 따르다면 메소드가 사용해야 하는 쿼리를 별도로 알려주지 않아도 되는 기술을 제공합니다. 이를 쿼리 메소드라고 부릅니다. 뒤에서 살펴보겠습니다.


EmployeeRepository extends JpaRepository

스프링은 JpaRepository 인터페이스에서부터 부모 인터페이스들에 정의되어 있는 모든 메소드들을 EmployeeRepository 인터페이스 구현체를 만들면서 추가합니다. 모든 메소드가 필요하지는 않고 몇 개의CRUD 메소드만 필요하다면 JpaRepository 인터페이스의 부모 인터페이스들 중 하나를 바로 상속하여 사용하는 것이 좋습니다.



위 그림을 보면 프리젠테이션 레이어에서 데이터를 표시할 때 처리해야 하는 대표기능 중에 하나인 Paging 로직을 위한 findAll(Pageable) 메소드가 포함되어 있다는 것을 알 수 있습니다. 페이징 처리 코드는 뒤에서 살펴보도록 하겠습니다.


application.properties 설정파일에서 spring.data.jpa.repositories.enabled=true라고 설정했기 때문에 클래스 위에 @Repository 어노테이션은 붙일 필요가 없습니다.


 Service Layer

DAO 클래스의 메소드들을 개발자가 직접 정의하지 않고 스프링이 제안하는 메소드들을 그대로 사용함으로써 메소드명은 고정이 됩니다. 대신 개발자는 서비스 레이어에서 자신의 스타일에 맞게 메소드들을 정의해서 사용하면 됩니다.


EmployeeService.java

package com.example.employee.service;


import java.util.List;

import com.example.employee.model.Employee;


public interface EmployeeService {

public List<Employee> select();

}


EmployeeServiceImpl.java

package com.example.employee.service;


import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import com.example.employee.model.Employee;

import com.example.employee.repository.EmployeeRepository;


@Service

public class EmployeeServiceImpl implements EmployeeService {

@Autowired

private EmployeeRepository employeeRepository;


@Override

public List<Employee> select() {

return employeeRepository.findAll();

}

}


Persistence Layer

EmployeeController.java

package com.example.employee.controller;


import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.RestController;

import com.example.employee.service.EmployeeService;


@RestController

public class EmployeeController {

@Autowired

private EmployeeService employeeService;


@GetMapping("/employees")

public Object getEmployees(){

return employeeService.select();

}

}



     테스트

무엇을 테스트해야 하는지 생각해 봅니다.


@Entity가 붙어 있는 모델클래스를 바탕으로 데이터베이스에 테이블이 생성되는지 여부


application.properties 설정파일에 spring.jpa.hibernate.ddl-auto=create로 설정했으므로 기존 테이블이 있다면 삭제하고 새로 테이블을 만들어야 합니다. "create" 대신 "update"를 지정하면 변화가 있을 때만 테이블을 새로 생성합니다. "update"로 설정해서 사용하는 경우 주의할 점은 엔티티 클래스에서 필드변수명을 바꾸는 경우 테이블에 칼럼이 추가되기만 할 뿐 기존 칼럼은 삭제되지 않는다는 점 입니다. 더 이상 사용하지 않는 칼럼을 삭제하기 위해서는 테이블을 새로 만들어야 가능하므로 "create" 옵션으로 설정해야 합니다.

새로 테이블을 생성한다면 데이터가 없는 빈 테이블이므로 조회 테스트를 수행해도 결과를 얻을 수 없습니다. 조회 테스트를 위해서 더미 데이터를 미리 입력해 놓고 사용하고 싶습니다. 스프링 부트는 다음 파일을 프로젝트 기동 시 처리해 주므로 이러한 작업에 적합합니다. data.sql 파일을 프로젝트에 추가합니다.

data.sql

파일 위치: src/main/resources/data.sql

INSERT IGNORE INTO EMPLOYEE(empno, ename, job) VALUES(7839,'KING','PRESIDENT');

INSERT IGNORE INTO EMPLOYEE(empno, ename, job) VALUES(7566,'JONES','MANAGER');

INSERT IGNORE INTO EMPLOYEE(empno, ename, job) VALUES(7698,'BLAKE','MANAGER');

INSERT IGNORE INTO EMPLOYEE(empno, ename, job) VALUES(7782,'CLARK','MANAGER');

IGNORE 옵션을 사용하기 때문에 매번 프로젝트를 기동해도 키 중복 예외는 발생하지 않을 것입니다.
http://localhost:8080/employees 주소로 서버에 접근해서 결과를 확인합니다.


    정리

SQL 쿼리를 개발자가 만들지 않아도 되는 기술의 가장 큰 혜택을 받는 분야는 솔루션을 만들어 서비스하는 분야일 것입니다. 기존에는 클라이언트가 사용하는 다양한 데이터베이스를 지원하기 위해서 매번 해당 데이터베이스에 맞게 DAO로직 클래스를 만들어야 했지만 이제 더 이상 그럴 필요가 없습니다. Hibernate는 약 40개 이상의 데이터베이스 방언을 지원하고 있습니다. 


네트워크가 발전함에 따라 분산환경에서의 기술이 발전하고 있습니다. 예로 소프트웨어는 본사 서버에서 제공하고 데이터베이스는 각 지사의 데이터베이스를 이용하는 상황을 들 수 있습니다. 이 경우에 하나의 소프트웨어가 다수의 데이터베이스를 처리할 수 있어야 하므로 JPA가 훌륭한 해결책이 됩니다. 더불어서 소프트웨어의 빈번한 업데이트가 있는 경우 관리적인 측면을 고려한다면 더욱 더 JPA의 기술이 매력적으로 느껴질 것입니다.


JPA를 스프링이 서포트 하는 기술인 Spring Data JPA를 사용하면 이제 개발자는 DAO 인터페이스에 추상메소드들을 정의하는 작업도 필요 없게 되었습니다. 기본적인 CRUD 메소드는 스프링이 정의한 인터페이스를 상속하는 걸로 스프링이 미리 정의해 놓은 메소드들을 이용할 수 있습니다.

 


그러나 많은 경우 스프링이 제안하는 추상 메소드들 외에 메소드들이 필요합니다. 개발자가 추가하는 메소드들도 스프링은 최대한 자동적으로 처리되도록 해 주는 서비스를 제공합니다.



#JPA, #SpringDataJPA, #JPA교육, #JPA동영상, #JPAHElloWorld, #스프링교육, #자바교육, #JAVA교육, #스프링학원, #자바학원, #JAVA학원, JPA, SpringDataJPA, JPA교육, JPA동영상, JPAHElloWorld, 스프링교육, 자바교육, JAVA교육, 스프링학원, 자바학원, JAVA학원,

오라클,PL/SQL,DBMS_SQL,동적SQL실습 테이블 생성, 멀티행 입력,BIND_ARRAY, EXECUTE, 오라클교육, 오라클학원, 오라클동영상,자바교육,자바학원,SQL교육, SQL학원

 오라클,PL/SQL,DBMS_SQL,동적SQL실습  테이블 생성, 멀티행 입력,BIND_ARRAY, EXECUTE, 오라클교육, 오라클학원, 오라클동영상,자바교육,자바학원,SQL교육, SQL학원


http://ojc.asia/bbs/board.php?bo_table=LecSQLnPlSql&wr_id=730 


오라클,PL/SQL,DBMS_SQL,동적SQL실습 테이블 생성, 멀티행 입력,BIND_ARRAY, EXECUTE, 오라클교육, 오라클학

오라클,PL/SQL,DBMS_SQL,동적SQL실습 테이블 생성, 멀티행 입력,BIND_ARRAY, EXECUTE, 오라클교육, 오라클학원, 오라클동영상,자바교육,자바학원,SQL교육, SQL학원오라클 PL/SQLDBMS_SQL동적SQL실습테이블 생성,

ojc.asia

https://www.youtube.com/watch?v=XbRQfXxbyng&list=PLxU-iZCqT52CfP98Y4gCDKIm52tKvgy36&index=42 


https://www.youtube.com/watch?v=XbRQfXxbyng&list=PLxU-iZCqT52CfP98Y4gCDKIm52tKvgy36&index=42 


https://www.youtube.com/watch?v=tO4rkJAC7FM&list=PLxU-iZCqT52CfP98Y4gCDKIm52tKvgy36&index=40 


DBMS_SQL

동적SQL실습

테이블 생성, 멀티행 입력


실습





DBMS_SQL을 이용하여 DDL문(CREATE, DROP)을 실행하고 생성된 테이블에 5개의 행을 오라클의 TABLE TYPE(배열)에 데이터를 넣은 후 멀티 행을 바인딩 하여 INSERT를 한번에 실행(EXECUTE)하는 예제를 실습하면서 DBMS_SQL 패키지 사용법에 대해 이해합니다.

https://www.youtube.com/watch?v=oR_UKxk_HO4&list=PLxU-iZCqT52CfP98Y4gCDKIm52tKvgy36&index=39

[실습1 : DBMS_SQL 패키지를 이용하여 테이블 생성 및 멀티행 바인딩 후 한번에 입력 실습]


CREATE OR REPLACE PROCEDURE CREATE_INSERT_TEST

AS

    V_CURSOR        NUMBER := DBMS_SQL.OPEN_CURSOR();

    V_CNT           NUMBER;    

    V_ID_ARR        DBMS_SQL.NUMBER_TABLE;

    V_NAME_ARR      DBMS_SQL.VARCHAR2_TABLE;    

    V_SQL           VARCHAR2(200);

    V_AFFECTED_ROWS NUMBER;

BEGIN    

    -- TEST 테이블이 생성되어 있는지 딕셔너리 뷰에서 확인

    SELECT COUNT(*) INTO V_CNT FROM USER_TABLES WHERE TABLE_NAME = 'TEST';

    -- 이미 생성되어 있다면 삭제 후 생성

    IF V_CNT > 0 THEN

       DBMS_SQL.PARSE(V_CURSOR, 'drop table test', DBMS_SQL.NATIVE);

       DBMS_SQL.PARSE(V_CURSOR, 'create table test ( id number, name varchar2(20)) ', DBMS_SQL.NATIVE);

       

       DBMS_OUTPUT.PUT_LINE('##### 삭제 후 생성');

    -- 생성되어 있지 않은 경우 그냥 생성

    ELSE

       DBMS_SQL.PARSE(V_CURSOR, 'create table test ( id number, name varchar2(20)) ', DBMS_SQL.NATIVE);

       DBMS_OUTPUT.PUT_LINE('##### 생성');

    END IF;   

    

    -- 5건 데이터 입력 위해 배열에 데이터 생성

    FOR i IN 1..5 LOOP

        V_ID_ARR(i) := i;

        V_NAME_ARR(i) := i || '길동';

    END LOOP;

    

    -- SQL문장을 변수에 담기

    V_SQL := 'insert into test (id, name) values (:id, :name)';

    -- SQL구문 파싱

    DBMS_SQL.PARSE(V_CURSOR, V_SQL, DBMS_SQL.NATIVE);

    -- 바인드 변수 연결, 한건씩 연결시 BIND_VARIABLE 사용

    DBMS_SQL.BIND_ARRAY(V_CURSOR, 'id', V_ID_ARR);

    DBMS_SQL.BIND_ARRAY(V_CURSOR, 'name', V_NAME_ARR);

    -- SQL실행, 한번에 5건이 입력됨

    V_AFFECTED_ROWS := DBMS_SQL.EXECUTE(V_CURSOR);

    -- 입력건수 츨력

    DBMS_OUTPUT.PUT_LINE('INSERT 건수 : ' || V_AFFECTED_ROWS);

    

    DBMS_SQL.CLOSE_CURSOR(V_CURSOR);

EXCEPTION

   WHEN OTHERS THEN

      DBMS_OUTPUT.PUT_LINE(SQLERRM);

    IF DBMS_SQL.IS_OPEN(V_CURSOR) THEN

       DBMS_SQL.CLOSE_CURSOR(V_CURSOR);

    END IF;

END;


exec CREATE_INSERT_TEST;

select * from test;






#오라클,#PLSQL,#DBMS_SQL,#동적SQL,#BIND_ARRAY, #오라클교육, #오라클학원, #오라클동영상,#자바교육,#자바학원,#SQL교육, #SQL학원,오라클,PLSQL,DBMS_SQL,동적SQL,BIND_ARRAY, 오라클교육, 오라클학원, 오라클동영상,자바교육,자바학원,SQL교육, SQL학원

스프링부트, Spring JDBC, MySQL, 모델, Persistence Layer, Service Layer, 자바학원, JAVA학원, 스프링학원, Spring학원

 

스프링부트, Spring JDBC, MySQL, 모델,  Persistence Layer, Service Layer, 자바학원, JAVA학원, 스프링학원, Spring학원


https://www.youtube.com/watch?v=K5R8FOYo34I&list=PLxU-iZCqT52Bihgf3v1bg5xEYeCwFQ_Zz&index=9 


https://www.youtube.com/watch?v=jDhjfRRbB9M&list=PLxU-iZCqT52Bihgf3v1bg5xEYeCwFQ_Zz&index=10 

http://ojc.asia/bbs/board.php?bo_table=LecSpring&wr_id=901 


스프링부트, Spring JDBC, MySQL, 모델, Persistence Layer, Service Layer

스프링부트, Spring JDBC, MySQL, 모델, Persistence Layer, Service Layer1.2.2. Spring JDBC현대의 대부분의 비즈니스 프로그램은 데이터베이스와 대화해야 합니다. 따라서 데이터베이스 처리 로직은 애플리케이

ojc.asia


1.2.2. Spring JDBC 

현대의 대부분의 비즈니스 프로그램은 데이터베이스와 대화해야 합니다. 따라서 데이터베이스 처리 로직은 애플리케이션의 핵심기능이라 할 수 있습니다.
먼저 데이터베이스 처리기술로 Spring JDBC를 살펴보겠습니다.
Spring JDBC는 자바표준 데이터베이스 처리기술인 JDBC를 개발자가 직접 사용할 경우 처리해야 하는 반복적인 작업을 스프링이 대신 처리해 주는 기술로 개발자를 지루함의 어둠으로부터 꺼내주는 유용한 기술입니다.


직원정보를 갖고 있는 테이블에 질의해서 데이터를 구한 다음 그 결과를 브라우저에게 전달하는 기능을 추가하겠습니다.


     새 프로젝트 생성

File > New > Spring Starter Project >

프로젝트 명: chapter1-2 > Next >

디펜던시 선택: Web, JDBC, MySQL > Finish



디펜던시
용도
Web
웹 서비스를 구축하기 위해 사용한다. 
스프링 핵심 모듈이 대부분 포함되어 있다.
JDBC
Spring JDBC 기술을 사용하기 위해 필요하다.
MySQL
MySQL 계열에 MariaDB와 연동하기 위한 연결 드라이버이다.


    프로젝트 환경설정

데이터베이스 연결정보를 환경설정 파일에 추가합니다.

application.properties

# DATASOURCE

spring.datasource.platform=mariadb

spring.datasource.sqlScriptEncoding=UTF-8

spring.datasource.url=jdbc:mysql://localhost:3306/testdb?createDatabaseIfNotExist=true

spring.datasource.username=root

spring.datasource.password=1111

spring.datasource.driver-class-name=com.mysql.jdbc.Driver


spring.datasource.platform 설정은 필수는 아니지만 스프링 부트에서 SQL의 DDL과 DML을 자동생성 하기위한schema-${platform}.sql, data-${platform}.sql 파일들을 사용할 수 있도록 해주기 때문에 여러 데이터베이스를 사용하는 개발 환경인 경우 설정해 놓으면 편리합니다.



     테스트 DB 생성

Maria DB를 설치하면 자동으로 test라는 DB는 존재하지만 testdb라는 DB는 없습니다. 테스트 DB는 "부록 3. HeidiSQL"을 참고하여 데이터베이스에 직접 접속하여 미리 생성해 놓아도 되고, 설정에서 "createDatabaseIfNotExist=true"라고 추가해 놓고 연결시도 시 생성하면서 사용하는 것도 가능합니다.


테스트 테이블 및 테스트 데이터를 입력해 놓기 위해서 application.properties 파일이 위치해 있는 src/main/resources 폴더에 다음 파일들을 생성합니다.


"부록 7.3.4"를 참조하여 파일 내용을 작성합니다.


schema.sql

data.sql


스프링 부트는 기동 시 위 파일들을 발견하면 schema.sql 파일의 DDL쿼리를 실행하고 다음으로 data.sql의 DML쿼리를 수행합니다.

스캐폴딩

프로젝트의 구조를 스캐폴딩(Scaffolding)이라고 부릅니다. 다음 그림을 보고 패키지 및 폴더를 생성합니다. com.example.employee 패키지 밑으로 하부 패키지 및 클래스를 생성하세요.



     모델 클래스

Value Object 역할을 수행할 모델 클래스를 작성합니다.

Emp.java

package com.example.employee.model;


public class Emp {

private int empno;

private String ename;

private String job;


public Emp() {}

public Emp(int empno, String ename, String job) {

this.empno = empno;

this.ename = ename;

this.job = job;

}

// getter, setter 생략

}


모델 클래스는 데이터베이스의 테이블과 1:1 대응되는 관계입니다. 테이블 내 한 줄의 데이터들을 객체에서 취급하기 위한 일종의 Value Object입니다. 때때로 취급하는 데이터의 개수가 다른 경우 별도의 DTO 클래스를 추가로 사용하기도 합니다. 


자바빈 규약에 따라 클래스의 필드변수는 private 접근제어자를 두고 getter, setter 메소드를 제공하는 형태로 작성합니다. 이러한 클래스를 계속 만들다 보면 단순하고 반복적인 작업을 계속하고 있다고 생각하게 됩니다. 이 부분에서 Lombok이 제공하는 기술을 사용하면 개발자는 필드변수만 선언하고 생성자, getter, setter 메소드를 만드는 작업은 롬복이 대신 처리하게 할 수 있습니다. 자세한 사용법은 "부록 4. Lombok"을 참고하세요.



     Persistence Layer

데이터베이스와 대화하는 로직을 취급하는 클래스를 작성합니다.

EmpDao.java

package com.example.employee.repository;


import java.util.List;

import com.example.employee.model.Emp;


public interface EmpDao {

public List<Emp> select();

}


경험으로 데이터베이스 처리 로직은 자주 변경된다는 것을 알고 있기에 일반적으로 DAO 구현 클래스를 만들기 전에 인터페이스를 작성합니다.


EmpDaoImpl.java

package com.example.employee.repository;


import java.util.List;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.jdbc.core.JdbcTemplate;

import org.springframework.jdbc.core.RowMapper;

import org.springframework.stereotype.Repository;

import com.example.employee.model.Emp;


@Repository

public class EmpDaoImpl implements EmpDao {

private JdbcTemplate jdbcTemplate;


@Autowired

public void setDataSource(DataSource dataSource){

jdbcTemplate = new JdbcTemplate(dataSource);

}


private RowMapper<Emp> rowMapper = (rs, idx)->{

Emp e = new Emp();

e.setEmpno(rs.getInt("empno"));

e.setEname(rs.getString("ename"));

e.setJob(rs.getString("job"));

return e;

};


@Override

public List<Emp> select() {

String sql = "select empno, ename, job from emp order by empno asc";

return jdbcTemplate.query(sql, rowMapper);

}

}


Spring JDBC 기술의 핵심은 반복적이고 뻔한 작업은 스프링이 대신 처리해 준다는 것입니다. 따라서 개발자는 상황에 따라 변하는 부분인 SQL쿼리 작성과 질의결과 처리 부분만 작업합니다. 


프로젝트 자바 버전이 1.8이므로 테이블 한 행의 데이터를 모델 객체에 옮겨 담는 바인딩로직을 정의하는 RowMapper 객체는 람다표현식을 사용하여 코드를 줄일 수 있습니다.



     Service Layer

EmpService.java

package com.example.employee.service;


import java.util.List;

import com.example.employee.model.Emp;


public interface EmpService {

public List<Emp> select();

}


여기서는 간단하게 하나의 메소드만 만들어 보겠습니다. 다른 메소드들은 하나씩 추가해 가시면서 살펴보시기 바랍니다.

EmpServiceImpl.java

package com.example.employee.service;


import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import com.example.employee.model.Emp;

import com.example.employee.repository.EmpDao;


@Service

public class EmpServiceImpl implements EmpService {

@Autowired

private EmpDao empDao;


@Override

public List<Emp> select() {

return empDao.select();

}

}


서비스 레이어의 존재 이유를 현재까지 작성한 코드만을 보고 생각해 내기 어렵지만 실제로 서비스를 구축하게 되면 자연스럽게 여러 비즈니스 로직이 필요하게 되고 그에 따라 서비스 레이어에 여러 로직이 추가됩니다. 전자정부 표준프레임워크에서도 퍼시스턴스 레이어와 서비스 레이어에는 항상 인터페이스를 두고 개발하기를 권고하고 있습니다. 이는 많은 개발자들이 수많은 프로젝트를 수행하면서 인터페이스를 두고 개발하는 것이 좋다는 결론에 동의한 결과라고 볼 수 있습니다.


일반적으로 트랜잭션은 서비스 클래스에 어노테이션으로 설정합니다. 그래야 비즈니스 로직에 따른 여러 쿼리들을 하나의 단위로 처리할 수 있기 때문입니다. 스프링 부트로 프로젝트를 만들고 디펜던시로 JDBC나 JPA를 추가하면 트랜잭션 객체가 빈으로 등록되어 있어서 @Transactional 어노테이션을 서비스 클래스에 추가하기만 하면 클래스 내 모든 메소드에 트랜잭션이 적용됩니다. 



     Presentation Layer

프리젠테이션 레이어의 임무는 받은 데이터를 예쁘게 만들어 클라이언트에게 전달하는 것입니다.

EmpController.java

package com.example.employee.controller;


import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.RestController;

import com.example.employee.service.EmpService;


@RestController

public class EmpRestController {

@Autowired

private EmpService empService;


@GetMapping("/emps")

public Object getEmps(){

return empService.select();

}

}


@GetMapping 어노테이션은 @RequestMapping(method={GET}) 어노테이션과 같은 의미를 갖는 편의성 어노테이션입니다. empService.select 메소드의 호출결과는 List<Emp> 객체입니다. 스프링은 RestController 클래스안에 메소드가 객체를 리턴하면 Jackson 라이브러리를 사용하여 JSON 문자열로 변경하고 그 결과를 클라이언트에게 전달합니다.


spring-boot-starter-web 디펜던시를 설정하면 jackson 라이브러리가 추가됩니다.



    테스트

http://localhost:8080/emps 주소로 서버에 접속합니다. 총 14건의 Emp 객체가 JSON 포맷의 문자열로 표시됩니다. 참고로 사용하고 있는 테스트 데이터는 오라클 데이터베이스를 설치하면 자동으로 추가되는 SCOTT 계정의 테스트 데이터를 사용하고 있습니다. 


다음 그림은 지면을 아끼기 위해서 상위 2건만 표시하고 있습니다.



     정리

서비스 레이어인 EmpService.java, EmpServiceImpl.java는 비즈니스 로직이 없고 미래에도 없을 거라고 판단된다면 작성하지 않아도 됩니다. 그렇게 본다면 Spring JDBC 기술을 사용할 때 개발자가 처리해야 하는 업무와 순서는 다음과 같습니다.


  • pom.xml

프로젝트에서 사용하는 디펜던시를 설정한다.

  • application.properties

데이터베이스 연결정보를 설정한다.

  • Emp.java 

테이블의 1 Row를 자바 객체의 1 Object로 취급하는 용도의 모델 클래스를 만든다.

  • EmpDao.java, EmpDaoImpl.java

데이터베이스 처리로직을 갖고 있는 DAO 클래스를 작성한다.

  • EmpRestController.java

사용자의 URL 요청을 받아서 결과를 돌려주는 기능을 수행하는 컨트롤러 클래스를 생성한다. 필요하다면 JSP를 별도로 사용하여 최종 결과로 HTML을 클라이언트에 전달할 수 있다.


여러 개의 파일을 역할에 따라 체계적으로 만든 후 연동해서 처리합니다. 사실 대부분의 작업은 미래를 위한 일종의 투자였습니다. 로직이 추가되거나 변화될 것을 대비해서 미리 예비 작업을 수행했다고 볼 수 있습니다. 


데이터베이스와 대화하는 로직을 갖고 있는 EmpDaoImpl 클래스의 메소드를 살펴보면 코드는 두줄에 불과합니다. 이는 스프링이 반복적으로 사용되는 JDBC의 Connection. Statement, ResultSet 객체들을 대신 처리해 주기 때문에 가능합니다. 


더불어 스프링은 체크드 예외를 언체크드 예외로 전환해서 던져주기 때문에 의미없는 try 구문을 개발자가 매번 코딩할 필요도 없습니다. 하지만 데이터베이스 로직만을 개발해서 다른 개발자에게 제공하는 경우에는 사용의 오용을 방지하기 위해서 try구문이 필요할 수도 있습니다. 이런 경우 여러 데이터베이스가 제 각각 던지는 예외를 일관된 예외로 변경해서 돌려 주는 스프링의 예외전환 서비스의 혜택을 누릴 수 있습니다.


#스프링부트, #스프링JDBC, #SpringJDBC, #스프링교육, #스프링동영상, #자바동영상, #자바교육, #스프링학원, #자바학원, ​스프링부트, 스프링JDBC, SpringJDBC, 스프링교육, 스프링동영상, 자바동영상, 자바교육, 스프링학원, 자바학원, ​



(C#교육동영상)C# ADO.NET 실습 ODP.NET/ODAC 설치 오라클 함수 호출 실습, C#학원, WPF학원, 닷넷학원, 자바학원

  (C#교육동영상)C# ADO.NET 실습  ODP.NET/ODAC 설치  오라클 함수 호출 실습, C#학원, WPF학원, 닷넷학원, 자바학원 https://www.youtube.com/watch?v=qIPU85yAlzc&list=PLxU-i...