Spring JDBC为具有值的列返回空值

Posted

技术标签:

【中文标题】Spring JDBC为具有值的列返回空值【英文标题】:Spring JDBC returning null values for columns with values 【发布时间】:2021-12-27 20:53:24 【问题描述】:

我对@9​​87654321@ 的体验很奇怪。 两个相似的查询返回不同的结果。当我在存储库中使用 @Query 时,如下所示,我返回了一些列,但其余列返回为 null。

@Repository
public interface StaffRepository extends CrudRepository<Staff, Long> 
    @Query(value = "select * FROM staff WHERE email = :email and deleted = false")
    Staff findStaffByEmail(String email);

返回:

Staff(id=2, firstName=null, middleName=null, lastName=null, email=geek@mail.com, password=$2a$10$sa.48mjYIYa/0Z9ck8J.ReYAxu8qzA062zUCUWZfYWs/h7BwTh28G, ntkenNo=null, phoneNumber=null, branch=Nairobi branch, roles=[], loginDisabled=false, emailVerified=false, deleted=false, failedLoginAttempts=0, createdAt=null, updatedAt=null)

但是当我使用jdbcTemplate.queryForMap 实现它时,如下所示,我得到正确的结果,所有列都有它们的值

Map<String, Object> map = jdbcTemplate.queryForMap("select * FROM staff WHERE email = ? and deleted = false", email);
        System.out.println(map);

返回:

id=2, firstName=John, middleName=Doe, lastName=Doesto, email=geek@mail.com, password=$2a$10$sa.48mjYIYa/0Z9ck8J.ReYAxu8qzA062zUCUWZfYWs/h7BwTh28G, ntkenNo=1234, phoneNumber=+14255550100, branch=Nairobi branch, roles=[], deleted=false, createdAt=2021-12-27 19:32:36.0, updatedAt=null, loginDisabled=false, emailVerified=false, failedLoginAttempts=0

我上面的代码可能有什么问题。

我正在使用 Mysql 数据库。

下面是映射不工作的Staff entity

package com.myapp.models;

import lombok.*;
import org.springframework.data.annotation.Id;
import org.springframework.data.relational.core.mapping.Table;

@Data
@Table("staff")
@Builder(toBuilder = true, builderClassName = "Builder")
@NoArgsConstructor
@AllArgsConstructor
public class Staff 
    @Id
    Integer id;
    Long bankId;
    String firstName, middleName, lastName, email, password, ntkenNo, phoneNumber, branch, roles;
    boolean loginDisabled, emailVerified, deleted;
    int failedLoginAttempts;
    String createdAt, updatedAt;

然而,这是一个具有相同定义和查询但工作正常的实体:

package com.myapp.models;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.Id;
import org.springframework.data.relational.core.mapping.Table;

@Data
@Table("sys_admins")
@Builder(toBuilder = true, builderClassName = "Builder")
@NoArgsConstructor
@AllArgsConstructor
public class SysAdmins 
    @Id
    Integer id;
    String name, email, password, role;

这是仓库查询:

package com.rmauth.repositories;

import com.rmauth.models.SysAdmins;
import org.springframework.data.jdbc.repository.query.Query;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface SysAdminsRepository extends CrudRepository<SysAdmins, Long> 

    @Query(value = "select * FROM sys_admins WHERE email = :email and deleted = false")
    SysAdmins findByEmail(String email);


我看不出为什么第一个不起作用。

【问题讨论】:

要映射到一个对象,映射必须正确,看起来映射不正确。我也不明白为什么你的Staff 实体的toString 应该与Map 实例的toString 相同。 @M.Deinum 请检查编辑,映射是正确的,除非有我没有注意到的错误 你正在使用 lombok 来生成东西。通常不是最好的想法。 AFAIK Spring Data JDBC 不适用于构建器,并且在使用构造函数时,参数的顺序很重要,您不知道返回 SQL 的顺序,因此它可能会将随机列映射到随机构造函数参数。我会避免使用 lombok,而只是自己编写一个普通的 DTO(或者只使用@Data,这样你就可以获得 Spring Data JDBC 可以用来正确设置列的 getter/setter)。 【参考方案1】:

正如 M. Deinum 所说。然而,映射失败是个问题,因为我想继续利用 Lombok 来简化 POJOS 的工作。我决定直接将jdbcTemplateBeanPropertyRowMapper 一起使用,而不是使用@Query,这需要我实现Mapper 类,从而增加样板代码。我只需要简单而动态的方法。

Staff staff =  jdbcTemplate.queryForObject("select * FROM staff WHERE email = ? and deleted = false", new BeanPropertyRowMapper<>(Staff.class), email);

【讨论】:

以上是关于Spring JDBC为具有值的列返回空值的主要内容,如果未能解决你的问题,请参考以下文章

在表中为每个数据库查找具有空值的列[关闭]

Spark 仅获取具有一个或多个空值的列

如何获取sql中给定行具有空值的列数?

如何获取数据集中具有空值的列的总数? [复制]

如何在 Spark/Scala 中查找具有许多空值的列

Spark数据框不添加具有空值的列