JDBC | 관계형 데이터 베이스와 자바의 연결고리 Java database connectivity - DataSource/DriverManager - Connection - PreparedStatement |
SQL | DDL, DML |
ORM | Object–relational mapping : 객체 관계 맵핑 - 도메인 모델 사용. > 객체지향 프로그램 장점 활용, 디자인패턴, 코드재사용, 비즈니스 로직 구현 테스트 편함. 애플리케이션의 클래스와 SQL 데이터 베이스의 테이블 사이의 맵핑 정보를 기술한 메타데이터를 사용하며, 자바 애플리케이션의 객체를 SQL 데이터베이스의 테이블에 자동으로 영속화 해주는 기술. - Java Persistence with Hibernate, Second Edition 장점 : 생산성, 유지보수성, 성능, 밴더 독립성 단점 : 학습비용 |
릴레이션/애트리뷰트 튜플/카디날리티 도메인 |
테이블 / 속성(ex_사원번호, 이름, 전화번호, 부서, 최소 차수는 1) 레코드 / 튜플갯수, 0일수있다. 릴레이션에 포함된 각각 속성들이 가질수 있는 값들의 집합. (ex_성별의 의 도메인 남, 여) |
ORM 패러다임 불일치.
문제 | 객체 | 릴레이션 |
밀도 | 다양한 크기 객체 만듬, 커스텀 타입 만들기 쉬움 | 테이블 기본 데이터 타입 UDT(Uniform Data Type) CPU 실행 않고 PG 저장 비추 |
서브타입 | 상속구조 만들기 쉽다, 다형성 | 상속관계없음, 표준기술 아님, 다형적관계표현안됨 |
식별성 문제 | 레퍼러스 동일성(==) 인스턴스 동일성(equals()) |
주키(Primary key) |
관계 | 객체 레퍼런스로 관계표현, 근복적으로 방향존재 다대다 가능 public class Study { User user; } public class User{ List<Study> studyList; } |
외래키(Foreign key) 방향 의미 없음, Join, 다대다 불가, |
데이터 네비게이션 |
레퍼런스를 이용해서 다른 객체로 이동 가능 콜렉션을 순회 활 수 도 있음 getOwner().getStudyList.stream().forEAch(s->s.getOwner()); |
비효율적. 데이터 요청 적게 할수록 성능좋다. Join사용 많이 한번에 가져오는 것도 성능 많이씀. 그렇다고 lazy loading을 하자니 그것도 문제다. (n+1 select) |
JPA 사용이유
1. 도메인 주도 개발... 비지니스 로직 구현 집중 가능. 소프트웨어 복잡도 최소화
도메인 : 사용자가 사용하는것. 영어사전: 1. 영역, 2. 소유지.
+ 단건조회의 경우 jpa가 느릴수 있으나 객체와 데이터 베이스 사이 캐시사용으로 트랜젝션안 불필요한 쿼리를 날리지 않음.
도메인 주도개발 참고 : 도메인 주도 설계(Domain-Driven Design) in Real Project — 도메인
PostgreSQL 설치 및 서버 실행 (docker)
잘못만들어 삭제시
C:\Users\miseong>docker container ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6fe0fabf1380 postgres "docker-entrypoint.s…" 22 minutes ago Up 22 minutes 0.0.0.0:5432->5432/tcp postgres_boot
C:\Users\miseong>docker container stop 6fe0fabf1380
6fe0fabf1380
C:\Users\miseong>docker container rm 6fe0fabf1380
6fe0fabf1380
C:\Users\miseong>docker images ps
REPOSITORY TAG IMAGE ID CREATED SIZE
C:\Users\miseong>docker images ps -a
REPOSITORY TAG IMAGE ID CREATED SIZE
--------
C:\Users\miseong>docker imgaes
docker: 'imgaes' is not a docker command.
See 'docker --help'
C:\Users\miseong>docker images ps
REPOSITORY TAG IMAGE ID CREATED SIZE
docker run -p 5432:5432 -e POSTGRES_PASSWORD=pass -e POSTGRES_USER=keesun -e POSTGRES_DB=springdata --name postgres_boot -d postgres
docker run -p 5432:5432 -e POSTGRES_PASSWORD=1234 -e POSTGRES_USER=day -e POSTGRES_DB=diarydata --name postgres_diary -d postgres
C:\Users\miseong>docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
postgres latest 26c8bcd8b719 2 weeks ago 314MB
C:\Users\miseong>docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6fe0fabf1380 postgres "docker-entrypoint.s…" About a minute ago Up About a minute 0.0.0.0:5432->5432/tcp postgres_boot
C:\Users\miseong>docker start postgres_diary
postgres_diary
C:\Users\miseong>docker exec -i -t postgres_diary bash
root@b1de21ce08f0:/# su - postgres
postgres@b1de21ce08f0:~$ psql --username day --dbname diarydata
psql (13.2 (Debian 13.2-1.pgdg100+1))
Type "help" for help.
diarydata=# CREATE TABLE ACCOUNT(id int, username varchar(255), password varchar(255));
CREATE TABLE
diarydata=# INSERT INTO ACCOUNT VALUES(1,'day', 'pass');
INSERT 0 1
diarydata=# SELECT * FROM ACCOuNT;
id | username | password
----+----------+----------
1 | day | pass
(1 row)
데이터베이스 조회
diarydata=# list
diarydata-# ;
ERROR: syntax error at or near "list"
LINE 1: list
^
diarydata=# \list
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+-------+----------+------------+------------+-------------------
diarydata | day | UTF8 | en_US.utf8 | en_US.utf8 |
postgres | day | UTF8 | en_US.utf8 | en_US.utf8 |
template0 | day | UTF8 | en_US.utf8 | en_US.utf8 | =c/day +
| | | | | day=CTc/day
template1 | day | UTF8 | en_US.utf8 | en_US.utf8 | =c/day +
| | | | | day=CTc/day
(4 rows)
diarydata=#
테이블 조회
diarydata=# \dt
List of relations
Schema | Name | Type | Owner
--------+---------+-------+-------
public | account | table | day
(1 row)
잘못만들어 삭제시
C:\Users\miseong>docker container ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6fe0fabf1380 postgres "docker-entrypoint.s…" 22 minutes ago Up 22 minutes 0.0.0.0:5432->5432/tcp postgres_boot
C:\Users\miseong>docker container stop 6fe0fabf1380
6fe0fabf1380
C:\Users\miseong>docker container rm 6fe0fabf1380
6fe0fabf1380
C:\Users\miseong>docker images ps
REPOSITORY TAG IMAGE ID CREATED SIZE
C:\Users\miseong>docker images ps -a
REPOSITORY TAG IMAGE ID CREATED SIZE
--------
C:\Users\miseong>docker imgaes
docker: 'imgaes' is not a docker command.
See 'docker --help'
C:\Users\miseong>docker images ps
REPOSITORY TAG IMAGE ID CREATED SIZE
docker run -p 5432:5432 -e POSTGRES_PASSWORD=pass -e POSTGRES_USER=keesun -e POSTGRES_DB=springdata --name postgres_boot -d postgres
docker run -p 5432:5432 -e POSTGRES_PASSWORD=1234 -e POSTGRES_USER=day -e POSTGRES_DB=diarydata --name postgres_diary -d postgres
C:\Users\miseong>docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
postgres latest 26c8bcd8b719 2 weeks ago 314MB
C:\Users\miseong>docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
6fe0fabf1380 postgres "docker-entrypoint.s…" About a minute ago Up About a minute 0.0.0.0:5432->5432/tcp postgres_boot
C:\Users\miseong>docker start postgres_diary
postgres_diary
C:\Users\miseong>docker exec -i -t postgres_diary bash
root@b1de21ce08f0:/# su - postgres
postgres@b1de21ce08f0:~$ psql --username day --dbname diarydata
psql (13.2 (Debian 13.2-1.pgdg100+1))
Type "help" for help.
diarydata=# CREATE TABLE ACCOUNT(id int, username varchar(255), password varchar(255));
CREATE TABLE
diarydata=# INSERT INTO ACCOUNT VALUES(1,'day', 'pass');
INSERT 0 1
diarydata=# SELECT * FROM ACCOuNT;
id | username | password
----+----------+----------
1 | day | pass
(1 row)
데이터베이스 조회
diarydata=# list
diarydata-# ;
ERROR: syntax error at or near "list"
LINE 1: list
^
diarydata=# \list
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+-------+----------+------------+------------+-------------------
diarydata | day | UTF8 | en_US.utf8 | en_US.utf8 |
postgres | day | UTF8 | en_US.utf8 | en_US.utf8 |
template0 | day | UTF8 | en_US.utf8 | en_US.utf8 | =c/day +
| | | | | day=CTc/day
template1 | day | UTF8 | en_US.utf8 | en_US.utf8 | =c/day +
| | | | | day=CTc/day
(4 rows)
diarydata=#
테이블 조회
diarydata=# \dt
List of relations
Schema | Name | Type | Owner
--------+---------+-------+-------
public | account | table | day
(1 row)
jdbc 예제
package com.today10sec.diary.basic;
import java.sql.*;
public class DBConnectTest {
public static void main(String[] args) throws SQLException {
String url = "jdbc:mariadb://localhost:3306/today10secDB";
String userName = "today";
String pw = "1234";
//try with resource java 7 //자동 자원정리 메소드
try(Connection connection = DriverManager.getConnection(url, userName,pw)){
//System.out.println("Connection Created"+ connection);
//String sql = " CREATE TABLE ACCOUNT(id int, username varchar(255), password varchar(255))";
//String sql = " INSERT INTO ACCOUNT VALUES(1,'day', 'pass')";
String sql =" SELECT * FROM ACCOuNT";
ResultSet rs ;
try(PreparedStatement statement = connection.prepareStatement(sql)){
rs = statement.executeQuery();
//int result = statement.executeUpdate();
//System.out.println(result);
while (rs.next()){
System.out.println(rs.getInt("id")+rs.getString("username")+rs.getString("password"));
}
}
}
//JDBC : 커넥션 만드는 비용이 비쌈 - 오래걸림.
//스프링 부트 : hicari : 커넥션 객체 미리 만들고 사용.
}
}
JPA 프로그래밍: 프로젝트 세팅
데이터베이스 실행
- PostgreSQL 도커 컨테이너 재사용
- docker start postgres_boot
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
스프링 부트
- 스프링 부트 v2.*
- 스프링 프레임워크 v5.*
스프링 부트 스타터 JPA
- JPA 프로그래밍에 필요한 의존성 추가
- JPA v2.*
- Hibernate v5.*
- 자동 설정: HibernateJpaAutoConfiguration
- 컨테이너가 관리하는 EntityManager (프록시) 빈 설정
- PlatformTransactionManager 빈 설정
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
엔티티메니저.. JPA 스팩.
엔티티매니저 내부적 하이버네이트 사용.
강의 해선. 스프링데이터 JPA 를 사용
JDBC 설정
- jdbc:postgresql://localhost:5432/springdata
- keesun
- pass
application.properties
- spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
- spring.jpa.hibernate.ddl-auto=create
#spring.jpa.hibernate.ddl-auto : create or update ( 매번 스키마 생성. )for dev, validate(매핑안되면 에러) for prod,추천
update.. 스키마 변경시... 스키마가 추가가됨. 주의
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation :
추가한 드라이버가 메시지를 구현안했을때 경고 >> true 없음.
spring.jpa.hibernate.ddl-auto=create.. 운영에서 소스 잘못 올라가면 살인날듯
entityManager
기본예제
#basic db
spring.datasource.url=jdbc:postgresql://localhost:5432/diarydata
spring.datasource.password=1234
spring.datasource.username=day
#hibernate
spring.jpa.hibernate.ddl-auto=create
#spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true
package com.today10sec.diary.etc;
import org.hibernate.Session;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.transaction.Transactional;
@Component
@Transactional
public class JpaRunner implements ApplicationRunner {
@PersistenceContext
EntityManager entityManager;
@Override
public void run(ApplicationArguments args) throws Exception {
Account account = new Account();
account.setUsername("day");
account.setPassword("12345");
Session session = entityManager.unwrap(Session.class);
session.save(account);
entityManager.persist(account);
System.out.println("접근");
}
}
package com.today10sec.diary.etc;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity
public class Account {
@Id @GeneratedValue
private Long id;
@Column
private String username;
private String password;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
'JAVA > spring' 카테고리의 다른 글
스프링 목차 (0) | 2021.04.29 |
---|---|
[1028 FORM 백기선 스프링프레임워크 핵심기술] SpEL, AOP,Null-safety (0) | 2021.04.29 |
[1028 FORM 백기선 스프링프레임워크 핵심기술] Validation, 데이터 바인딩. (0) | 2021.04.28 |
[1028 FORM 백기선 스프링프레임워크 핵심기술] Environment, MessageSource, ApplicationEventPublisher, ResourceLoader (0) | 2021.04.28 |
[1028 FORM 백기선 스프링프레임워크 핵심기술] IoC 컨테이너와 빈 (0) | 2021.04.28 |