代码之家  ›  专栏  ›  技术社区  ›  user2870934

Spring数据JPA JDBC语句疯狂[重复]

  •  0
  • user2870934  · 技术社区  · 7 年前

    我有一个简单的实体:

    @Entity
    @Table(name = "dish_type")
    class DishType : Serializable {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        var id: Long = -1
        var name: String? = null
        var description: String? = null
        @OneToMany(mappedBy = "dishType")
        var dishTypeLocales: List<DishTypeLocale>? = null
    }
    
    @Entity
    @Table(name = "dish_type_locale")
    class DishTypeLocale : Serializable {
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        var id: Long = -1
    
        @Enumerated(EnumType.STRING)
        var locale: LocaleString? = null
        var value: String? = null
    
        @ManyToOne
        @JoinColumn(name = "dish_type_id")
        var dishType: DishType? = null
    }
    

    DAO:

    interface DishTypeService {
        fun findAll(withLocale: Boolean): List<DishTypeDto>
    }
    
    @Service
    @Transactional
    open class DishTypeServiceImpl(private val dishTypeRepository: DishTypeRepository) : DishTypeService {
    
        override fun findAll(withLocale: Boolean): List<DishTypeDto> {
            return this.dishTypeRepository.findAll().map { DishTypeDto(it, withLocale) }
        }
    
    }
    
    @Repository
    interface DishTypeRepository : JpaRepository<DishType, Long>
    

    DTO:

    class DishTypeDto {
        var id: Long = -1
        var description: String? = null
        var locale: List<DefaultLocalizationDto>? = null
    
        constructor()
    
        constructor(dishType: DishType, withLocale: Boolean) {
            this.id = dishType.id
            this.description = dishType.description
            if (withLocale) {
                this.locale = dishType.dishTypeLocales?.map { DefaultLocalizationDto(it) }
            }
        }
    
        override fun toString(): String {
            return "DishTypeDto{" +
                    "id=" + id +
                    ", description='" + description + '\'' +
                    '}'
        }
    }
    
    
    class DefaultLocalizationDto {
        var locale: Int? = null
        var name: String? = null
        var description: String? = null
    
        constructor()
    
        constructor(locale: DishTypeLocale) {
            this.locale = locale.locale?.code
            this.name = locale.value
        }
    
        override fun toString(): String = "DefaultLocalizationDto(locale=$locale, name=$name, description=$description)"
    }
    

    如果 DishTypeService.findAll(false) 我们向DB提交了1份声明:

    Session Metrics {
        6789040 nanoseconds spent acquiring 1 JDBC connections;
        0 nanoseconds spent releasing 0 JDBC connections;
        146499 nanoseconds spent preparing 1 JDBC statements;
        3929488 nanoseconds spent executing 1 JDBC statements;
        0 nanoseconds spent executing 0 JDBC batches;
        0 nanoseconds spent performing 0 L2C puts;
        0 nanoseconds spent performing 0 L2C hits;
        0 nanoseconds spent performing 0 L2C misses;
        0 nanoseconds spent executing 0 flushes (flushing a total of 0 entities and 0 collections);
        43774 nanoseconds spent executing 1 partial-flushes (flushing a total of 0 entities and 0 collections)
    }
    

    如果 DishTypeService.findAll(true) 语句==表。尺寸(在我的案例中为282):

    Session Metrics {
        11570010 nanoseconds spent acquiring 1 JDBC connections;
        0 nanoseconds spent releasing 0 JDBC connections;
        4531164 nanoseconds spent preparing 282 JDBC statements;
        60280410 nanoseconds spent executing 282 JDBC statements;
        0 nanoseconds spent executing 0 JDBC batches;
        0 nanoseconds spent performing 0 L2C puts;
        0 nanoseconds spent performing 0 L2C hits;
        0 nanoseconds spent performing 0 L2C misses;
        0 nanoseconds spent executing 0 flushes (flushing a total of 0 entities and 0 collections);
        60464 nanoseconds spent executing 1 partial-flushes (flushing a total of 0 entities and 0 collections)
    }
    

    如何告诉Spring在1中获取所有数据(ok mb 2-3语句)?

    @OneToMany(mappedBy = "dishType", fetch = FetchType.EAGER)
    var dishTypeLocales: List<DishTypeLocale>? = null
    

    渴望无助

    我知道,我可以删除 dishTypeLocales 从…起 DishType 通过两种不同的方法获得全部 dishTypes 然后全部 dishTypeLocales ,然后在代码中映射它们,但mb有更好的方法吗?

    我正在使用:

        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.0.RELEASE</version>
    

    DB:Postgresql 9.6

    1 回复  |  直到 7 年前
        1
  •  3
  •   Arnold Galovics    7 年前

    您正在经历延迟加载关系,这是 OneToMany 关系。

    这里有4个选项:

    1. 为关系设置渴望加载(我知道你写道,你已经尝试过了,但它不起作用,但相信我,它起作用了。你可能只是遇到了另一个问题)
    2. 使用 FETCH JOIN 加载实体和关系。为此,您必须使用以下查询(草稿)在存储库中编写自定义方法: SELECT dt FROM DishType dt JOIN FETCH dt.dishTypeLocales
    3. 使用Spring Data JPA的功能, Fetch/LoadGraph
    4. 使用 projections 因为这是一个只读操作。最好避免在读取数据时使用实体,只有在修改数据时才使用实体。