简体   繁体   中英

how to set the findAll() on springboot to only return one column of it's foreign key's table

I'm working on a database with multiple relations, how can I return only the table I need and some of its columns instead of what findAll() returns which is the table the related table and tables related to that one and so on.

What I'm getting is something along the lines of:

{
    "id":1 ,
    "title": "foo",
    "writer": {
       "id":6,
       "name": "name",
       "group": {
         "id":3,
         "name":"group"
       }
    }
}

how can i get something like this:

{
  "id":1 ,
  "title": "foo",
  "writer": {
    "name": "name",
   }
}

Should I use jpql? Otherwise, what's the best approach.

One possibility would be relying on JPQL for this. Assuming that your entity class is called Article it would be something in the line of:

@Query("select article.id, article.title from Article article")
List<Article> getAllArticlesOptimized();

You can read more about this at https://www.appsdeveloperblog.com/specific-columns-jpa-native-query/ .


Another possibility would be Projections so that you can selectively retrieve partial views of your entities. You would declare an interface that exposes accessor methods for the properties to be read:

interface ArticleSummary {

  Long getId();
  String getTitle();
  WriterSummary getWriter();

  interface WriterSummary {
    String getName();
  }
}

And you would use it as the return type in your repository:

interface ArticleRepository extends Repository<Article, Long> {
  List<ArticleSummary> findAll();
}

You can use native-query and ResultTransformer :


    @PersistenceContext
    private EntityManager entityManager;

    @Override
    public Optional<ArticleDTO> getArticle(final long id) {
        final Session sess = entityManager.unwrap(Session.class);
        return sess.createNativeQuery(
            "select a.id, a.title, w.name from Article a left outer join Writer w on a.writer_id = w.id where a.id = :id")
            .setParameter("id", id)
            .addScalar("id", LongType.INSTANCE)
            .addScalar("name", StringType.INSTANCE)
            .addScalar("title", StringType.INSTANCE)
            .setResultTransformer(new ArticleResultTransformer())
            .uniqueResultOptional();
    }

    public static class ArticleResultTransformer extends BasicTransformerAdapter {
        @Override
        public Object transformTuple(final Object[] tuple, final String[] aliases) {
            final Optional<String> writerName = Optional.ofNullable((String) tuple[2]);
            final WriterDTO writer = writerName.map(name -> new WriterDTO(name)).orElse(null);

            return new ArticleDTO((Long) tuple[0], (String) tuple[1], writer);
        }
    }

See also :

Hibernate supports both entity queries (JPQL/HQL and Criteria API) and native SQL statements. Entity queries are useful only if you need to modify the fetched entities, therefore benefiting from the automatic dirty checking mechanism.

For read-only transactions, you should fetch DTO projections because they allow you to select just as many columns as you need to fulfill a certain business use case. This has many benefits like reducing the load on the currently running Persistence Context because DTO projections don't need to be managed.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM