Versions Compared

Key

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

RDB를 조작하는 언어인 SQL문을 JPA와 연관하여 SQL문을 함께 정리를하였습니다.

일반적인 SQL문이 JPA에서는 어떻게 표현이 되는지? 샘플화 하였습니다.


Code Link : http://git.webnori.com/projects/WEBF/repos/spring_jpa/browse/src/test/java/com/example/demo/jpa/JpaBasic.java

Expand
title목차 펼치기

Table of Contents

...

Expand
title샘플데이터준비

주소 테이블 생성

Select 구문을 익히기전에 JPA를 통해 테이블을 생성하고 샘플 데이터를 입력하겠습니다.


 어플리케이션에서는 데이터모델뿐 아니라 JSON유틸리티/리퀘스트유틸/라우터처리 등

여러가지 성격이 다른 클래스를 다루게 됩니다. 여기서는 data모듈하위에 데이터베이스에

관련된 테이블의 정의를 집합하도록 하겠습니다. 


JPA-주소테이블

Code Block
languagejava
themeEmacs
@Entity
public class Address {
	@Id
    @GeneratedValue
    @Column(name = "ADDRESS_ID")
    private Integer id;
	
	private String name;	
	private String phoneNbr;	
	private String address;	
	private String sex;	
	private int	   age;	
	//getter,setter 생략	
}


SQL-주소테이블

