TIL_Java Spring the Modern Way_10

-·2021년 3월 22일
0

Java Spring the Modern Way

목록 보기
10/13

JPA, hibernate

JPA가 필요한 이유?????

간단한 쿼리는 직접 mapper를 이용해서 짜면 되지만
규모가 커지면? 테이블도 몇백개, 쿼리도 엄청 복잡해질것이다.

엔티티와 관계를 정의하면
쿼리를 짜는 작업은 JPA가 한다.

쿼리를 개발자가 짜는게 아니고 프레임워크가 짜는걸로 분담하는것이다.

우리는 정의만 하면된다.

JPA, hibernate 차이

맨처음 배웟을때는 JPA와 Hibernate가 뭔차이일까 했는데.

JPA는 ORM을 수행하는 표준이다.

Hibernate가 JPA를 구현시켜주는 구현체인것이다.

구현 예시

Hibernate에 역시 구현을 위한 많은 어노테이션들이 준비되어있다.

@Entity // 테이블이라는거 명시
//@Table 테이블 이름 매핑, 같으면 필요없음
@NamedQuery(name="find_all_persons", query = "select p from Person p") 	// JPQL
public class Person { 
	@Id // 기본키 설정
	@GeneratedValue // 시퀀스를 생성해서 알아서 값채워줌
	private int id;
	
	private String name;
	private String location;
	private Date birthDate;
	
	public Person() {

	}

	public Person(int id, String name, String location, Date birthDate) {
		super();
		this.id = id;
		this.name = name;
		this.location = location;
		this.birthDate = birthDate;
	}
	// id는 primary key그리고 시퀀스로 생성되니까 정의해줄 필요없음
	public Person(String name, String location, Date birthDate) {
		super();
		this.name = name;
		this.location = location;
		this.birthDate = birthDate;
	}
}

Repository

@Repository // 저장소라는걸 명시
@Transactional // 트랜젝션 관리
public class PersonJpaRepository {
	// 데이터베이스에 연결하기
    // JdbcTemplate말고 EntityManager이용 
	@PersistenceContext
	EntityManager entityManager;

	// JPQL
	public List<Person> findAll(){
		TypedQuery<Person> nameQuery = entityManager.createNamedQuery("find_all_persons", Person.class);
		return nameQuery.getResultList();
	}
	// JPA 구현
	public Person findById(int id){
		return entityManager.find(Person.class, id);
	}
	public Person update(Person person) {
		// id가 이미있으면 update, id가 없으면 insert
		return entityManager.merge(person);
	}
	public Person insert(Person person) {
		return entityManager.merge(person);
	}
	public void deleteById(int id) {
		Person person = findById(id);
		entityManager.remove(person);
	}
}

merge 부분 결과 로그

// merge insert - id로 select해서 없으니까 새로생성
Hibernate: select person0_.id as id1_0_0_, person0_.birth_date as birth_da2_0_0_, person0_.location as location3_0_0_, person0_.name as name4_0_0_ from person person0_ where person0_.id=?
Hibernate: call next value for hibernate_sequence
Hibernate: insert into person (birth_date, location, name, id) values (?, ?, ?, ?)

// merge update - id로 select해서 있으니까 update
Hibernate: select person0_.id as id1_0_0_, person0_.birth_date as birth_da2_0_0_, person0_.location as location3_0_0_, person0_.name as name4_0_0_ from person person0_ where person0_.id=?
Hibernate: update person set birth_date=?, location=?, name=? where id=?

더 향상된 버전 (JpaRepository for JPA)

// extends JpaRepository<관리할 repository, primary key>
public interface PersonSpringDataRepository 
	extends JpaRepository<Person, Integer>{

}

repository의 CRUD 도 정의해줄 필요가없다.! 기본적인건 이미 다 만들어져 있음

@Autowired
PersonSpringDataRepository repository;
...
logger.info("User id: {}", repository.findById(10001));
// save = merge
logger.info("Inserting 10004: {}", repository.save(new Person("Tara", "Berlin", new Date())));
logger.info("Update 10003: {}", repository.save(new Person(10003, "Pieter", "Utrecht", new Date())));
repository.deleteById(10002);
logger.info("All users: {}", repository.findAll());

이렇게 그냥 바로 사용가능

profile
거북이는 오늘도 걷는다

0개의 댓글