diff --git a/.gitignore b/.gitignore
index 2f43530..ee9c430 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,3 +15,130 @@ buildNumber.properties
.project
# JDT-specific (Eclipse Java Development Tools)
.classpath
+### Java template
+# Compiled class file
+*.class
+
+# Log file
+*.log
+
+# BlueJ files
+*.ctxt
+
+# Mobile Tools for Java (J2ME)
+.mtj.tmp/
+
+# Package Files #
+*.jar
+*.war
+*.nar
+*.ear
+*.zip
+*.tar.gz
+*.rar
+
+# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
+hs_err_pid*
+replay_pid*
+
+### Maven template
+target/
+pom.xml.tag
+pom.xml.releaseBackup
+pom.xml.versionsBackup
+pom.xml.next
+release.properties
+dependency-reduced-pom.xml
+buildNumber.properties
+.mvn/timing.properties
+# https://github.com/takari/maven-wrapper#usage-without-binary-jar
+.mvn/wrapper/maven-wrapper.jar
+
+# Eclipse m2e generated files
+# Eclipse Core
+.project
+# JDT-specific (Eclipse Java Development Tools)
+.classpath
+
+### JetBrains template
+# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
+# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
+
+# User-specific stuff
+.idea/**/workspace.xml
+.idea/**/tasks.xml
+.idea/**/usage.statistics.xml
+.idea/**/dictionaries
+.idea/**/shelf
+
+# AWS User-specific
+.idea/**/aws.xml
+
+# Generated files
+.idea/**/contentModel.xml
+
+# Sensitive or high-churn files
+.idea/**/dataSources/
+.idea/**/dataSources.ids
+.idea/**/dataSources.local.xml
+.idea/**/sqlDataSources.xml
+.idea/**/dynamic.xml
+.idea/**/uiDesigner.xml
+.idea/**/dbnavigator.xml
+
+# Gradle
+.idea/**/gradle.xml
+.idea/**/libraries
+
+.idea/*
+*.iml
+
+# Gradle and Maven with auto-import
+# When using Gradle or Maven with auto-import, you should exclude module files,
+# since they will be recreated, and may cause churn. Uncomment if using
+# auto-import.
+# .idea/artifacts
+# .idea/compiler.xml
+# .idea/jarRepositories.xml
+# .idea/modules.xml
+# .idea/*.iml
+# .idea/modules
+# *.iml
+# *.ipr
+
+# CMake
+cmake-build-*/
+
+# Mongo Explorer plugin
+.idea/**/mongoSettings.xml
+
+# File-based project format
+*.iws
+
+# IntelliJ
+out/
+
+# mpeltonen/sbt-idea plugin
+.idea_modules/
+
+# JIRA plugin
+atlassian-ide-plugin.xml
+
+# Cursive Clojure plugin
+.idea/replstate.xml
+
+# SonarLint plugin
+.idea/sonarlint/
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+com_crashlytics_export_strings.xml
+crashlytics.properties
+crashlytics-build.properties
+fabric.properties
+
+# Editor-based Rest Client
+.idea/httpRequests
+
+# Android studio 3.1+ serialized cache file
+.idea/caches/build_file_checksums.ser
+
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..8675a73
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,88 @@
+
+
+ 4.0.0
+
+ jpa-basic
+ ex1-hello-jpa
+ 1.0-SNAPSHOT
+
+
+
+ 17
+
+ UTF-8
+ UTF-8
+
+
+ 5.5.7.Final
+
+ 2.2.220
+ 2.0.6
+ 1.4.7
+
+
+
+
+ org.hibernate
+ hibernate-entitymanager
+ ${hibernate.version}
+
+
+
+ com.h2database
+ h2
+ ${h2db.version}
+
+
+ org.projectlombok
+ lombok
+ 1.18.28
+ provided
+
+
+
+ org.slf4j
+ slf4j-api
+ ${slf4j-version}
+
+
+ org.slf4j
+ jcl-over-slf4j
+ ${slf4j-version}
+ runtime
+
+
+ org.slf4j
+ slf4j-log4j12
+ ${slf4j-version}
+ runtime
+
+
+ ch.qos.logback
+ logback-classic
+ ${logback.version}
+
+
+ org.jetbrains
+ annotations
+ RELEASE
+ compile
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ 3.1
+
+ ${java.version}
+ ${java.version}
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/java/hellojpa/Jpa2.java b/src/main/java/hellojpa/Jpa2.java
new file mode 100644
index 0000000..4898227
--- /dev/null
+++ b/src/main/java/hellojpa/Jpa2.java
@@ -0,0 +1,85 @@
+package hellojpa;
+
+
+import hellojpa.model.Member;
+import lombok.extern.slf4j.Slf4j;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.EntityTransaction;
+import javax.persistence.Persistence;
+import java.util.List;
+
+@Slf4j
+public class Jpa2 {
+ public Jpa2(EntityManagerFactory emf) {
+ EntityManager em = emf.createEntityManager();
+ EntityTransaction tx = em.getTransaction();
+ tx.begin();
+ try{
+ // 추가
+// insertMember(em, tx);
+ // 조회
+// selectMember(em);
+ // 수정
+// updateMember(em, tx);
+
+ // 삭제
+// deleteMember(em, tx);
+
+ // JPQL
+ jpql(em);
+
+
+// tx.commit();
+ } catch (Exception e){
+ tx.rollback();
+ } finally {
+ em.close();
+ }
+ emf.close();
+ }
+
+ // JPQL
+ private void jpql(EntityManager em) {
+ List result = em.createQuery("select m from Member as m", Member.class)
+ .setFirstResult(5)
+ .setMaxResults(8)
+ .getResultList();
+
+ for (Member member : result) {
+ System.out.println("member.name = " + member.getName());
+ }
+ }
+
+ // 추가
+ private static void insertMember(EntityManager em, EntityTransaction tx) {
+ Member member = new Member();
+ member.setId(1L);
+ member.setName("HelloA");
+ em.persist(member);
+ tx.commit();
+ }
+
+ // 조회
+ private static void selectMember(EntityManager em) {
+ Member findMember = em.find(Member.class, 1L);
+ }
+
+ // 수정
+ private static void updateMember(EntityManager em, EntityTransaction tx) {
+ Member findMember = em.find(Member.class, 1L);
+ findMember.setName("HelloJPA");
+ tx.commit();
+ }
+
+ // 삭제
+ private static void deleteMember(EntityManager em, EntityTransaction tx) {
+ // 엔티티 조회, 영속 상태
+ Member memberA = em.find(Member.class, "memberA");
+ em.remove(memberA);
+ tx.commit();
+ }
+
+
+}
diff --git a/src/main/java/hellojpa/Jpa3.java b/src/main/java/hellojpa/Jpa3.java
new file mode 100644
index 0000000..9c08f8a
--- /dev/null
+++ b/src/main/java/hellojpa/Jpa3.java
@@ -0,0 +1,200 @@
+package hellojpa;
+
+
+import hellojpa.model.Member1;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.EntityTransaction;
+import java.util.List;
+
+public class Jpa3 {
+ public Jpa3(EntityManagerFactory emf) {
+ EntityManager em = emf.createEntityManager();
+ EntityTransaction tx = em.getTransaction();
+ tx.begin();
+ try{
+ // 엔티티 조회
+// persistSelectMember(em);
+ // 엔티티 등록
+// persistinsertMember(em, tx);
+ // 엔티티 삭제
+// deleteMember(em);
+ // flush
+// fulsh(em);
+ // 준영속
+// detach(em, tx);
+// detachedClear(em);
+// detachedClose(em, tx);
+
+ // 비영속 병합
+// TransientMerge(em, tx);
+
+
+ } catch (Exception e){
+ tx.rollback();
+ } finally {
+ em.close();
+ }
+ // 병합
+// detachedMerge(emf);
+ emf.close();
+ }
+
+ private void TransientMerge(EntityManager em, EntityTransaction tx) {
+ Member1 member = new Member1();
+ Member1 newMember = em.merge(member); // 비영속 병합
+ tx.commit();
+ }
+
+ // 엔티티 조회
+ private void persistSelectMember(EntityManager em) {
+ Member1 member = new Member1();
+ member.setId("member1");
+ member.setUserName("회원1");
+
+ // 1차 캐시에 저장됨
+ em.persist(member);
+
+ // 1차 캐시에서 조회
+ Member1 findMember = em.find(Member1.class, "member1");
+ System.out.println("findMember.id = " + findMember.getId());
+ }
+
+ // 엔티티 추가
+ private void persistinsertMember(EntityManager em, EntityTransaction tx) {
+
+ Member1 memberA = new Member1();
+ memberA.setId("memberA");
+ memberA.setUserName("회원1");
+ Member1 memberB = new Member1();
+ memberB.setId("member2");
+ memberB.setUserName("회원2");
+
+ em.persist(memberA);
+ em.persist(memberB);
+ // 여기까지 INSERT SQL을 데이터베이스에 보내지 않는다.
+
+ // 커밋하는 순간 데이터베이스에 INSERT SQL을 보낸다.
+ tx.commit(); //[트랜잭션] 커밋
+ }
+
+ // 엔티티 삭제
+ private void deleteMember(EntityManager em) {
+ Member1 memberA = em.find(Member1.class, "member1");
+ em.remove(memberA);
+ }
+
+ // flush
+ private void fulsh(EntityManager em) {
+ Member1 memberA = new Member1();
+ memberA.setId("member1");
+ memberA.setUserName("회원1");
+
+ Member1 memberB = new Member1();
+ memberB.setId("member2");
+ memberB.setUserName("회원2");
+
+ em.persist(memberA);
+ em.persist(memberB);
+ // 중간에 JPQL 실행 시 자동으로 flush 호출
+ List query = em.createQuery("select m from member m", Member1.class).getResultList();
+
+ }
+
+ // 준영속
+ private void detachedClose(EntityManager em, EntityTransaction tx) {
+ Member1 memberA = em.find(Member1.class, "memberA");
+ Member1 memberB = em.find(Member1.class, "memberB");
+
+ tx.commit(); // 트랜잭션 커밋
+
+ em.close(); // 영속성 컨텍스트 종료
+ }
+
+ // 준영속
+ private void detachedClear(EntityManager em) {
+ // 엔티티 조회, 영속 상태
+ Member1 member = em.find(Member1.class, "memberA");
+
+ em.clear(); // 영속성 컨텍스트 초기화
+
+ // 준영속 상태
+ member.setUserName("changeName");
+
+ }
+
+ // 준영속
+ private void detach(EntityManager em, EntityTransaction tx) {
+ // 회원 엔티티 생성, 비영속 상태
+ Member1 member = new Member1();
+ member.setId("memberA");
+ member.setUserName("회원A");
+
+ // 회원 엔티티 영속 상태
+ em.persist(member);
+
+ // 회원 엔티티를 영속성 컨텍스트에서 분리, 준영속 상태
+ em.detach(member);
+ tx.commit(); // 트랜잭션 커밋
+ }
+
+ // 병합
+ private void detachedMerge(EntityManagerFactory emf) {
+ Member1 member1 = createMember(emf);
+ member1.setUserName("회원명변경");
+ mergeMember(emf, member1);
+
+ }
+
+ // 병합
+ private void mergeMember(EntityManagerFactory emf, Member1 member) {
+ EntityManager em = emf.createEntityManager();
+ EntityTransaction tx = em.getTransaction();
+ tx.begin();
+ try{
+// Member1 mergeMember = em.merge(member);
+ member = em.merge(member); // 준영속 엔티티를 참조하던 변수를 영속 엔티티를 참조하도록 변경하는것이 안전하다
+ tx.commit();
+ // 준영속 상태
+ System.out.println("member = " + member.getUserName());
+
+ // 영속 상태
+// System.out.println("mergeMember = " + mergeMember.getUserName());
+ System.out.println("em contains(member) = " + em.contains(member));
+// System.out.println("em.contains(mergeMember) = " + em.contains(mergeMember));
+ // 결과
+ // member = 회원명변경
+ // mergeMember = 회원명변경
+ // em contains(member) = false
+ // em.contains(mergeMember) = true
+ } catch (Exception e){
+ tx.rollback();
+ } finally {
+ em.close();
+ }
+ }
+
+ // 병합
+ private Member1 createMember(EntityManagerFactory emf) {
+ EntityManager em = emf.createEntityManager();
+ EntityTransaction tx = em.getTransaction();
+ tx.begin();
+ Member1 member = new Member1();
+ try{
+ member.setId("member1");
+ member.setUserName("회원3");
+
+ em.persist(member);
+ tx.commit();
+
+ } catch (Exception e){
+ tx.rollback();
+ } finally {
+ em.close(); // 영속성 컨텍스트 종료
+ // member 엔티티는 준영속 상태
+ }
+ return member;
+ }
+
+}
diff --git a/src/main/java/hellojpa/JpaMain.java b/src/main/java/hellojpa/JpaMain.java
new file mode 100644
index 0000000..39f300d
--- /dev/null
+++ b/src/main/java/hellojpa/JpaMain.java
@@ -0,0 +1,21 @@
+package hellojpa;
+
+import hellojpa.model.Member;
+import lombok.extern.slf4j.Slf4j;
+
+import javax.persistence.*;
+import java.util.List;
+
+@Slf4j
+
+public class JpaMain {
+ public static void main(String[] args) {
+ log.debug("teste========");
+ EntityManagerFactory emf = Persistence.createEntityManagerFactory("hello");
+// Jpa2 jp = new Jpa2(emf);
+ Jpa3 jp = new Jpa3(emf);
+
+ }
+
+
+}
\ No newline at end of file
diff --git a/src/main/java/hellojpa/model/Member.java b/src/main/java/hellojpa/model/Member.java
new file mode 100644
index 0000000..1aafdfb
--- /dev/null
+++ b/src/main/java/hellojpa/model/Member.java
@@ -0,0 +1,15 @@
+package hellojpa.model;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+@Entity
+@Getter@Setter
+public class Member {
+ @Id
+ private Long id;
+ private String name;
+}
diff --git a/src/main/java/hellojpa/model/Member1.java b/src/main/java/hellojpa/model/Member1.java
new file mode 100644
index 0000000..58599f7
--- /dev/null
+++ b/src/main/java/hellojpa/model/Member1.java
@@ -0,0 +1,15 @@
+package hellojpa.model;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+@Entity
+@Getter@Setter
+public class Member1 {
+ @Id
+ private String id;
+ private String userName;
+}
diff --git a/src/main/resources/META-INF/persistence.xml b/src/main/resources/META-INF/persistence.xml
new file mode 100644
index 0000000..f1c2c5a
--- /dev/null
+++ b/src/main/resources/META-INF/persistence.xml
@@ -0,0 +1,25 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml
new file mode 100644
index 0000000..e699ab3
--- /dev/null
+++ b/src/main/resources/logback.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+ %d{HH:mm:ss} [%-5level] %logger{36}[line: %L] - %msg%n
+
+
+
+
+ /tmp/access.log
+
+ /tmp/access-%d{yyyy-MM-dd}.log
+ 50
+
+
+
+ %d{HH:mm:ss} [%-5level] %logger{36}[line: %L] - %msg%n
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file