Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

spring.jpa.hibernate.ddl-auto 옵션

  • none DataBase구조 : 테이블 구조 변경에 관여하지 않지않기때문에, DB 모델과 Code모델을 스키마와 JPA 모델을 맞추어놓아야합니다.
  • update: JPA에서 정의한 데이터모델과, 실제   데이터베이스의 모델에 스키마 변경이 있을때 반영됩니다. 

  • create: 매번 데이터베이스를 테이블을 생성하지만, 어플리케이션이 닫힐때 드롭하지 않습니다.

  • create-drop: 매번 데이터베이스를 테이블을 생성하고, 세션이 닫힐때 자동으로 데이터베이스를 테이블을 드롭합니다.


Data Model(Entity) 생성

...

  • 헝가리 표기안법을 따릅니다. ( 첫글자가 대문자) 만약 Class명이 SampleTable 이라고 하면 실제 테이블명인 sample_table로 변환되게 됩니다.
  • 컬럼명은 카멜 표기법을 따릅니다. ex> sampleName 
  • 이미 존재하는 테이블및 컬럼을 참조하여 규칙이 다를시 @Table(name=”SAMPLE_TABLE”) @Column(name = “COLUMN_NAME”,nullable=false) 어노테이션을 통해 해결가능


CRUD 저장소생성

...

JPA에서는 CrudRepository를 이용하여 조금더 객체 지향접근방식을 통해 Database를 제어할수가 있습니다.

User 란 User란 테이블을 제어하는 객체를 정의하기 위해서, 여기서는 UserRepository 라고 정의를 하였습니다.

...

JPA를 활용했을때 장점은, 일괄적인 객체접근을 통해 데이터모델을 핸들링 할수가 있다란 것이며

일반적으로 소스와 통합이 되기때문에  SP이 SP가 필요없이 형상관리가 될수 있다란것이며  

JPA의 장점이긴하지만, 모든곳에 적용되기에는 한계가 있습니다.

데이터 모델이 고정적이지 않고 복잡한 SQL문 혹은 다수개의 조인이 사용이 되는 데이터 추출에서는 권장되지 않습니다추출과 같은 프로세스에서는

그냥 네이티브한 SQL 사용이 더 적합할수도 있습니다.


JPA Relation

일반적으로 DB의 테이블은 하나의 테이블에 모든 정보를 포함하지 않고, 데이터의 효율적인 관리를 위해서 몇개의 테이블구조로

나누게 관계를 형성하게 됩니다.  이렇게 구조적으로 나뉜 테이블을 맵핑을 하여 하나의 테이블정보인것처럼 처리를 하려면

정보를 머지를 하려면  SQL문에서는 JOIN문으로 해결하며, JOIN을 통해 테이블을 지배해야합니다.

JPA 객체처리모델에서는 SQL문의 JOIN문에서 해방을 하여 JOIN문을 직접적으로 사용하지 않고, 동일한 효과를 내려고 합니다.

그 목적을 달성하기위해 데이터베이스와 객체지향의 몇가지 차이점을 알아야합니다.

...

Code Block
languagejava
themeEmacs
class User{
	int id;
	string name;
	string email;
}


class ClickLog{
	int clickid;
	User user;  //데이터베이스에서는 userid가 저장됨
	string clickurl;	
}


  • 프로그래밍모델에서 객체는 일반적으로 상속또는 포함관계를 통해 단방향 접근이 허용이 됩니다일반적입니다.. ( ClickLog→ User )
  • 데이터 베이스는 Join문을 통해 양방향 접근이 가능합니다연관관계와는 별개로,  양방향 접근에 자유롭습니다. ( User ↔ ClickLog )
  • 프로그래밍 모델에서는 상속의 개념이 있지만, 데이터베이스 에서는 존재하지 않습니다. 존재하여 다양한 객체를 포함할수가있습니다. 데이터베이스 에서는 상속개념이 없으며 리스트와같은 데이터Type을 포함할수 없습니다.
  • 데이터베이스에서는 상속의 개념을, 외래키를 통해 관계형성을 하며 논리적인 관계를 형성할수가 있습니다.


이와같은 차이를 극복하고, 데이터베이스의 Table을 객체지향적 이와같은 차이를 극복하고, 데이터베이스의 Table을 객체지향적 인 모델로 변경을 하려면 JPA에서 지원하는

관계(Relation)을 형성(Join)하는 몇가지 키워드의 의미를 알아야합니다.

...

Code Block
languagejava
themeEmacs
titletest
collapsetrue
@Autowired
private GroupRepository groupRepository;


@Autowired
private UserRepository userRepository;

GroupInfo newGroup = new GroupInfo();
newGroup.setName("학생");
groupRepository.save(newGroup);

// 사용자 생성
User addUser = new User();
addUser.setName("minsu");
addUser.setEmail("test@x.com");
addUser.setGroupInfo(newGroup);        
        
userRepository.save(addUser);
 
//* 
사용자 조회, select * from user join group_info 와 동일한조회효과를 누릴수 있습니다.
전통적인 처리 방법은 Insert쿼리를 실행하고 다시조회쿼리를 실행하고,그 데이터셋의 결과를 어플리케이션에 가지고와서
 과 동일한 효과로, 분리된 테이블에서 그룹명을 가지고 온다.
Iterable<User> userList = userRepository.findAll();      
userList.forEach(item->System.out.println( String.format("Name:%s  GroupName:%s", item.getName(),item.getGroupInfo().getName() )  ));

전통적인 처리 방법은 Insert쿼리를 실행하고 다시조회쿼리를 실행하고,그 데이터셋의 결과를 어플리케이션에 가지고와서
사용하기 과정까지 각각 다른 처리코드와 변환과정이 필요했을것입니다.( 테이블을 쿼리로 설계 <-> SQL <-> DataSet <-> Object <-> Json )
Json의 뷰단의 데이터가 하나만 바뀌어도 최대 5가지 수정 포인트에서 코드 수정이 이루어 졌을것입니다.


JPA를 통한 데이터모델링 정의및

...

 데이터제어가 다소 익숙하지않고 SQL문의 자유롭고 복잡한
표현을 모두 표현하기에 어려울수도 있습니다. 현재로서는 일괄적인 단일지점( 객체지향 정의)에서
모두 가능하다란것정도 이해를 해두고 넘어갑시다.


OneToMany

테이블구조는 변함이 없으며 접근 방식을 ManytoOne에서 OneToMany로 변경을 하여 객체지향접근방식으로

...

JPA에서의 목적은, 기존 SQL에서 처리하는 방식을 객체지향적으로 변경하는것입니다.

그리고 중요한것은 기존 데이터 모델의 테이블의 관계(외래키관계)를 그대로 유지하는것입니다.

Join에서 해방되고, 외래키 설정같은것을 신경쓸필요가 없으나...

우리는 아래코드가 외래키도 설정도 실제로하고 Join명령을 통해 FindByname이 작동이 된다란

없어보이나

아래코드가 외래키 설정도 되고, Join명령을 통해 FindByname이 작동이 된다란

사실을 알고 있어야합니다. 

즉 각종 Join(Inner,Left,Right....)에 대응하는 JPA Relation 키워드기능을  잘 파악해둬야합니다.

SQL Join의 자유도만큼 JPA가 표현하지 못할수도 있습니다.사실은 알고 있어야합니다. 


Code Block
languagejava
themeEmacs
titleGroupInfo에 1:N 포함관계처리 추가
collapsetrue
@Entity
public class GroupInfo {	  
  @OneToMany(mappedBy = "groupInfo", cascade = {CascadeType.PERSIST},fetch=FetchType.EAGER)
  private Set<User> users;

	@Override
    public String toString() {
        String result = String.format(
                "GroupInfo[id=%d, name='%s']%n",
                id, name);        
        if (users != null) {        	        	
            for(User user : users) {
                result += String.format(
                        "User[id=%d, name='%s']%n",
                        user.getId(), user.getName());
            }
        }
        return result;
    }
}


public interface GroupRepository extends CrudRepository<GroupInfo, Long> {
	public GroupInfo findByName(String name);	
}

...

데이터를 넣을 일은 없을것이나, Insert처리 조회처리를 일괄적이고 효과적인 방법으로 할수 있다란 

예일뿐입니다.


Paging 처리



Native SQL처리

JPA에서 Native SQL문을 통해, 데이터를 제어하는것은 권장되지 않습니다. 이러한 코드가 늘어나면 JPA 사용이유가 없어집니다.

하지만, 어떠한 상황에서는 Native SQL문을 사용해야하는 케이스가 유리할수 있으며 Repository에서 이러한 SQL문을 인터페이스화 할수 있는 기능을 제공해줍니다.



Info

다른 진영(.net) 에서도 JPA와 유사하게 데이터를 제어하고 있습니다.

Entity Framework

https://docs.microsoft.com/en-us/ef/core/

...