728x90
JPA 다중 스키마 설정
아래 내용은 https://github.com/beaver84/setting-test 에서 실제 소스를 확인할 수 있습니다.
- JPA 구조
- Persistence: EntityManagerFactory 인스턴스를 얻기 위한 정적 메서드를 포함하는 클래스이다.
- EntityManagerFactory: EntityManager의 팩토리 클래스입니다. EntityManager의 여러 인스턴스를 생성하고 관리한다.
- EntityManager: 개체에 대한 지속성 작업을 제어하는 인터페이스이다. 쿼리 인스턴스에서 작동합니다.
- Entity 엔터티는 데이터베이스에 레코드로 저장되는 persistence 개체입니다.
- Persistence Unit: 모든 엔터티 클래스 집합을 정의합니다. 애플리케이션에서는 EntityManager 인스턴스가 이를 관리합니다. 엔티티 클래스 집합은 단일 데이터 저장소에 포함된 데이터를 나타냅니다.
- EntityTransaction: EntityManager 클래스와 일대일 관계를 가집니다 . 각 EntityManager에 대해 작업은 EntityTransaction 클래스에 의해 유지 관리됩니다.
- Query: 기준에 맞는 관계 객체를 얻기 위해 각 JPA 벤더에서 구현하는 인터페이스이다.
- 앞선 글에 Mybatis 설정 완료된 프로젝트에 이어서 JPA 설정을 추가한다.
- 먼저 build.gradle 에 아래 라이브러리를 추가하고 코끼리 모양 버튼을 클릭하여 새로고침을 한다.
dependencies {
...
// JPA 라이브러리 추가 (기존에 있으면 추가안해도 무방함)
implementation 'org.springframework.data:spring-data-jpa'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
...
}
- 다음에 application.properties 파일을 수정한다.
(기존 내용 아래 추가)
teamflace.jpa.datasource.master.jdbc-url=jdbc:log4jdbc:mysql://localhost:3306/[스키마명]?characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true&autoReconnection=true
teamflace.jpa.datasource.master.username=[아이디]
teamflace.jpa.datasource.master.password=[비밀번호]
teamflace.jpa.database=mysql
teamflace.jpa.hibernate.use-new-id-generator-mappings=false
teamflace.jpa.show-sql=true
#데이터베이스 방언을 프로젝트 main DB인 MySQL로 설정
teamflace.jpa.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
#JPA Lazy 타입 조회 시, N+1(1+N) 현상 발생 방지
teamflace.jpa.properties.hibernate.default_batch_fetch_size=1000
- 이제 application.properties의 내용을 컨테이너에 주입할 config 파일을 만들어야 한다.
- 그러기 위해 config 패키지 밑에 JpaConfig.java 파일을 만든다.
- repository 패키지 하위에 jpa 패키지를 미리 만들어야 한다(JPA 설정을 적용할 basePackage 지정) .
- @EnableJpaRepositories(basePackages = "com.example.settingtest.repository.jpa" 에는 위에 만든 패키지의 풀네임을 입력한다.
- 마지막으로 em.setPackagesToScan("com.example.settingtest.domain") 에는 실제 entity가 저장되는 패키지 위치를 입력한다.
(임포트 구문 생략)
@Configuration
@Lazy
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "com.example.settingtest.repository.jpa", entityManagerFactoryRef = "jpaTestEntityManagerFactory")
@EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class})
public class JpaConfig {
private Logger log = LogManager.getLogger(this.getClass());
private Properties properties;
@Autowired
public JpaConfig(@Qualifier("jpaTestDatasourceProperties") Properties properties) {
this.properties = properties;
}
//application.properties 파일에 jpaTest.jp로 시작하는 접속 정보를 Properties에 가져온다.
@ConfigurationProperties(prefix = "jpaTest.jpa")
@Bean(name = "jpaTestDataSourceProperties")
public Properties jpaTestDataSourceProperties() {
return new Properties();
}
//위에서 만들어진 properties 정보를 바탕으로 spring JDBC에 필요한 dataSource를 생성
@Bean(name = "jpaTestDatasource")
public DataSource jpaTestDatasource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
log.info("teamflaceJpaDatasource ===> {}", dataSource);
dataSource.setDriverClassName(properties.getProperty("driver-class-name"));
dataSource.setUrl(properties.getProperty("url"));
dataSource.setUsername(properties.getProperty("username"));
dataSource.setPassword(properties.getProperty("password"));
return dataSource;
}
//위에서 만들어진 datasource를 바탕으로 JPA에 영속성 컨텍스트인 EntityManager를 만든다.
//또한 이를 생성하는 EntityManagerFactory를 만든다.
@Bean(name = "jpaTestEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean jpaTestEntityManagerFactory() throws Exception {
LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(jpaTestDatasource());
em.setPackagesToScan("[실제 entity가 저장되는 패키지]");
HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(jpaTestDataSourceProperties());
log.info("jpaTestDataSourceProperties ===> {}", jpaTestDataSourceProperties());
return em;
}
//위에서 만든 EntityManager와 EntityManagerFactory 정보를 바탕으로 TransactionManager를 만든다.
//서비스단에서 @Transactional로 사용할 수 있다.
//Mybatis와 같이 사용하기 위해 작업을 한 트랜잭션으로 묶기 위한 배경작업
@Bean(name = "jpaTestTransactionManager")
public PlatformTransactionManager jpaTestTransactionManager() throws Exception {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(jpaTestEntityManagerFactory().getObject());
log.info("teamflaceJpaTransactionManager ===> {}", transactionManager);
return transactionManager;
}
}
- @EnableAutoConfiguration(exclude = {DataSourceAutoConfiguration.class}) 는 기본 설정과 겹치는 부분이 있는 경우 무시하는 설정방법이다(어떤 설정을 가져왔는지 몰라서 생기는 오류 발생 방지).
- @Configuration 안에 @Bean이 4개 있는데 차례대로 간략히 설명하자면 다음과 같다.
- Properties teamflaceJpaDataSourceProperties() - application.properties 파일에 패키지명의 prefix 로 시작하는 접속 정보를 Properties에 가져옴
- DataSource teamflaceJpaDatasource() - properties 정보를 바탕으로 spring JDBC에 필요한 dataSource 를 생성
- LocalContainerEntityManagerFactoryBean teamfleshEntityManagerFactory() - datasource 를 바탕으로 JPA에 Entity를 관리하는 EntityManager, 또한 이를 생성하는 EntityManagerFactory 를 만든다.
- PlatformTransactionManager teamflaceJpaTransactionManager() - EntityManager와 EntityManagerFactory 정보를 바탕으로 TransactionManager를 만든다. PlatformTransactionManager의 구현체 중에 JpaTransactionManager를 활용하였다.
728x90
- 이제 Mybatis와 한 트랜잭션으로 묶어서 관리하기 위해 Mybatis 설정에서 만들었던 RdbConnectionConfiguration을 수정한다.
- Qualifier에 설정된 빈과 같은 이름으로 찾아가 패키지에 따라 Mybatis 혹은 JPA로 DB 연동 작업을 수행하게 된다.
(임포트 구문 생략)
@Configuration
@Lazy
@EnableTransactionManagement
public class RdbConnectionConfiguration {
@Bean(name = "transactionManager")
@Primary
public PlatformTransactionManager transactionManager(
@Qualifier("mybatisTransactionManager") PlatformTransactionManager mybatisTransactionManager,
@Qualifier("jpaTestTransactionManager") PlatformTransactionManager jpaTestTransactionManager) {
return new ChainedTransactionManager(
mybatisTransactionManager,
jpaTestTransactionManager);
}
}
- 이제 JPA 설정이 완료됐으며 테스트 코드를 통해 테스트를 진행한다.
- 아래 위치에 repository 파일을 추가한다.
@Repository
public interface MemberJpaRepository extends JpaRepository<Member, Long> {
Member findByEmail(String email);
}
- 기존 엔티티에 @Entity, @Id 속성을 추가한다.
- test 코드를 작성한다.
import static org.assertj.core.api.Assertions.assertThat;
@SpringBootTest
@Transactional
class MemberJpaRepositoryTest {
@Autowired
MemberJpaRepository memberJpaRepository;
@BeforeEach
public void setUp() {
//setup before testing
memberJpaRepository.deleteAll();
}
@Test
@DisplayName("이메일로 멤버 조회 JPA 테스트")
void findByEmail() {
//given : 멤버 정보가 주어졌을 때
Member member = new Member();
member.setEmail("beaver@timf.co.kr");
member.setName("배비버");
member.setAddress("경기도 부천");
member.setPassword("1123");
memberJpaRepository.save(member);
//when : 이메일로 단건조회를 하면
Member memberResult = memberJpaRepository.findByEmail("eden@timf.co.kr");
//then : 해당 유저 정보를 조회할 수 있다.
assertThat(memberResult.getId()).isGreaterThanOrEqualTo(1);
assertThat(memberResult.getEmail()).isEqualTo("beaver@timf.co.kr");
assertThat(memberResult.getName()).isEqualTo("배비버");
assertThat(memberResult.getAddress()).isEqualTo("경기도 부천");
assertThat(memberResult.getPassword()).isEqualTo("1123");
}
}
- 테스트가 정상적으로 수행되었고 JPA 셋팅이 완료되었다.
참고: https://www.javatpoint.com/spring-boot-jpa
728x90
'Spring > 초기 setting' 카테고리의 다른 글
6) 스프링 시큐리티(spring-security) 적용 (0) | 2023.04.05 |
---|---|
5) 스프링 시큐리티(spring-security) 개요 (0) | 2023.04.05 |
4) Querydsl 설정 (2) | 2023.03.20 |
2) MyBatis 3.0 다중 스키마 설정 (0) | 2023.03.19 |
1) 스프링 부트 프로젝트 생성 (0) | 2023.03.19 |