本文是使用@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进行搜索,仍然可以使用 。
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/