我知道标题可能听起来有些混乱,但我不知道如何总结我的标题问题。
我的主要问题是我不想使用PagingAndSortingRepository返回特定的列。想象一下以下场景:
我有两个实体,一个名为Users:
@Entity
@Table(name = "users")
public class User implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotBlank()
@Column(name = "name")
private String name;
@Column(name = "password")
private String password;
}
一个叫汽车:
@Entity
@Table(name = "car")
public class Car implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@NotBlank()
@Column
private String name;
@ManyToOne(targetEntity = User.class, fetch = FetchType.EAGER, cascade = CascadeType.MERGE)
@JoinColumn(name = "owner_id", referencedColumnName = "id")
private User owner;
}
我想使用PagingAndSortingRepository按用户名返回汽车列表。使用以下界面我可以实现:
public interface CarRepository extends PagingAndSortingRepository<Car, Long> {
List<Car> findByOwner_name(String name);
}
然而,通过所述界面,结果还将返回用户的密码。我可以在列表的每个元素上使用for并将密码设置为null,但在有大量汽车的用户的情况下会很麻烦。我怎么能这样做,以便列表的结果带有特定的列,密码,对用户没有任何价值?
提前致谢=)。
ps:我想过返回一个投影列表而不是一个Car列表,但是我不知道如何对投影说这个类中的一个属性应为null。
答案 0 :(得分:3)
为此,您需要使用Projections
。详细记录了here
创建一个界面,其中包含要包含在要返回的实体中的字段 例如,在您的情况下,它就像这样
interface CarSummary {
String getName();
Long getId();
UserSummary getUser();
interface UserSummary {
String getName();
Long getId();
}
}
并像这样修改您的存储库
public interface CarRepository extends PagingAndSortingRepository<Car, Long> {
Collection<CarSummary> findByOwner_name(String name);
}
答案 1 :(得分:1)
可以递归使用投影。这样的事情应该有效:
interface CarPojection{
Long getId();
String getName();
UserSummary getUser();
interface UserSummary {
Long getId();
String getName();
}
}
您的存储库应该返回CarPojection
在Spring docs中查找更多信息:
https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#projections
答案 2 :(得分:1)
您可以通过在实体类中提供匹配的构造函数来返回数据的子集。
@Query("select new com.foo.bar.entity.User(u.id, u.name) from User u where u.name = ?1")
List<User> findByOwner_name(String name);
在您的班级User
中,只需提供构造函数,其他属性将保留null
:
public User(Long id, String name) {
// ...
}