Posts
Q&A
์๋ก ๋ค๋ฅธ ์คํค๋ง(database) ์ ์๋ ํ ์ด๋ธ์ ์ฐ๊ด๊ด๊ฒ ๋งคํ ์ ์๋ฌ๊ฐ ๋๋๋ฐ ๊ฐ๋ฅํ ๋ฐฉ๋ฒ์ด ์๋์?
๊ฐ์ EntityManagerFactory ๋ก ๊ด๋ฆฌ๋๋ ๊ฒฝ์ฐ A.table1 join B.table2 ์ด ์ ๋๋ค์... EntityManagerFactory ๊ฐ ๋ค๋ฅธ ๊ฒฝ์ฐ๋ ์๋๋๊ฒ ๋ง์ ๊ฒ ๊ฐ์ต๋๋ค. ํ์ธ ๊ฐ์ฌํฉ๋๋ค.
- Likes
- 0
- Comments
- 3
- Viewcount
- 1.2K
Q&A
์๋ก ๋ค๋ฅธ ์คํค๋ง(database) ์ ์๋ ํ ์ด๋ธ์ ์ฐ๊ด๊ด๊ฒ ๋งคํ ์ ์๋ฌ๊ฐ ๋๋๋ฐ ๊ฐ๋ฅํ ๋ฐฉ๋ฒ์ด ์๋์?
์๊ฒ ์ต๋๋ค. ํ์ ๋ค๋ฅธ EntityManagerFactory ๋ก ๊ด๋ฆฌ๋๋๋ฐ EntityManagerFactory ํ๋๋ก ํฉ์ณ๋ ๋ ๊ฒ ๊ฐ์ต๋๋ค. ํฉ์ณ์ ํ ์คํธ ํด ๋ณด๊ฒ ์ต๋๋ค. ๊ฐ์ฌํฉ๋๋ค.
- Likes
- 0
- Comments
- 3
- Viewcount
- 1.2K
Q&A
batchInsert ๊ฐ ๊ฐ๋ฅํ์ง ๋ฌธ์๋๋ฆฝ๋๋ค.
์ค์ ์คํ๋ง ๋ถํธ์ JPA ํ์ฉ1,2 JPA : ์๋ฐ ORM ํ์ค JPA ํ๋ก๊ทธ๋๋ฐ -๊ธฐ๋ณธํธ QueryDSL Spring Data JPA ์๋ ํ์ธ์ ๊ฐ์ ์ ๋ฃ๊ณ ์์ต๋๋ค. ์ ๊ฐ ๊ตฌ๋งคํ ๊ฐ์ ๋ชฉ๋ก ์ธ๋ฐ์ ์ด์ค์ batchinsert (JPA ์ฑ 15.4.5) ๊ฐ ์ด๋ ๊ฐ์์ ์๋์ง ํ๋ฒ ๋ ํ์ธํด ์ฃผ์๋ฉด ๊ณ ๋ง๊ฒ ์ต๋๋ค. batch update ๋ฑ์ ๊ฐ์์์ ๋ดค๋๋ฐ์. batch insert ๋ก ๋๋์ ๋ฐ์ดํ(List) ๋ฅผ ๋ฃ๋ ๊ฒฝ์ฐ๋ ํ์ํด์ ์ง๋ฌธ๋๋ ธ์ต๋๋ค
- Likes
- 0
- Comments
- 4
- Viewcount
- 543
Q&A
fetch join ์ child table ์กฐ๊ฑด์ด ์ค์ ์ฟผ๋ฆฌ์ ๋ฐ์์ด ์๋๋ค์..
โข ์๋ฐ์ง์์ORM๊ธฐ์ ํ์ค โข JPA๋ฅผ ์ ์ฌ์ฉํด์ผ ํ๋๊ฐ? โข JPA๋์-์ ์ฅ, ์กฐํ โข JPA์์์-์ ์ฅ,์กฐํ โข ์ฑ๋ฅ์ต์ ํ - 1์น ์บ์ฌ โข ์ฑ๋ฅ์ต์ ํ - Lazy ๋ก๋ฉ โข OSIV ์ต์ ํ โข ์๋ฐฉํฅ ์ฐ๊ด๊ด๊ณ Owner โข QueryDsl ์ฅ์ โข QueryDsl ์ฟผ๋ฆฌ ์ฌ์ฉ์ ์ํ Repository ๊ตฌ์กฐ (Custom Repository, Impl, Querydsl4RepositorySupport) โข N+1 ๋ฌธ์ ํด๊ฒฐ . ํ์ด์ง & ์ํ โข Projections JPA ๊ด๋ จ ๊ฐ์ 5๊ฐ๋ฅผ ๋ค์ผ๋ฉด์ ์ ๋ฆฌํด ๋ณธ ์ฃผ์ ์ธ๋ฐ์. ์ค๋ฌด์์ ์ค์ํ ํ(@OneToMany ์์ batch_size ์ค์ ์ ํตํ N+1 ๋ฌธ์ ํด๊ฒฐ, osiv on/off ์ด์๋ฑ) ๋๋ ์ค๋ฌด์์ ๋ฐ์ํ ์ ์๋ ์ค์ ํฌ์ธํธ ์ค์ ๋์น๊ฒ ์๋์ง ํ๋ฒ ํ์ธ ๋ถํ๋๋ ค๋ ๋ ๋ฐ์ง์?
- Likes
- 0
- Comments
- 6
- Viewcount
- 822
Q&A
batchInsert ๊ฐ ๊ฐ๋ฅํ์ง ๋ฌธ์๋๋ฆฝ๋๋ค.
๋ต๋ณ ๊ฐ์ฌํฉ๋๋ค ^^ ํ์ธํด ๋ณด๊ฒ ์ต๋๋ค ~~~
- Likes
- 0
- Comments
- 4
- Viewcount
- 543
Q&A
@OneToMany ์์ N+1 ๋ฌด์ ์ ํ์ด์ง ๋ฌธ์
๋ค^^ ๊ฐ์์๋ฃ ์ ๋ณด๊ณ ์์ต๋๋ค.
- Likes
- 0
- Comments
- 3
- Viewcount
- 398
Q&A
์ดํ๋ฆฌ์ผ์ด์ ์คํ์ ์ธํ ๋ฆฌ์ ์ด ์ฝ์์ ์ฐํ๋ sql statement๊ฐ 1์ค๋ก ๋์ค๋ ๋ฌธ์ !
datasource ๊ฐ 1๊ฐ์ธ ๊ฒฝ์ฐ yml ํ์ผ์๋ง ์ง์ ํ๋ฉด format_sql ๋ ์๋๊ณ default_batch_fetch_size ๋ ์ ๋๋๋ฐ์. ๋ฉํฐ datasource ๋ฅผ ์ฌ์ฉ์ค์ด๋ผ JPAConfig ํด๋์ค๋ฅผ ๋ง๋ค์ด์ ์ฌ์ฉํ๋ฉด default_batch_fetch_size ํ๋กํผํฐ๋ ์๋ properties ์ ๊ฐ์ ๋ฃ์ผ๋ฉด ๋๋๋ฐ์. format_sql ์ ์๋จน๋ค์ ???? -> yml ํ์ผ์ ๋ฑ๋กํด๋ ์๋์ default_batch_size ๋ ์๋ ์์ฑ๊ฐ์ ์ถ๊ฐํ๋๊น ๋์๋๋ฐ์. format_sql ์ ์๋๋ค์.. package kr.co.korbit.demo;:::@Configuration@EnableTransactionManagement@EnableJpaRepositories( entityManagerFactoryRef = "jpaEntityManagerFactory", transactionManagerRef = "jpaTransactionManager", basePackages = {"kr.co.korbit.demo.jpa.repository", "kr.co.korbit.demo.jpa.repository.custom", "kr.co.korbit.demo.jpa.repository.impl", "kr.co.korbit.demo.jpa.repository.querydsl"})public class JpaConfig { final String dialect = "org.hibernate.dialect.H2Dialect" ; String ddlAuto = "create" ; String showSql = "false" ; String formatSql = "true" ; String useNewIdGeneratorMappings = "false" ; String implicitStrategy = "org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy" ; String physicalStrategy = "org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy" ; @Autowired(required = false) private PersistenceUnitManager persistenceUnitManager; @Bean(name = "jpaDataSource") @ConfigurationProperties(prefix = "spring.datasource.demo") @Primary public DataSource jpaDataSource() { HikariDataSource dataSource = DataSourceBuilder.create().type(HikariDataSource.class).build() ; return dataSource ; } @Bean(name = "jpaEntityManagerFactoryBuilder") @Primary public EntityManagerFactoryBuilder jpaEntityManagerFactoryBuilder(){ HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter(); adapter.setShowSql(true); adapter.setPrepareConnection(true); adapter.setDatabase(Database.H2); adapter.setDatabasePlatform(dialect); adapter.setGenerateDdl(false); HashMap, String> properties = new HashMap, String>() ; properties.put("hibernate.ddl-auto", ddlAuto); properties.put("format_sql", "true"); properties.put("default_batch_size", "300"); properties.put("hibernate.naming.implicit-strategy", implicitStrategy); properties.put("hibernate.naming.physical-strategy", physicalStrategy); properties.put("hibernate.use-new-id-generator-mappings", useNewIdGeneratorMappings); EntityManagerFactoryBuilder builder = new EntityManagerFactoryBuilder( adapter, properties , this.persistenceUnitManager); return builder; } @Primary @Bean(name = "jpaEntityManagerFactory") public LocalContainerEntityManagerFactoryBean jpaEntityManagerFactory( @Qualifier("jpaEntityManagerFactoryBuilder") EntityManagerFactoryBuilder builder, @Qualifier("jpaDataSource") DataSource jpaDataSource) { LocalContainerEntityManagerFactoryBean factory = builder .dataSource(jpaDataSource) .packages("kr.co.korbit.demo.jpa.model") .persistenceUnit("demo") .build(); factory.setPackagesToScan("kr.co.korbit.demo.jpa.model") ; return factory ; } @Bean(name = "jpaTransactionManager") @Primary public PlatformTransactionManager jpaTransactionManager( @Qualifier("jpaEntityManagerFactory") EntityManagerFactory jpaEntityManagerFactory) { return new JpaTransactionManager(jpaEntityManagerFactory); } @Bean(name = "jpaQueryFactory") @Primary public JPAQueryFactory jpaQueryFactory(@Qualifier("jpaEntityManagerFactory") EntityManagerFactory jpaEntityManagerFactory) { return new JPAQueryFactory(jpaEntityManagerFactory.createEntityManager()) ; }}
- Likes
- 0
- Comments
- 3
- Viewcount
- 1.3K
Q&A
@OneToMany ์์ N+1 ๋ฌด์ ์ ํ์ด์ง ๋ฌธ์
@OneToMany ์ธ Collection join ์ธ๊ฒฝ์ฐ N+1 ์ด ์๋๋ผ 1 + 1 in (...) ์ฟผ๋ฆฌ๋ก ๋์ ์ต์ ํ๊ฐ ๊ฐ๋ฅํ๋ค๋๊ฑฐ์ฃ ? default_batch_fetch_size = 100 ์ผ๋ก ์ง์ ํ ๊ฒฝ์ฐ ํ์ด์ง๋ ๊ฐ๋ฅํ๊ณ 1+n -> 1+1 ๋ก ๋ณ๊ฒฝ...
- Likes
- 0
- Comments
- 3
- Viewcount
- 398
Q&A
fetch join ์ child table ์กฐ๊ฑด์ด ์ค์ ์ฟผ๋ฆฌ์ ๋ฐ์์ด ์๋๋ค์..
๋ฐ๋ชจ์ฉ์ผ๋ก ์ฌ์ฉํ์ ํ๋ก์ ํธ๋ฅผ ๊ณต์ ํด ์ฃผ์๋ฉด ์ ๊ฐ ํ ์คํธ ์ค์ธ ์ฝ๋๋ฅผ ์ข ๋ ์ฝ๊ฒ ๊ณต์ ํ ์ ์์ ๊ฒ ๊ฐ์ต๋๋ค. ํน์ ๊ฐ๋ฅํ์ค๋ฐ์ง์?
- Likes
- 0
- Comments
- 6
- Viewcount
- 822
Q&A
fetch join ์ child table ์กฐ๊ฑด์ด ์ค์ ์ฟผ๋ฆฌ์ ๋ฐ์์ด ์๋๋ค์..
@EntityGraph(attributePaths = ["quizList"])@Query(value = "select q " + " from LneQuest q INNER JOIN q.quizList qz where 1=1 " + " and (:type is null or q.type = :type) " + " and (:from is null or :from + " and (:to is null or q.createdAt , countQuery = "select count(q)" + " from LneQuest q where 1=1 " + " and (:type is null or q.type = :type) " + " and (:from is null or :from + " and (:to is null or q.createdAt , nativeQuery = false)fun findAllByJpql(@Param("type")type: String?, @Param("from")from: LocalDateTime?, @Param("to")to: LocalDateTime?, pageable: Pageable): Page val jpql = selectFrom(lneQuest) .innerJoin(lneQuest.quizList, lneQuiz) .fetchJoin() .where( WhereBuilder() .optionalAnd(from, { lneQuest.createdAt.after(from) }) .optionalAnd(to, { lneQuest.createdAt.before(to) }) .optionalAnd(type, { lneQuest.type.eq(type) }) ) .orderBy(*ordable(pageable.sort).toTypedArray())val countJpql = selectFrom(lneQuest) .where( WhereBuilder() .optionalAnd(from, { lneQuest.createdAt.after(from) }) .optionalAnd(to, { lneQuest.createdAt.before(to) }) .optionalAnd(type, { lneQuest.type.eq(type) }) )return applyPagination(pageable, jpql, countJpql) ์๋ ํ์ธ์ ๋ต๋ณ ์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค. ๋ฌธ์ ๋๋ฆฌ๊ณ ์ถ์ ๋ถ๋ถ๋ค์ ์ ๋ฆฌํด์ github ์ ๋ฐ๋ชจ๋ก ๋ง๋ค์ด์ ์ด์๋ฅผ ํ์ธ๋ฐ๊ณ ์ถ์๋ฐ, ์ ์๋๋ค์.... ;;; qz.type = :type ์ผ๋ก ์กฐ๊ฑด์ ๊ฑธ ์ ์๋ ๋ฐฉ๋ฒ์ด ์๋ค๋ฉด ์ถ๊ฐ๋ก ์๋ ค์ฃผ์๋ฉด ๊ฐ์ฌํ๊ฒ ์ต๋๋ค. (Querydsl ๋๋ JPQL ์ด๋ ธํ ์ด์ ์ฟผ๋ฆฌ ๋ชจ๋ ์๊ด์์ต๋๋ค) -> ๊ฐ๋ฅํ๋ฉด ์ ๋ H2 db ๋ก ํ ์คํธ ์ฝ๋ ํ๋ฒ ๋ง๋ค์ด์ ๊ณต์ ๋๋ฆฌ๋๋ก ํ๊ฒ ์ต๋๋ค. ๋๋ถ์ด ์ผ๋ฐ์ ์ธ @OneToMany ๋ฅผ QueryDsl FetchJoin ์ผ๋ก ์์ฑํด ๋ดค๋๋ฐ์ N+1 ๋ฌธ์ ๋ ์ ํด๊ฒฐ๋๋๋ฐ ํ์ด์ง ์ฒ๋ฆฌ๋ ์๋์ ํน์ ๋ฐฉ๋ฒ์ด ์๋์ง์? -> ์๋๋ฉด FetchJoin ์์๋ ๊ตฌ์กฐ์ ์ผ๋ก ํ์ด์ง ์ฒ๋ฆฌ๊ฐ ์๋๋์ง์? .fetchJoin() ์ ์ ๊ฑฐํ๋ฉด N+1 ๋ฌธ์ ๊ฐ ๋ฐ์ํ์ง๋ง ํ์ด์ง ์ฒ๋ฆฌ์ Sort ๋ ๋ชจ๋ ์ ๋ฉ๋๋ค. JPQL @Query ์ด๋ ธํ ์ด์ ๋ Runtime ์ Syntax ์ฒดํฌ๋ฅผ ํด์ฃผ๊ธด ํด์ฃผ๋๋ผ๊ตฌ์... QueryDsl ์ ๊ฒฝ์ฐ์๋ Syntax ์ฒดํฌ๊ฐ ์ธ์ด ๋ ๋ฒจ์์ ๋๋ ์ ์ด ๋ ํธํ ๊ฒ ๊ฐ๊ธด ํฉ๋๋ค๋ง, ๋ณต์กํ ์ฟผ๋ฆฌ์ ๊ฒฝ์ฐ QueryDsl ๋ก ์์ฑํ๋๊ฒ ๋ ๊ฒ์ฆ์ด๋ ์ ์ง๋ณด์๊ฐ ๋ ํธ๋ฆฌํ ๊น์? (์ํฐํ๋ผ์ด์ฆ ์ํฉ์์์)
- Likes
- 0
- Comments
- 6
- Viewcount
- 822




