简体   繁体   English

如何在 spring 引导 JPA 中获得选择性列?

[英]How to get selective column in spring boot JPA?

I am new to spring boot.我是 spring 引导的新手。

I have two entities Invite and User.我有两个实体 Invite 和 User。

@Entity
public class Invite {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    
    @Column(name="email")
    private String email_id;
    private String mobile;
    private String pincode;
    private String name;
    private String status;
    private Date created_on;
    private Date updated_on;
 
    //gettes and setters
}


@Entity
public class User {
    @Id
    @GeneratedValue(strategy= GenerationType.IDENTITY)
    private int id;
    
    @OneToOne
    private Invite invite;
    private String firstName;
    private String LastName;
    @JsonIgnore
    private String password;
    private Date created_on;
    private Date updated_on;

    // getters and setters

}

I want the following data我想要以下数据

+---------+---------------------------------------------+
|  id     |   firstName    email_id         mobile      |
+-------------------+------------+----------------------+
|         |         |            |                      |
| 1       |Ram      | s@mail.com |      1111111111      |
|         |         |            |                      |
+---------+---------+------------+----------------------+

So I have created the below query in UserRepository:所以我在 UserRepository 中创建了以下查询:

@Repository
public interface UserRepository extends JpaRepository<User, Integer> {

    
    @Query("select u.id,u.firstName,i.email_id, i.mobile from User u inner join u.invite i")
    public List<User> getUserDetails();
}

So I am getting the below error -所以我收到以下错误 -

Failed to convert from type [java.lang.Object[]] to type [@org.springframework.data.jpa.repository.Query com.example.jpa.JPA.entity.User] for value

I know it's because the return value is of type Object and I am trying to get it into user.我知道这是因为返回值的类型是 Object 并且我正试图将其输入用户。

Could you please give me a way to get any data without creating extra DTO classes or interface?您能否给我一种在不创建额外 DTO 类或接口的情况下获取任何数据的方法?

Its great you already know what the issue is.太好了,您已经知道问题所在。

@Query("select u.id,u.firstName,i.email_id, i.mobile from User u inner join u.invite i")
List<User> getUserDetails();

You are selecting a few columns but asking Data-Jpa to return you back with the a List of User Objects.您正在选择几列,但要求 Data-Jpa 将用户对象列表返回给您。

So you need to understand first, what JPA specification says about using JPQL.所以你需要首先了解,JPA 规范中关于使用 JPQL 的内容。

  • select u from User u where u.id =:id -> this returns a List of User type Objects This query in native is: SELECT * FROM USER WHERE ID = "{whatever value you passed}"; select u from User u where u.id =:id -> 这将返回一个User类型对象列表 本机查询是: SELECT * FROM USER WHERE ID = "{whatever value you passed}";

  • select u.username from User u where u.id =:id" -> this returns just the username, which lets say is a String type. So the return object type is of the String type in case you using TypedQuery or Object is returned in case you using Query . The corresponding SQL generated is SELECT u.USERNAME FROM USER u WHERE u.id = {id} select u.username from User u where u.id =:id" -> 这仅返回用户名,可以说是 String 类型。因此返回 object 类型是 String 类型,以防您使用TypedQuery或 Z49720345B5991514AC5A如果您使用Query . 生成的相应 SQL 是SELECT u.USERNAME FROM USER u WHERE u.id = {id}

  • select u.id, u.username from User u where u.id =:id -> this returns Object[]. select u.id, u.username from User u where u.id =:id -> 这返回 Object[]。 This is when you need the DTO projection to map it to a proper Type of what you want.这是您需要将 DTO 投影到 map 的时候,它是您想要的正确类型。

With native JPA implementations you can use DTO Projection or Query Projection使用本机 JPA 实现,您可以使用DTO 投影查询投影

I mostly use DTO Projection from JPA spec ad not use Query Projection, so I am giving an example of DTO projection, but above documents if gone through gives a good reference how to work with each abstraction/feature.我主要使用 JPA 规范中的 DTO 投影而不使用查询投影,所以我给出了 DTO 投影的示例,但是如果通过上述文档,可以很好地参考如何使用每个抽象/功能。

  1. Define a class to represent the DTO and package I am taking into consideration: com.example.定义一个 class 来表示 DTO 和 package 我正在考虑:com.example。 Package name is important since you need the full class name for reference in JPQL Package 名称很重要,因为您需要完整的 class 名称以供在 JPQL 中参考
package com.example;


class UserDTO {
 int id;
 String firstName,
 String email_id;
 String mobile;

 //All args constructor is needed and madatory
public User(int id, String firstName, String email_id, String mobile) {
 // assignments
}
  // getters and setters
}

In the Repository:在存储库中:

@Query("select new com.example.UserDTO(u.id,u.firstName,i.email_id, i.mobile) from User u inner join u.invite i")
List<UserDTO> getUserDetails();

The most important thing being: new fully-qualifed-classname(all columns you are fetching)最重要的是:新的完全限定类名(您正在获取的所有列)

This is how you use DTO projection with JPQL and Data Jpa Repository.这就是您如何将 DTO 投影与 JPQL 和数据 Jpa 存储库一起使用。

Write a constructor in User class for your selective column and use in query.User class 中为您的选择列编写一个构造函数并在查询中使用。 Make sure you are also using a constructor in Invite class for email_id and mobile and use it inside constructor in User.确保您还在Invite class 中为email_idmobile使用构造函数,并在 User 的构造函数中使用它。

@Query("select new com.example.jpa.JPA.entity.User(u.id,u.firstName,i.email_id, i.mobile) from User u inner join u.invite i")
public List<User> getUserDetails();

Use this constructor in User and Invite class在用户中使用此构造函数并邀请 class

public User(int id, String firstName, String email_id, String mobile) {
 // assign id and firstName
 // call invite class constuctor 
}

public Invite(String email_id, String mobile) {
 // assign email_id and mobile
}

If you want to have selected fields in query result or customize query result, you can simply use jpa Projection .如果您想在查询结果中选择字段或自定义查询结果,您可以简单地使用jpa Projection create an interface with related property method创建具有相关属性方法的接口

try this..this work for me: spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.DefaultNamingStrategy try this..this work for me: spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.DefaultNamingStrategy

this is to be added in application.properties这将被添加到 application.properties

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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