如何在Spring Boot中使用Hibernate Natural ID

本文详细介绍了如何在Spring Boot应用中使用Hibernate的Natural ID功能。从编写带有自然ID的实体开始,接着阐述如何创建NaturalRepository接口和其实现,然后设置NaturalRepositoryImpl作为存储库基类。通过示例展示了如何通过自然ID查找和保存实体,同时讨论了支持多个自然ID的情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先,让我们关注所需类的实现。完成所有这些后,我们将能够为具有自然ID的实体提供存储库。

用自然ID编写实体

让我们考虑以下具有自动生成ID和自然ID(code列)的实体。这只是一个使用一个自然ID的典型实体@NaturalId

@实体
public  class  Product  implements  Serializable {

 
    private  static  final  long  serialVersionUID  =  1L ;

 
    @ID
    @GeneratedValue(策略 =  GenerationType。IDENTITY)
    私人  身份 ;

 
    私有 字符串 名称 ;

 
    @NaturalId(mutable  =  false
    @Column(nullable  =  false,updatable  =  false,unique  =  true,length  =  50
    私有 字符串 代码 ;

 
    // getter和setter

 
    @覆盖
    public  boolean  equals(Object  o){
        ifthis  ==  o){
            返回 true ;
        }
        if(!(o  instanceof  Product)){
            返回 false ;
        }
        产品 naturalIdProduct  =(产品)o ;
        返回 对象。等于(引用代码(),naturalIdProduct。引用代码());
    }

 
    @覆盖
    public  int  hashCode(){
        返回 对象。hash(getCode());
    }

 
    @覆盖
    public  String  toString(){
        返回 “Product {”  +  “id =”  +  id  +  “,name =”  +  name  +  “,code =”  +  code  +  '}' ;
    }
}

编写NaturalRepository合同

我们首先编写一个名为的接口NaturalRepository。基本上,当我们想要微调存储库时,我们可以依赖  @NoRepositoryBean注释。在我们的例子中,我们想要用另外两个来丰富Spring Data方法库,  findBySimpleNaturalId()并且findByNaturalId() :

@NoRepositoryBean
public  interface  NaturalRepository < T,ID  extends  Serializable >  extends  JpaRepository < T,ID > {

 
    //当您的实体具有使用@NaturalId注释的单个字段时,请使用此方法
    可选< T >  findBySimpleNaturalId(ID  naturalId);

 
    //当您的实体具有多个使用@NaturalId注释的字段时,请使用此方法
    可选< T >  findByNaturalId(Map < StringObject >  naturalIds);        
}

编写NaturalRepository实现

此外,我们扩展了SimpleJpaRepository 类并实现了NaturalRepository。通过扩展,SimpleJpaRepository我们可以通过添加我们需要的方法来定制基本存储库。主要是,我们扩展了特定于持久性技术的存储库基类,并将此扩展用作存储库代理的自定义基类:

@Transactional(readOnly  =  true
public  class  NaturalRepositoryImpl < T,ID  扩展 Serializable >
        扩展 SimpleJpaRepository < T,ID >  实现 NaturalRepository < T,ID > {

 
    private  final  EntityManager  entityManager ;

 
    公共 NaturalRepositoryImpl(JpaEntityInformation  entityInformation,
            EntityManager  entityManager){
        super(entityInformation,entityManager);

 
        这个。entityManager  =  entityManager ;
    }

 
    @覆盖
    public  Optional < T >  findBySimpleNaturalId(ID  naturalId){

 
        可选< T >  entity  =  entityManager。解包(会话。
                。bySimpleNaturalId(。getDomainClass())
                。loadOptional(naturalId);

 
        回报 实体 ;
    }

 
    @覆盖
    public  Optional < T >  findByNaturalId(Map < StringObject >  naturalIds){

 
        NaturalIdLoadAccess < T >  loadAccess
                =  entityManager。解包(会话。)。byNaturalId(。getDomainClass());
        naturalIds。forEach(loadAccess :: using);

 
        return  loadAccess。loadOptional();
    }

 
}

将NaturalRepositoryImpl设置为基类

接下来,我们必须指示Spring Data依赖于我们的自定义存储库基类。在Java配置中,您可以repositoryBaseClass通过@EnableJpaRepositories注释使用该属性来执行此操作  :

@SpringBootApplication
@EnableJpaRepositories(repositoryBaseClass  =  NaturalRepositoryImpl。
公共  NaturalIdApplication {
    ...
}

让我们看看它是如何工作的

现在,让我们看看它是否按预期工作。首先,让我们定义ProductRepository

@Repository
public  interface  ProductRepository < T,ID >  extends  NaturalRepository < Product,Long > {    
}

一个自然身份证

此外,让我们保存两个具有唯一代码(自然ID)的产品:

产品 tshirt  =   产品();
T恤。setName(“T-Shirt”);
T恤。setCode(“014-tshirt-2019”);

 
产品 袜子 =   产品();
袜子。setName(“袜子”);
袜子。setCode(“012-socks-2018”);

 
productRepository。保存(T 恤);
productRepository。保存(袜子);

最后,让我们通过它的自然ID 找到T-Shirt产品:

//这应该返回包装在Optional中的T恤产品
可选< Product >  tshirt  =  productRepository。findBySimpleNaturalId(“014-tshirt-2019”);

注意:productRepository.findById(Object id)如果要按自动生成的ID进行搜索,仍可以使用  。

更多自然ID

实体可以使用多个自然ID。例如,让我们假设code 我们旁边还有  sku自然ID:

@NaturalId(mutable  =  false
@Column(nullable  =  false,updatable  =  false,unique  =  true
私人  sku ;

现在,当我们坚持我们的产品时,它们将如下所示:

产品 tshirt  =   产品();
T恤。setName(“T-Shirt”);
T恤。setCode(“014-tshirt-2019”);
T恤。setSku(1L);

 
产品 袜子 =   产品();
袜子。setName(“袜子”);
袜子。setCode(“012-socks-2018”);
袜子。setSku(2L);

 
productRepository。保存(T 恤);
productRepository。保存(袜子);

找到T恤产品可以这样做:

Map < StringObject >  ids  =  new  HashMap <>();
ids。put(“code”“014-tshirt-2019”);
ids。put(“sku”1L);

 
可选< Product >  tshirt  =  productRepository。findByNaturalId(ids);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值