Spring Boot JPA原生查询对象映射

huangapple go评论76阅读模式
英文:

Spring Boot JPA Native Query Object Mapping

问题

以下是翻译好的部分:

"I have a Model called CommunityProfile. This model contains two child relationships; player (type User), and rank (type Rank)."

"我有一个名为CommunityProfile的模型。这个模型包含两个子关系:player(类型为User)和rank(类型为Rank)。"

"The default spring boot JPA-generated query is taking approximately 9s to fetch 200 records, which is rather slow. By using the following MySQL query, I can return the data I need rather quickly:"

"Spring Boot JPA生成的默认查询大约需要9秒来获取200条记录,这相当慢。通过使用以下的MySQL查询,我可以更快地获取我需要的数据:"

"How can I make my repository map the results to their correct Objects/Models?"

"如何让我的存储库将结果映射到它们正确的对象/模型?"

"I have tried using a non-native query, like this:"

"我尝试使用非本地查询,就像这样:"

"However, this is still quite slow in comparison, resulting in an 800-900ms response. For comparison, my current Laravel application can return the same data in a 400-ms cold start."

"然而,与此相比,它仍然相当慢,导致响应时间在800-900毫秒之间。相比之下,我的当前Laravel应用程序在冷启动时可以在400毫秒内返回相同的数据。"

"Any tips are appreciated, thank you"

"感谢任何建议,谢谢"

"==UPDATE=="

"==更新=="

"After trying the suggested @Index annotation, I still don't really see any performance gains. Did I implement correctly?"

"在尝试了建议的@Index注释后,我仍然没有看到任何性能提升。我实现得正确吗?"

@Entity
@Table(name = "community_profiles", indexes = @Index(name = "cp_ci_idx", columnList = "community_id"))
public class CommunityProfile {
@Entity
@Table(name = "community_profiles", indexes = @Index(name = "cp_ci_idx", columnList = "community_id"))
public class CommunityProfile {
英文:

I have a Model called CommunityProfile. This model contains two child relationships; player (type User), and rank (type Rank).

The default spring boot JPA-generated query is taking approximately 9s to fetch 200 records, which is rather slow. By using the following MySQL query, I can return the data I need rather quickly:

SELECT cp.*, r.*, u.* FROM community_profiles cp
LEFT JOIN users u ON cp.player_id = u.id
LEFT JOIN ranks r ON cp.rank_id = r.id 
WHERE cp.community_id = 1

How can I make my repository map the results to their correct Objects/Models?

I have tried using a non-native query, like this:

    @Query("SELECT cp FROM CommunityProfile cp " +
            "LEFT JOIN FETCH cp.player u " +
            "LEFT JOIN FETCH cp.rank r " +
            "WHERE cp.communityId = :communityId")
    List<CommunityProfile> findByCommunityIdWithJoin(@Param("communityId") Integer communityId);

However, this is still quite slow in comparison, resulting in an 800-900ms response. For comparison, my current Laravel application can return the same data in a 400-ms cold start.

Any tips are appreciated, thank you

==UPDATE==

After trying the suggested @Index annotation, I still don't really see any performance gains. Did I implement correctly?

@Entity
@Table(name = "community_profiles", indexes = @Index(name = "cp_ci_idx", columnList = "community_id"))
public class CommunityProfile {

答案1

得分: 1

If your JPA query is working, and you are just asking about performance, you may add the following index:

CREATE INDEX idx ON community_profiles(community_id);

This index should allow MySQL to filter off records which are not part of the result set.

From JPA itself you may use:

@Table(indexes = @Index(name = "idx", columnList = "community_id"))
public class CommunityProfile {
    // ...
}
英文:

If your JPA query is working, and you are just asking about performance, you may add the following index:

<!-- language: sql -->

CREATE INDEX idx ON community_profiles(community_id);

This index should allow MySQL to filter off records which are not part of the result set.

From JPA itself you may use:

<!-- language: java -->

@Table(indexes = @Index(name = &quot;idx&quot;, columnList = &quot;community_id&quot;))
public class CommunityProfile {
    // ...
}

答案2

得分: 0

Have you tried EntityManager

       @PersistenceContext(type = PersistenceContextType.TRANSACTION)
             private EntityManager entityManager;

            List&lt;CommunityProfile&gt; findByCommunityIdWithJoin(Integer communityId){
              String query = &quot;&quot;SELECT cp FROM CommunityProfile cp &quot; +
                    &quot;LEFT JOIN FETCH cp.player u &quot; +
                    &quot;LEFT JOIN FETCH cp.rank r &quot; +
                    &quot;WHERE cp.communityId = :communityId&quot;
            List&lt;CommunityProfile&gt; list = entityManager.createNativeQuery(query, CommunityProfile.class)
                            .setParameter(&quot;communityId&quot;,communityId)
                            .getResultList();
           entityManager.clear();
           return list
        }

Once I used this kind of native query inside loop and it constantly returned cash values bu entityManagaer.clear() clears cash. This is for info only)

Or create an Index on specific columns when you are defining entity classes like:

  @Table(indexes = {
  @Index(columnList = &quot;firstName&quot;),
  @Index(name = &quot;fn_index&quot;, columnList = &quot;firstName&quot;),
  @Index(name = &quot;mulitIndex1&quot;, columnList = &quot;firstName, lastName&quot;)
  ...
}

For Non-entity @Index you can check documentation

英文:

Have you tried EntityManager

       @PersistenceContext(type = PersistenceContextType.TRANSACTION)
             private EntityManager entityManager;

            List&lt;CommunityProfile&gt; findByCommunityIdWithJoin(Integer communityId){
              String query = &quot;&quot;SELECT cp FROM CommunityProfile cp &quot; +
                    &quot;LEFT JOIN FETCH cp.player u &quot; +
                    &quot;LEFT JOIN FETCH cp.rank r &quot; +
                    &quot;WHERE cp.communityId = :communityId&quot;
            List&lt;CommunityProfile&gt; list = entityManager.createNativeQuery(query, CommunityProfile.class)
                            .setParameter(&quot;communityId&quot;,communityId)
                            .getResultList();
           entityManager.clear();
           return list
        }

Once I used this kind of native query inside loop and it constantly returned cash values bu entityManagaer.clear() clears cash. This is for info only)

Or create an Index on specific columns when you are defining entity classes like:

  @Table(indexes = {
  @Index(columnList = &quot;firstName&quot;),
  @Index(name = &quot;fn_index&quot;, columnList = &quot;firstName&quot;),
  @Index(name = &quot;mulitIndex1&quot;, columnList = &quot;firstName, lastName&quot;)
  ...
}

For Non-entity @Index you can check documentation

huangapple
  • 本文由 发表于 2023年2月14日 06:53:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/75441935.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定