Java Persistence API
https://docs.oracle.com/javaee/6/tutorial/doc/bnbpz.html
Object Relational Mapping - 자바 객체 관계형 데이터 베이스 테이블 매핑
구현체 : 하이버네이트(Hibernate)
sql 작성 안하려는 노력(등록, 수정, 삭제는 자동화, select는 부분 자동화)
import jakarta.persistence.Entity; // javax -> jakarta
import jakarta.persistence.Id;
@Entity
public class Product {
@Id
package entity;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.Persistence;
//spring을 제외한 jpa 사용
public class Test {
public static void main(String[] args){
// EntityManagerFactory -> EntityManager
EntityManagerFactory emf = Persistence.createEntityManagerFactory("my-pu"); // unit name
EntityManager em = emf.createEntityManager();
em.getTransaction().begin(); // 1차 캐시 준비
// 작업 수행
em.getTransaction().commit();
em.close();
}
}
// 1건
{
Product p = new Product();
p.setId(1);
p.setName("Book");
em.persist(p); // 이 시점에 insert X - commit때 insert
}
// 여러 건
{
Product p2 = new Product();
p2.setId(2);
p2.setName("Phone");
Product p3 = new Product();
p3.setId(3);
p3.setName("Car");
// persis 순서대로 inser X
// 영속화 context가 flush() (commint()이 flush() 호출) 되는 시점에 결정(순서는 알 수 없지만 id 순으로 되는 거 같음)
em.persist(p3);
em.persist(p2);
}
public class MyPersistenceUnitInfo implements PersistenceUnitInfo
HikariCP 추가
@Override
public String getPersistenceUnitName() {
return "my-pu"; // 이름 맞게 설정
}
@Override
public String getPersistenceProviderClassName() {
return "org.hibernate.jpa.HibernatePersistenceProvider";
}
@Override
public PersistenceUnitTransactionType getTransactionType() {
return PersistenceUnitTransactionType.RESOURCE_LOCAL;
}
@Override
public DataSource getJtaDataSource() {
HikariDataSource dataSource = new HikariDataSource();
dataSource.setJdbcUrl("db 주소");
dataSource.setUsername("이름");
dataSource.setPassword("비번");
return dataSource;
}
@Override
public List<String> getManagedClassNames() {
return List.of("entity.Product");
}
EntityManagerFactory emf= new HibernatePersistenceProvider()
.createContainerEntityManagerFactory(new MyPersistenceUnitInfo(), new HashMap<>());
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
// TODO
em.getTransaction().commit();
em.close();
for(int i=1;i<=3;i++){
Product p = new Product();
p.setId(i);
p.setName("Phone"+i);
em.persist(p);
}
Product p = new Product();
p.setId(4);
p.setName("Watch");
em.persist(p); // p객체는 영속화 context에 담긴 상태 - entitymanager가 관리
p.setName("Glasses");
commit할때의 상태로 저장됨
@Entity
@Table(name = "emp")
public class Employee {
@Id
@Column(name = "emp_id")
table이랑 column명 달라도 적용 가능
// find
// table data -> 객체화 & 영속화
{
Employee e = em.find(Employee.class, 1);
System.out.println(e);
Employee e2 = em.find(Employee.class, 2);
System.out.println(e2); // 없는 값은 null 출력
}
// merge
// 객체가 테이블에 없으면 insert, 있는 객체면 update
{
// 없는 데이터
Employee e = new Employee();
e.setId(2);
e.setName("lee");
e.setAddress("gangju");
em.merge(e);
// 있는 데이터
Employee e2 = new Employee();
e2.setId(1);
e2.setName("hong");
e2.setAddress("busan");
em.merge(e2);
}
// detach
// 영속화 context에서 분리(em이 관리 x)
{
Employee e = em.find(Employee.class, 2);
System.out.println(e);
em.detach(e);
e.setAddress("jeju");
System.out.println(e); // 출력은 jeju로 되지만 실제 db에는 detach 전의 값을 가짐
}
// remove
{
Employee e = em.find(Employee.class, 2);
System.out.println(e);
em.remove(e);
Employee e2 = new Employee();
e2.setId(1);
em.remove(e2); // error(IllegalArgumentException:
// Removing a detached instance entity.Employee#1)
}
Map<String, String > props = new HashMap<>();
props.put("hibernate.hbm2ddl.auto","update"); // create(drop&create), update(없으면 create, 변하면 alter)
props.put("hibernate.show_sql","true"); // 수행되는 sql 출력
EntityManagerFactory emf= new HibernatePersistenceProvider()
.createContainerEntityManagerFactory(new MyPersistenceUnitInfo(), props);
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
// ddl option update(현재 엔티티와 동일한 테이블 존재) => 아무일 x
// 테이블 x => 테이블 생성
// 컬럼이 다름 => 컬럼 추가/삭제
em.getTransaction().commit();
em.close();
}
import entity.Book;
import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import jakarta.persistence.Persistence;
import jakarta.persistence.TypedQuery;
import java.util.List;
// select
// em.commit() 사용 x
// jpql - sql과 유사한 거
public class Test {
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("my-pu");
EntityManager em = emf.createEntityManager();
//typed query
{
String jpql = "select b from Book b"; // table이 아니라 entity
// Hibernate: select b1_0.bookid,b1_0.bookname,b1_0.price,b1_0.publisher from Book b1_0
TypedQuery<Book> query = em.createQuery(jpql, Book.class);
List<Book> bookList = query.getResultList();
for(Book book : bookList){
System.out.println(book);
}
}
em.close();
}
}
//typed query + parameter
{
String jpql = "select b from Book b where b.price > ?1";
TypedQuery<Book> query = em.createQuery(jpql, Book.class);
query.setParameter(1,15000);
List<Book> bookList = query.getResultList();
for(Book book : bookList){
System.out.println(book);
}
}
{
String jpql = "select b from Book b where b.price > :price";
TypedQuery<Book> query = em.createQuery(jpql, Book.class);
query.setParameter("price",15000);
List<Book> bookList = query.getResultList();
for(Book book : bookList){
System.out.println(book);
}
}