数据模型可能很棘手。建模可能更难。有时应该进入数据库表的信息不一定是我们想要输出到每段代码的信息。
和许多其他时候一样,Spring 来拯救。一个名为投影 的小功能可以帮助我们在普通界面中仅用几行就可以映射数据。
在本文中,我们将通过一个简单示例了解如何使用投影。
好的,让我们设置场景。假设我们有以下实体:
@Builder @Data @NoArgsConstructor @AllArgsConstructor @Entity @Table @EqualsAndHashCode(doNotUseGetters = true) @ToString(doNotUseGetters = true) public class User implements Serializable { @Id @SequenceGenerator(name = "user_seq", sequenceName = "user_seq") @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "user_seq") private Long id; @Basic private String username; @Basic private String salt; @Basic private String password; @Basic private String firstName; @Basic private String lastName; }
一些解释在这里可能会有帮助:让我们看一下注释。老实说,我很懒惰,所以 Lombok 正合我意。 Lombok 为我们提供了一种很好的声明方式来说明我们需要:
@Builder
)@Data
)@NoArgsConstructor
)@AllArgsConstructor
)equals()
和 hashCode()
,但请使用字段,而不是 getter (@EqualsAndHashCode(doNotUseGetters = true)
)toString()
;再次使用字段 (@ToString(doNotUseGetter = true)
)其余注释(@Entity
和 @Table
)是很好的旧 JPA。
是的,所以,我们有一个很好的实体。问题是什么?
让我们看看这个存储库:
@Repository public interface UserRepository extends JpaRepository<User, Long> { }
上面的代码为我们提供了一组最小的 CRUD 方法。一个是 getOne(Long id)
。很好,不是吗?
那么,正确答案必须是:视情况而定!为什么?因为这会返回整个实体,包括盐和散列密码。这是非常敏感的信息。特别是盐不应该被外界获取。
为了从生成的实体中获取此信息,我们将不得不做大量的手动工作。就在我的脑海里,我们应该: * 创建一个新的 bean * 实现一个映射器以从我们的实体到新的 bean也可能有多个结果。
值得庆幸的是,Spring安全了一天。一个名为投影 的小功能可以让我们以声明的方式定义映射。这样的界面看起来像这样:
public interface UserProjection { @Value("#{target.getUsername()}") String getUsername(); @Value("#{target.getFirstName()}") String getFirstName(); @Value("#{target.getLastName()}") String getLastName(); }
Spring 会将 target
替换为我们当前正在处理的实体。换句话说,target
将是 User
的一个实例。
我们现在唯一要做的就是这样:
@Repository public interface UserRepository extends JpaRepository<User, Long> { UserProjection findById(Long id); List<UserProjection> findAllUser(); }
现在,每次我们调用 findById()
时,我们都会得到一个 UserProjection
的实例。我们的盐或密码散列不可能泄露!更好的是,我们可以对具有多个结果的方法使用相同的过程。
我们可以使用 Spring Projections 节省大量代码和痛苦。 @Value()
定义可以根据我们的需要变得非常复杂。例如,在我当前的项目中,当我们将“有趣的”遗留数据库设计映射到更简单的数据模型时,这为我的团队节省了大量样板代码。
如果您想试一试,可以在 GitHub 上找到一个简单的示例应用程序。
标签2: Java教程地址:https://www.cundage.com/article/jcg-power-data-model-projections.html