Code Block
languagesql
themeEmacs
CREATE TABLE `address` (
  `address_id` int(11) NOT NULL AUTO_INCREMENT,
  `address` varchar(255) DEFAULT NULL,
  `age` int(11) NOT NULL,
  `name` varchar(255) DEFAULT NULL,
  `phone_nbr` varchar(255) DEFAULT NULL,
  `sex` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`address_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8


JPA-주소 데이터 입력

Code Block
languagejava
themeEmacs
package com.example.demo.data;

import org.springframework.data.repository.CrudRepository;

public interface AddressRepo extends CrudRepository<Address, Long>{

}
//사용예
	@Autowired
	private AddressRepo addressRepo;

	public void InsertAddressData(){		
		String[] addArray = {
				"서울","대구","부산","창원","마산","제주"				
		};
		
		for(int i=0; i<100;i++) {
			
			double random = Math.random();
		    double x = random*100;
		    int y = (int)x + 1; //Add 1 to change the range to 1 - 100 instead of 0 - 99
		    
			Address address = new Address();
			address.setAge(y);
			address.setAddress( addArray[i%6] );
			address.setPhoneNbr(String.format("010-3333-1%04d", i));
			
			if( i%2 == 0 ) {
				address.setName(String.format("민수%d", i+1));
				address.setSex("남");				
			}else {
				address.setName(String.format("영희%d", i+1));
				address.setSex("여");				
			}			
			addressRepo.save(address);			
		}		
	}

JPA에서는, SQL문을 직접사용하여 Insert를 하지 않습니다. JPA로 작성된 데이터모델에

Insert를 하기위해서는, CrudRepository 인터페이스를 작성후, 배열을 조작하고

관련 함수를 사용하는것만으로 실제 데이터베이스 테이블에 데이터를 추가하는것과  동일한 효과를 낼수 있습니다.


Info


JPA의 Crud객체는, 데이터 Insert를 효율적으로 수행하기위해

개별 기본 엔티티 추가 / 리스트형태의 엔티티추가 두개의 저장 인터페이스를 지원합니다.

SQL-주소 데이터 입력


2019.11 Update

여러 객체를 한꺼번에 동시에 insert하는것은 ORM에서 일반적으로 네이티브 쿼리를 사용하는것보다 훨씬 느리게 작동을 합니다. 

대량 Insert는 배치처리기와 연관이 있으며 이것에대한 성능처리는 다른 방법으로 풀어야합니다. 


실시간 세미 배치전략을 어떻게 잘 설계할지 유연한 구현을 할수 있다고 하면 ORM이든 네이티브이던 성능에대한 간격은 많이 줄어든 상태입니다.

참고 자료:


ORM이냐 네이티브냐의 문제가 아니라....

  • 유입되는 대량 메시지에따라 타임단위/개수단위로 통제하여 벌크인서트를 하는방법 ( with FSM )
  • 데이터 베이스의 성능을 확인하여, 유입량을 유연하게 통제할수 있는 방법 ( backpressure )

위 두가지 문제를 어떻게 해결할것인가에 초점을 두어야한다란 이야기입니다.


SQL-주소 데이터 입력

No Format
Hibernate: 
    /* insert com.example.demo.data.Address
        */ insert 
        into
No Format
Hibernate: 
    /* insert com.example.demo.data.Address
        */ insert 
        into
            address
            address
            (address, age, name, phone_nbr, sex) 
        values
            (?, ?, ?, ?, ?)

위와같은 SQL문을 실행하여 실제 데이터베이스에 입력을 하게 됩니다.

JPA를 활용하면 Hibernate 기능이 귀찮은 SQL문을 작성해준다라고 보면됩니다.


...

Code Block
languagejava
themeEmacs
title사용예
List<AddressStatistics> addressStaticByRegion = addressRepo.findRegionAvgage(10,49);
// 결과
//대구 51.40
//마산 57.20
//부산 54.13
//서울 66.75
//제주 54.69
//창원 58.12

Order BY

지금까지 SELECT구문의 몇가지 예제를 살펴보았습니다. 그런데 그 결과 레코드는 어떠한 순일까요?

그것은 딱히 정해진 규칙없이 DBMS에따라 다르게 작동이됩니다. 어떠한 규칙에(입력순서,빠르게처리되는순서) 의해 작동될수도 있지만

DBMS의 처리순서 규칙을 어렵게 알아내었다고 해도  상황에따라 달라질수도 있기때문에

...


Order BY

지금까지 SELECT구문의 몇가지 예제를 살펴보았습니다. 그런데 그 결과 레코드는 어떠한 순일까요?

그것은 딱히 정해진 규칙없이 DBMS에따라 다르게 작동이됩니다. 어떠한 규칙에(입력순서,빠르게처리되는순서) 의해 작동될수도 있지만

DBMS의 처리순서 규칙을 어렵게 알아내었다고 해도  상황에따라 달라질수도 있기때문에

순서를 보장받으려면 명시적으로 지정을 하여야 합니다. 

Order by을 사용안했을시, 암묵적인 Order처리가 어떻게 되냐? 를 두고 때로 갑론을박이 이루어지기도합니다.

고성능 암묵적인 순서보장을 위해 DBMS의 숨겨진 특성을 이용하고 마치 규칙적인 오더를 발견 할수도 있지만

제공되는 기능은 아닐뿐더러 언제 그 규칙이 깨질지 예측이 불가능하며 동일 DBMS라 할지라도 버젼에따라

그 규칙이 유지되리란 보장이 없는것은 명확한 사실입니다.  이러한 숨겨진 특성을 가지고

DBMS의 성능을 비교한다는것은 소모적인 논쟁이 될가능성이 높습니다


SQLJPA

select
*
from
Address
where
generatedAlias0.sex=:param0

order by

age asc,
address asc

public interface AddressRepo extends CrudRepository<Address, Long>{

List<Address> findBySex(String sex, Sort sort);

List<Address> findBySexOrderByAgeDesc(String sex);

...

사용예>

addressRepo.findBySex("남", new Sort(Sort.Direction.ASC, "age","address") );

– ASC : 오름차순 , DESC : 내림차순

...

No Format
JPAQuery query = new JPAQuery(em);
QMember = member = Qmember.member;
List<Member> members = 
	query.from(member)
	.where(member.username.eq("Kim"))
	.list(member);



관련 샘플코드:

...