๋ฒ ์ด์ง๋ฐ
๋ฐ์ดํฐ ์ ๊ทผ ๋ฐฉ๋ฒ JPA
12/17 11:00 ~ 12:40 (์ฝ 1์๊ฐ 40๋ถ ์งํ)
์ค์ ํค์๋
- JPA
- ์์์ฑ ์ปจํ ์คํธ → ๋ฉด์ ์์ ํญ์ ๋์ค๋ ๋ด์ฉ
- ์์์ฑ ์ปจํ
์คํธ์ ์ฅ์
- 1์ฐจ ์บ์ฑ
- ๋๋ฑ์ฑ ๋ณด์ฅ
- ์ฐ๊ธฐ ์ง์ฐ
- ๋ณ๊ฒฝ ๊ฐ์ง
- JPA ๋ ๊ฐ์ง ํ์ฉ ๋ฐฉ๋ฒ
- ์์ JPA
- JPA ์ธํฐํ์ด์ค → ํ์ ์์ ๋ง์ด ์ฌ์ฉํ๋ค.
JPA(Java Persistence API)
JPA๋ ์๋ฐ ์ํ๊ณ์์ ORM์ ๊ตฌํํ ์ ์๋ ํ์ค ๋ช
์ธ์ด๋ค.
Hibernate๋ JPA ๋ช
์ธ๋ฅผ ๊ตฌํํ ๊ตฌํ์ฒด ์ค ํ๋์ด๋ค.
JPA๊ฐ ๋ด๋ถ์ ์ผ๋ก JDBC API๋ฅผ ํ์ฉํ๋ค.
ORM(Object-Relational Mapping)
๋ฐ์ดํฐ๋ฅผ ๊ฐ์ฒด์ฒ๋ผ ์ฌ์ฉํ๋ ๊ธฐ๋ฒ์ด๋ค.
ORM์ ํ๊ณ๊ฐ ์กด์ฌํ๊ธฐ ๋๋ฌธ์ SQL์ ์ ์๊ณ ์์ด์ผ ํ๋ค.
- ๋ ๋ค ์๊ณ ์์ด์ผ ํ๋ค. ํ์ชฝ๋ง ์๊ณ ์์ผ๋ฉด ์ ๋๋ค.
- ORM์ด ์์ฐ์ฑ์ด ์ข๋ค.
์ธ์ด๋ง๋ค ๋ค์ํ ORM ๊ธฐ์
์ธ์ด | ORM ๊ธฐ์ ์ด๋ฆ |
Java | JPA |
javascript | Sequelize |
python | Django ORM |
CRUD ํ์ฉ ์์
1. ์์ฑ(CREATE)
INSERT INTO student (name) VALUES ("gygim");
Student newStudent = new Student("gygim");
studentRepository.save(newStudent);
2. ์กฐํ(READ)
SELECT * FROM student;
List<Student> students = studentRepository.findAll();
3. ์ ๋ฐ์ดํธ(UPDATE)
UPDATE student SET name="Steve" WHERE id = 1;
Student foundStudent = studentRepository.findById(1L);
foundStudent.setName("Steve");
4. ์ญ์ (DELETE)
DELETE FROM student WHERE id = 1;
Student foundStudent = studentRepository.findById(1L);
studentRepository.delete(foundStudent);
์ํฐํฐ(Entity) @Entity
๋ฐ์ดํฐ๋ฒ ์ด์ค ํ ์ด๋ธ๊ณผ ๋งคํ๋๋ ํด๋์ค์ด๋ค.
1. ๋ฐ์ดํฐ๋ฒ ์ด์ค
CREATE TABLE student (
id BIGINT AUTO_INCREMENT PRIMARY_KEY,
name VARCHAR(255)
);
Field | Type | Null | Key | Extra |
id | bigint(20) | No | PRI | auto_increment |
name | varchar(255) | No |
2. ์ํฐํฐ(Entity)
@Entity
public class Student {
@Id
@GeneratedValue(straregy = GenerationType.IDENTITY)
private Long id;
private String name;
// Getter and Setters
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
์์์ฑ ์ปจํ ์คํธ
์ํฐํฐ(Entity)๋ฅผ ์ ์ฅํ๋ ๊ณต๊ฐ์ด๋ค.
์๋ฐ์ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ฌ์ด์์ ์ค๊ฐ ๋ค๋ฆฌ ์ญํ ์ ๋ด๋นํ๋ค.
์์์ฑ ์ปจํ
์คํธ์ ์ง์ด๋ฃ๋ ์๊ฐ ์ถ์ ํ๊ณ ๊ฐ์ํ๋ค.
๋๊ธฐํ ์์
์ ํ๋ค. ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ผ์น๋๊ฒ๋ ๋ง๋ค์ด์ค๋ค.
1. JPA๋ฅผ ํ์ฉํ ์คํ๋ง ์ ํ๋ฆฌ์ผ์ด์ ํ๋ฆ๋
a. ์ํฐํฐ ๋งค๋์ ํฉํ ๋ฆฌ(EMF: EntityManagerFactory)
application.properties
spring.datasource.url=jdbc:mysql://localhost:3306/<๋ฐ์ดํฐ๋ฒ ์ด์ค>
spring.datasource.username=<์ ์ ์ด๋ฆ>
spring.datasource.password=<๋น๋ฐ๋ฒํธ>
spring.datasource.driver-class-name=<๋ฐ์ดํฐ๋ฒ ์ด์ค ๋ฐฉ์ธ>
์์: EntityManagerFactory๊ฐ ์์ฑ๋๋ ์ฝ๋
EntityManagerFactory emf = Persistence.reateEntityManagerFactory("์๋ฌธ์ EMF");
b. ์ํฐํฐ ๋งค๋์ (EM: EntityManager)
์ํฐํฐ ๋งค๋์ (EntitiyManager)๊ฐ ์์ฑ๋ ๋ ์์์ฑ ์ปจํ
์คํธ๊ฐ ๋์์ ์์ฑ๋๋ค.
์ํธ์์ฉ์ ํ๋ ์น๊ตฌ์ด๋ค.
์์: EntityManagerFactory๊ฐ ์์ฒญ๋ง๋ค EntitiyManager๋ฅผ ์์ฑํ๋ ์ฝ๋
EntityManagerFactory emf = Persistence.createEntityManagerFactory("์๋ฌธ์EMF");
EntityManager emA = emf.createEntityManager();
EntityManager emB = emf.createEntityManager();
โ๏ธ ์์์ฑ ์ปจํ ์คํธ์ ์์ฑ ์์
์์์ฑ ์ปจํ ์คํธ๋ EntityManager๊ฐ ์์ฑ๋ ๋ ๋ง๋ค์ด์ง๋ค.
2. ์์์ฑ ์ปจํ ์คํธ ํ์ฉ
@Repository
public class StudentRepository {
@PersistenceContext
EntityManager em;
public void save(Student student) {
em.persist(student);
}
...
}
@PersisteneContext๋ ์คํ๋ง ์ปจํ ์ด๋๊ฐ ๊ด๋ฆฌํ๋ ์ํฐํฐ ๋งค๋์ (EntityManager)๋ฅผ ์ฃผ์ ํ๋ ์ด๋ ธํ ์ด์ ์ด๋ค.
์ํฐํฐ(Entity) ์๋ช ์ฃผ๊ธฐ
์ํ | ์ค๋ช |
๋น์์ | ์์์ฑ ์ปจํ ์คํธ์ ์ ํ ๊ด๊ณ๊ฐ ์๋ ์๋ก์ด ์ํ |
์์ | ์์์ฑ ์ปจํ ์คํธ์ ๊ด๋ฆฌ๋๋ ์ํ |
์ค์์ | ์์์ฑ ์ปจํ ์คํธ์ ์ ์ฅ๋์๋ค๊ฐ ๋ถ๋ฆฌ๋ ์ํ |
์ญ์ | ์ญ์ ๋ ์ํ |
1. ๋น์์
// ๊ฐ์ฒด๋ฅผ ์์ฑํ ์ํ(๋น์์)
Student student = new Student();
student.setName("์๋ฌธ์ํ์");
2. ์์
// ๊ฐ์ฒด๋ฅผ ์์ฑํ ์ํ(๋น์์)
Student newStudent = new Student();
newStudent.setName("์๋ฌธ์ํ์");
// ๊ฐ์ฒด๋ฅผ ์ ์ฅํ ์ํ(์์์ํ)
em.persist(newStudent);
์์์ฑ ์ปจํ ์คํธ ์ฅ์
1. 1์ฐจ ์บ์ฑ
Student a = em.find(Student.class, "์๋ฌธ์ํ์A"); // SELECT * FROM Student WHERE id = '์๋ฌธ์ํ์A'
Student b = em.find(Student.class, "์๋ฌธ์ํ์A"); // SELECT ์ฟผ๋ฆฌ ๋ฐ์ X (1์ฐจ ์บ์ ์ฌ์ฉ)
2. ๋์ผ์ฑ ๋ณด์ฅ
Student a = em.find(Student.class, "์๋ฌธ์ํ์A");
Student b = em.find(Student.class, "์๋ฌธ์ํ์A");
// ๋์ผ์ฑ ๋น๊ต true (๊ฐ์ ๊ฐ์ฒด ๋ฐํ)
System.out.println(a == b);
3. ์ฐ๊ธฐ ์ง์ฐ
EntityManager em = emf.createEntityManager();
EntityTransaction transaction = em.getTransaction();
//๋ฐ์ดํฐ ๋ณ๊ฒฝ์ ํธ๋์ญ์
์ ์์
transaction.begin(); // ํธ๋์ญ์
์์
em.persist(studentA); // (1) INSERT ...
em.persist(studentB); // (2) INSERT ...
// ์ฐ๊ธฐ์ง์ฐ์ persist ํธ์ถ์ SQL ์ด ๋ฐ๋ก ์คํ๋์ง ์์ต๋๋ค.
// (1, 2 ์ sql ์ ๋ชจ์๋ค๊ฐ ๋ณด๋ธ๋ค.)
trasnaction.commit(); ํธ๋์ ์
์ปค๋ฐ
4. ๋ณ๊ฒฝ ๊ฐ์ง
// ์์
Student foundStudent = em.find(Student.class, "์๋ฌธ์ํ์A");
foundStudent.setName("์๋ก์ด์ด๋ฆ");
// persist ํธ์ถ ๋ถํ์ํฉ๋๋ค.
// ๋ณ๊ฒฝ๋ ์์ฑ์ ํธ๋์ญ์
์ปค๋ฐ ์ ์๋ ๋ฐ์ ๋ฉ๋๋ค.
em.persist(foundStudent);
์ค์ต ํฌ์ธํธ
- student ์์ฑ API
- student ์กฐํ API
1. ์ฌ์ฉํ ๋ฐ์ดํฐ๋ฒ ์ด์ค ์ค๋น
CREATE DATABASE basic_db CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;
2. ์์กด์ฑ ์ถ๊ฐ ๋ฐ ์ ํ๋ฆฌ์ผ์ด์ ์ค์
// JPA
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
// MYSQL
implementation 'mysql:mysql-connector-java:8.0.28'
// MariaDB
implementation 'org.mariadb.jdbc:mariadb-java-client'
spring.application.name=<์ ํ๋ฆฌ์ผ์ด์
์ด๋ฆ>
// Mysql ์ฌ์ฉ์
spring.datasource.url=jdbc:mysql://localhost:3306/basic_db
spring.datasource.username=<์ ์ ์ด๋ฆ>
spring.datasource.password=<๋น๋ฐ๋ฒํธ>
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
// (์ ํ) MariaDB ์ฌ์ฉ์
spring.datasource.url=jdbc:mariadb://localhost:3306/basic_db
spring.datasource.username=<์ ์ ์ด๋ฆ>
spring.datasource.password=<๋น๋ฐ๋ฒํธ>
spring.datasource.driver-class-name=org.mariadb.jdbc.Driver
// JPA ์์ ์ง์ํด์ฃผ๋ ํธ์ ๊ธฐ๋ฅ
spring.jpa.hibernate.ddl-auto=create
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
3. ์ํฐํฐ(Entity) ๋ง๋ค๊ธฐ - Student.java
@Entity
@Getter
@Table(name = "student")
public class Student {
@Id @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
protected Student() {}
private Student(String name) {
this.name = name;
}
public static Student of(String name) {
return new Student(name);
}
}
4. ๋ฐ์ดํฐ ์ ๊ทผ ๋ก์ง - JPAStudentRepository.java
@Repository
public class JPAStudentRepository implements StudentRepository {
@PersistenceContext
private EntityManager entityManager;
@Transactional
@Override
public Student save(Student student) {
entityManager.persist(student);
return student;
}
@Override
public List<Student> findAll() {
return entityManager.createQuery("SELECT s FROM Student s", Student.class).getResultList();
}
}
JPA ๋ ๊ฐ์ง ํ์ฉ ๋ฐฉ๋ฒ
1. ์์ JPA ํ์ฉ
@Repository
public class JPAStudentRepository {
@PersistenceContext
private EntityManager entityManager;
@Transactional
public Student save(Student student) {
entityManager.persist(student);
return student;
}
public List<Student> findAll() {
return entityManager.createQuery("SELECT s FROM Student s", Student.class).getResultList();
}
}
2. JPA ์ธํฐํ์ด์ค ํ์ฉ
public interface SpringDataStudentRepository extends JpaRepository<Student, Long> {
}
a. ์ฟผ๋ฆฌ ๋ฉ์๋
public interface SpringDataStudentRepository extends JpaRepository<Student, Long> {
Optional<Student> findByName(String name);
}
'Today I Learned(TIL) > ์์ค๋ณ ํ์ต๋ฐ' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
์์ค๋ณ ํ์ต๋ฐ_๋ฒ ์ด์ง๋ฐ 5ํ์ฐจ ์ธ์ (1) | 2024.12.22 |
---|---|
์์ค๋ณ ํ์ต๋ฐ_๋ฒ ์ด์ง๋ฐ 3ํ์ฐจ ์ธ์ (0) | 2024.12.16 |
์์ค๋ณ ํ์ต๋ฐ_๋ฒ ์ด์ง๋ฐ 2ํ์ฐจ ์ธ์ (0) | 2024.12.11 |
์์ค๋ณ ํ์ต๋ฐ_๋ฒ ์ด์ง๋ฐ 1ํ์ฐจ ์ธ์ (0) | 2024.12.07 |
์์ค๋ณ ํ์ต๋ฐ_์คํ ๋ค๋๋ฐ 1ํ์ฐจ (1) | 2024.12.04 |