【问题标题】:Spring Boot JPA how to select specific column from table with the entity class?Spring Boot JPA如何使用实体类从表中选择特定列?
【发布时间】:2020-01-14 13:37:19
【问题描述】:

我正在使用 Spring Boot JPA 进行数据库操作。在我的实体类中,我用我的表映射了每一列。在我的表中,我有很多列,但我需要在查询结果集中选择其中一些。我不需要这样做select * from table_name,这会给我的应用程序带来性能问题。

我的实体类:

@Entity
@Table(name = "user_table")
public class UserInformation {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "user_id")
    private int userId;

    @Column(name = "user_name")
    private String userName;

    @Column(name = "user_type")
    private String userType;

    @Column(name = "user_age")
    private int userAge;

    @Column(name = "is_male")
    private boolean isMale;
}

在此之后,我为上述类生成了所有 getter 和 setter。

我的 userDAO 类

public interface UserInformationRepo extends 
         JpaRepository<UserInformation, String>{

    @Query(value="select user_name from user_table where user_age > 
               :userAge", nativeQuery=true)
    public UserInformation getInfo(int userAge);\

    @Query(value="select user_name,userType, user_id  from user_table where 
          user_age > :userAge", nativeQuery=true)
    public UserInformation getInfo(int userAge);
}

当我使用上面的类运行这个 Spring Boot 应用程序时,它显示错误为

user_id 未包含在结果集中

这个错误是因为我没有从我的查询中选择 user_id。

在我的 userDAO 类中我有多个函数,每个函数需要不同的列集,但所有方法的返回类型应该是 UserInformation 类。

我的例外结果是,我没有从查询中选择的列在我的结果 UserInformation 对象中应该有空值。

我也为此搜索了很多资源,但我找不到任何相关的答案。

任何帮助。提前致谢

【问题讨论】:

  • 如何获取 3 列并期望创建整个对象?
  • @Andronicus 是的,但这些值可能为空。
  • 粘贴完整的日志以更好地了解确切的错误。

标签: java spring spring-boot jpa spring-data-jpa


【解决方案1】:

user_id 是您的 UserInformation 对象中的主键。最好在 Query 中包含 UserInformation 对象中的所有列:

public interface UserInformationRepo extends 
         JpaRepository<UserInformation, String>{

    @Query(value="select * from user_table where user_age > 
               :userAge", nativeQuery=true)
    public UserInformation getInfo(int userAge);
    @Query(value="select *  from user_table where 
          user_age > :userAge", nativeQuery=true)
    public UserInformation getInfo(int userAge);

        }

如果你的 user_table 有大量信息,你可以只列出你关心的列,但一定要包括@Id(主键)。

【讨论】:

  • 感谢您的回答。好的,我可以在我的选择语句中包含主键,但在必要之前我不应该选择其他列。
  • 尽量避免过早优化。半格式的 UserInformation 对象可能是几个月后调试的噩梦 - 特别是如果用于检索用户列表的查询与以后使用该 User 对象的方式分离时。
  • 是否有必要在我的选择语句中包含主键,如果不需要,我可以删除我的其余列​​。
  • 我猜是的 - 您看到的错误是由于缺少查询中的主键。
  • 即使我包含了主键,它仍显示为错误,因为结果集中未包含其他列。
【解决方案2】:

为实体创建投影时最简单的解决方案(仅包含必要的属性):

public interface UserInformationNameProjection {
  String getUserName();
}

然后你可以这样定义repository方法(你甚至不需要id!):

@Query(value="select user_name from user_table where user_age > 
           :userAge", nativeQuery=true)
public UserInformationNameProjection getInfo(int userAge);

让 Spring Data JPA 完成剩下的工作。 :)

【讨论】:

    【解决方案3】:

    一种方法是使用userIduserName 创建UserInformation 的构造函数。

    package com.demo.model;
    
    public UserInformation( String userName, String userType, String userId){
        this.userName = userName;
        this.userType = userType;
        this.userId = userId;
    }
    

    然后

     @Query(value="select new com.demo.model.UserInformation
                   (user_name,userType, user_id)  
                    from user_table where 
                    user_age > :userAge", nativeQuery=true)
    

    【讨论】:

    • 感谢您的回答。空的构造函数将这些字段是否足够或者我必须在构造函数内部生成getter和setter..
    • 我没有从上面的 sql 查询中理解新的 valid.java.package.path.to.UserInformation。可以举个例子解释一下吗
    • 感谢您的回答。我仍然得到同样的错误。它显示在结果集中找不到 user_age..
    • 这对我不起作用。它将错误显示为“。”附近的 Synax 错误。在查询语句的行。
    • 而且您将两个参数传递给 UserInformation 构造函数,但这些数据类型不同,例如 sql 中的 user_name 必须为 varchar,而构造函数中的 user_name 必须是字符串。这给我抛出了一个错误“错误:函数样本(字符变化,字符变化,没有时区的时间戳,字符变化,字符变化)不存在”并且它还显示“提示:没有函数与给定的名称和参数类型匹配。您可能需要添加显式类型转换。”
    猜你喜欢
    • 2021-08-17
    • 2018-07-22
    • 2017-05-21
    • 2014-03-27
    • 1970-01-01
    • 2020-04-04
    • 1970-01-01
    • 2020-07-04
    相关资源
    最近更新 更多