如何在Spring Boot JPA中获取特定列?

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

How to get selective column in spring boot JPA?

问题

以下是您要翻译的内容:

我是Spring Boot的新手。

我有两个实体 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;

    //getters 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
}

我想要以下数据:

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

因此,我在 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();
}

因此,我得到以下错误:

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

我知道这是因为返回值的类型是 Object 数组,而我试图将其转换为 User。

请问您能否提供一种在不创建额外 DTO 类或接口的情况下获取任何数据的方法?

英文:

I am new to spring boot.

I have two entities Invite and User.

@Entity
public class Invite {

	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private int id;
	
	@Column(name=&quot;email&quot;)
	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:

@Repository
public interface UserRepository extends JpaRepository&lt;User, Integer&gt; {

	
	@Query(&quot;select u.id,u.firstName,i.email_id, i.mobile from User u inner join u.invite i&quot;)
	public List&lt;User&gt; 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.

Could you please give me a way to get any data without creating extra DTO classes or interface?

答案1

得分: 5

很好,你已经知道问题所在。

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

你选择了几列,但要求 Data-Jpa 返回一个 User 对象的列表。

所以你首先需要理解 JPA 规范关于使用 JPQL 的内容。

  • select u from User u where u.id = :id -> 这将返回一个 User 类型对象的列表。
    该查询在原生 SQL 中是:SELECT * FROM USER WHERE ID = "{传入的任何值}";

  • select u.username from User u where u.id = :id" -> 这只返回用户名,假设用户名是字符串类型。因此,返回对象类型是 String 类型,如果您使用 TypedQuery,或者如果您使用 Query,则返回的是 Object。相应生成的 SQL 是 SELECT u.USERNAME FROM USER u WHERE u.id = {id}

  • select u.id, u.username from User u where u.id = :id -> 这将返回 Object[]。当您需要 DTO 投影以将其映射到您想要的适当类型时使用。

通过原生的 JPA 实现,您可以使用 DTO 投影查询投影

我通常使用 JPA 规范中的 DTO 投影,不使用查询投影,因此我提供了一个 DTO 投影的示例,但是上述文档如果阅读过会对如何使用每个抽象/特性提供很好的参考。

  1. 定义一个表示 DTO 的类,我考虑的包名是:com.example。包名很重要,因为您需要完整的类名来在 JPQL 中引用
package com.example;

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

 // 必须有全参构造函数
 public UserDTO(int id, String firstName, String email_id, String mobile) {
     // 赋值操作
 }
  // getters 和 setters
}

在 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();

最重要的是:new 完整的类名(您检索的所有列)

这就是您如何使用 JPQL 和 Data Jpa Repository 进行 DTO 投影。

英文:

Its great you already know what the issue is.

@Query(&quot;select u.id,u.firstName,i.email_id, i.mobile from User u inner join u.invite i&quot;)
List&lt;User&gt; getUserDetails();

You are selecting a few columns but asking Data-Jpa to return you back with the a List of User Objects.

So you need to understand first, what JPA specification says about using 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 = &quot;{whatever value you passed}&quot;;

  • select u.username from User u where u.id = :id&quot; -> 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.id, u.username from User u where u.id = :id -> this returns Object[]. This is when you need the DTO projection to map it to a proper Type of what you want.

With native JPA implementations you can use DTO Projection or Query Projection

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.

  1. Define a class to represent the DTO and package I am taking into consideration: com.example. Package name is important since you need the full class name for reference in 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(&quot;select new com.example.UserDTO(u.id,u.firstName,i.email_id, i.mobile) from User u inner join u.invite i&quot;)
List&lt;UserDTO&gt; 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.

答案2

得分: 1

User类中编写一个构造函数,用于选择性地初始化列,并在查询中使用。确保在Invite类中也使用了一个构造函数来初始化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();

// 在User类和Invite类中使用这个构造函数

public User(int id, String firstName, String email_id, String mobile) {
    // 分配id和firstName
    // 调用Invite类的构造函数
}

public Invite(String email_id, String mobile) {
    // 分配email_id和mobile
}

这是翻译好的部分,不包含额外的内容或问题回答。

英文:

Write a constructor in User class for your selective column and use in query. Make sure you are also using a constructor in Invite class for email_id and mobile and use it inside constructor in User.

@Query(&quot;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&quot;)
public List&lt;User&gt; getUserDetails();

Use this constructor in User and Invite 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
}

答案3

得分: 1

如果您想在查询结果中仅选择特定字段或自定义查询结果,您可以简单地使用JPA投影(Projection)。创建一个带有相关属性方法的接口。

英文:

If you want to have selected fields in query result or customize query result, you can simply use jpa Projection. create an interface with related property method

答案4

得分: -1

尝试这个...这对我有效:
spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.DefaultNamingStrategy

这个需要添加到application.properties中。

英文:

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

this is to be added in application.properties

huangapple
  • 本文由 发表于 2020年8月16日 13:46:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/63433549.html
匿名

发表评论

匿名网友

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

确定