本文是使用@NaturalIdSpring Data样式的Hibernate NaturalID()的快速实用指南。主要是,我们要公开的休眠,bySimpleNaturalId()并byNaturalId()通过典型的Spring数据存储库的方法,并把它们准确地叫我们称之为众所周知,findAll(),findOne(),等等。
Implementation 首先,让我们专注于所需类的实现。完成所有这些操作后,我们将能够为具有自然ID的实体提供存储库。
编写具有自然ID的实体 让我们考虑以下具有自动生成的ID和自然ID(该code列)的实体。这只是通过@NaturalId以下方式使用一个自然ID的典型实体:
@Entity public class Product implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; private String name; @NaturalId(mutable = false) @Column(nullable = false, updatable = false, unique = true, length = 50) private String code; // getters and setters @Override public boolean equals(Object o) { if (this == o) { return true; } if (!(o instanceof Product)) { return false; } Product naturalIdProduct = (Product) o; return Objects.equals(getCode(), naturalIdProduct.getCode()); } @Override public int hashCode() { return Objects.hash(getCode()); } @Override public String toString() { return "Product{" + "id=" + id + ", name=" + name + ", code=" + code + '}'; } }
编写NaturalRepository合同 我们首先编写一个名为的接口NaturalRepository。基本上,当我们要微调存储库时,我们可以依靠 @NoRepositoryBean注释。在我们的例子中,我们希望有两个,以丰富的春节数据的方法武库, findBySimpleNaturalId()并且findByNaturalId() :
@NoRepositoryBean public interface NaturalRepository<T, ID extends Serializable> extends JpaRepository<T, ID> { // use this method when your entity has a single field annotated with @NaturalId Optional<T> findBySimpleNaturalId(ID naturalId); // use this method when your entity has more than one field annotated with @NaturalId Optional<T> findByNaturalId(Map<String, Object> naturalIds); }
编写NaturalRepository实现 此外,我们扩展SimpleJpaRepository 类并实现NaturalRepository。通过扩展,SimpleJpaRepository我们可以通过添加所需的方法来自定义基础存储库。主要是,我们扩展了特定于持久性技术的存储库基类,并将此扩展用作存储库代理的自定义基类:
@Transactional(readOnly = true) public class NaturalRepositoryImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID> implements NaturalRepository<T, ID> { private final EntityManager entityManager; public NaturalRepositoryImpl(JpaEntityInformation entityInformation, EntityManager entityManager) { super(entityInformation, entityManager); this.entityManager = entityManager; } @Override public Optional<T> findBySimpleNaturalId(ID naturalId) { Optional<T> entity = entityManager.unwrap(Session.class) .bySimpleNaturalId(this.getDomainClass()) .loadOptional(naturalId); return entity; } @Override public Optional<T> findByNaturalId(Map<String, Object> naturalIds) { NaturalIdLoadAccess<T> loadAccess = entityManager.unwrap(Session.class).byNaturalId(this.getDomainClass()); naturalIds.forEach(loadAccess::using); return loadAccess.loadOptional(); } }
将NaturalRepositoryImpl设置为基类 接下来,我们必须指示Spring Data依赖于我们自定义的存储库基类。在Java配置中,您可以repositoryBaseClass通过@EnableJpaRepositories注释使用属性 :
@SpringBootApplication @EnableJpaRepositories(repositoryBaseClass = NaturalRepositoryImpl.class) public class NaturalIdApplication { ... }
让我们看看它是如何工作的 现在,让我们看看它是否按预期工作。首先,让我们定义ProductRepository:
@Repository public interface ProductRepository<T, ID> extends NaturalRepository<Product, Long>{ }
One Natural ID 此外,让我们保存两个具有唯一代码(自然ID)的产品:
Product tshirt = new Product(); tshirt.setName("T-Shirt"); tshirt.setCode("014-tshirt-2019"); Product socks = new Product(); socks.setName("Socks"); socks.setCode("012-socks-2018"); productRepository.save(tshirt); productRepository.save(socks);
最后,让我们通过其自然ID查找T恤产品:
// this should return the t-shirt product wrapped in an Optional Optional<Product> tshirt = productRepository.findBySimpleNaturalId("014-tshirt-2019");
注意:productRepository.findById(Object id)如果您要按自动生成的ID进行搜索,仍然可以使用 。
productRepository.findById(Object id)
More Natural IDs 一个实体可以使用多个自然ID。例如,假设code 我们旁边也有 sku自然ID:
@NaturalId(mutable = false) @Column(nullable = false, updatable = false, unique = true) private Long sku;
现在,当我们坚持使用我们的产品时,它们将如下所示:
Product tshirt = new Product(); tshirt.setName("T-Shirt"); tshirt.setCode("014-tshirt-2019"); tshirt.setSku(1L); Product socks = new Product(); socks.setName("Socks"); socks.setCode("012-socks-2018"); socks.setSku(2L); productRepository.save(tshirt); productRepository.save(socks);
查找T恤产品可以这样完成:
Map<String, Object> ids = new HashMap<>(); ids.put("code", "014-tshirt-2019"); ids.put("sku", 1L); Optional<Product> tshirt = productRepository.findByNaturalId(ids);
原文链接:https://codingdict.com/