Maven은 resources 하위의 모든 파일은 classpath로 들어간다.
component scan은 설정된 패키지의 하위 stereotype bean들을 스캔한다.
이때까지 했던 모든 것들은 다 관계형 데이터베이스
하지만 지금 내가 사용하고 있는 프로그래밍 언어는 Java이고 객체지향 프로그래밍 언어이다.
h2 데이터베이스 실행
java -jar h2/bin/h2-2.1.212.jar

| 구성요소 | 설명 | 역할 |
|---|---|---|
| Java Application | 자바 응용프로그램, 자바 웹 애플리케이션 서버(tomcat, weblogic 등) | 응용 프로그램 개발자, 웹 애플리케이션 서버 개발사 |
| JDBC API | 자바 응용프로그램에서 데이터베이스를 연결하고 데이터를 제어할 수 있도록 데이터베이스 연결 및 제어를 위한 인터페이스와 클래스들 | JavaSE 개발사(Sun microsystems, Oracle) |
| JDBC Driver Manager | 자바 응용프로그램이 사용하는 데이터베이스에 맞는 JDBC 드라이버를 찾아서 로드한다. | JavaSE 개발사(Sun microsystems, Oracle |
| JDBC Driver | 각 데이터베이스 개발사에서 만든 데이터베이스 드라이버 | 데이터베이스 개발사(Oracle, MySql, PostgreSql,.. |


| Action | Spring Framework | 개발자 |
|---|---|---|
| Define connection parameters | X | |
| Open the connection | X | |
| Specify the SQL statement | X | |
| Declare parameters and provide parameter values | X | |
| Set up the loop to iterate through the result (if any) | X | |
| Do the work for each iteration | X | |
| Process any exception | X | |
| Handle transactions | X | |
| Close the connection, the statement, and the resultset | X |
jpa는 구현체가 아니라 표준 스펙이다. 구현체는 Hibernate 등이 있다.
jpa는 자바 ORM 기술 표준이다.
servlet 스펙을 구현한 것이 tomcat이다.
Hibernate가 사실상 표준(defecto)이다.
기존에 SQL을 직접 작성한 것에서 데이터를 받는 클래스의 필드를 수정하면

트랜젝션은 작업의 안정성과 데이터의 무결성을 유지시키기 위해 다음의 4가지 성질을 가지고 있다.
public interface PlatformTransactionManager extends TransactionManager {
TransactionStatus getTransaction(TransactionDefinition definition) /*..*/;
void commit(TransactionStatus status) throws TransactionException;
void rollback(TransactionStatus status) throws TransactionException;
}
@Transaction
Transaction은 보통 service layer에서 묶는다.
jpa를 사용하기 위해서는 jpa dependency와 hibernate dependency가 필요하고 JpaConfig를 만들어서 @EnableJpaRepositories를 사용해야 한다.
내가 직접 쿼리 안 짜고 orm이 짜게 하는 것이 jpa이다.
jpa를 사용하기 위해서는 JpaConfig에 EntityManagerFactoryBean과 TransactionManager를 Bean으로 등록해줘야 한다.
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) {
LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
emf.setDataSource(dataSource);
emf.setPackagesToScan("com.nhnacademy.springjpa.entity");
emf.setJpaVendorAdapter(jpaVendorAdapters());
emf.setJpaProperties(jpaProperties());
return emf;
}
private JpaVendorAdapter jpaVendorAdapters() {
HibernateJpaVendorAdapter hibernateJpaVendorAdapter = new HibernateJpaVendorAdapter();
hibernateJpaVendorAdapter.setDatabase(Database.H2);
return hibernateJpaVendorAdapter;
}
private Properties jpaProperties() {
Properties jpaProperties = new Properties();
jpaProperties.setProperty("hibernate.show_sql", "true");
jpaProperties.setProperty("hibernate.format_sql", "true");
jpaProperties.setProperty("hibernate.use_sql_comments", "true");
jpaProperties.setProperty("hibernate.globally_quoted_identifiers", "true");
jpaProperties.setProperty("hibernate.temp.use_jdbc_metadata_defaults", "false");
return jpaProperties;
}
@Bean
public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory);
return transactionManager;
}
hibernate.show_sql=true
hibernate.format_sql=true
<logger name="org.hibernate.SQL" level="debug" additivity="false">
<appender-ref ref="console" />
</logger>
<logger name="org.hibernate.type.descriptor.sql.BasicBinder" level="trace" additivity="false">
<appender-ref ref="console" />
</logger>
Entity와 database table이 매핑되는 것이 entity mapping이다.
Entity는 database table과 매핑되는 자바 객체이다.
db table 이름과 Entity 객체 이름이 다를 경우 @Table로 어떤 테이블인지 지정을 해줘야 한다.
table의 column은 자바 class의 field로 매핑이 된다.
@Entity
@Table(name = "Members")
public class Member {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@Column(name = "created_dt")
private LocalDateTime createdDate;
}
java8 이전 버전에는 날짜 타입을 맵핑하는 어노테이션이 존재함
public enum TemporalType {
DATE,
TIME,
TIMESTAMP
}
TABLE 전략: 이 전략은 채번 테이블을 사용하여 기본 키를 생성하는 방법입니다. 채번 테이블은 데이터베이스에 미리 생성된 특별한 테이블로, 기본 키 값들이 저장됩니다. 어플리케이션은 이 테이블에서 기본 키 값을 가져와 사용하고, 가져온 값은 테이블에서 삭제되거나 마킹됩니다. 이 방법은 여러 어플리케이션이 동시에 사용될 때 충돌을 방지할 수 있습니다.
SEQUENCE 전략: 시퀀스 전략은 데이터베이스에 시퀀스라는 객체를 사용하여 기본 키를 생성하는 방법입니다. 시퀀스는 일련번호를 자동으로 생성해주는 데이터베이스 객체로, 각 기본 키 값은 시퀀스에서 생성됩니다. 이 방법은 다양한 데이터베이스에서 지원되며, 성능면에서 우수합니다.
IDENTITY 전략: 이 전략은 기본 키 생성을 데이터베이스에 위임하는 방법입니다. 대부분의 데이터베이스에서는 자동 증가(auto-increment) 혹은 identity 컬럼을 지원하며, 이를 사용하여 각 레코드가 삽입될 때마다 기본 키 값을 자동으로 생성합니다.
AUTO 전략: AUTO 전략은 선택한 데이터베이스 방언(dialect)에 따라 기본 키 맵핑 전략을 자동으로 선택하는 방법입니다. Hibernate에서는 해당 데이터베이스의 특성을 파악하여 가장 적합한 전략을 자동으로 선택합니다.
@Entity
@Table(name = "OrderItems")
@IdClass(OrderItem.Pk.class)
public class OrderItem {
@Id
@Column(name = "order_id")
private Long orderId;
@Id
@Column(name = "line_number")
private Integer lineNumber;
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
public static class Pk implements Serializable {
private Long orderId;
private Integer lineNumber;
}
}
@Entity
@Table(name = "OrderItems")
public class OrderItem {
@EmbeddedId
private Pk pk;
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
@Embeddable
public static class Pk implements Serializable {
@Column(name = "order_id")
private Long orderId;
@Column(name = "line_number")
private Integer lineNumber;
}
}
GMT : Greenwich mean time
GMT+09:00 여기서 뒤에 있는 시간이 offset이다.
@PersistenceContext

entityManager가 관리하는 entity가 db에 써지기 위해서는 flush() 메서드를 실행해 주어야 한다.