我有 2 个有关 Spring Data JPA (3.2) 存储库的问题。我的背景是 .Net c#,最近开始使用 Java,所以请原谅我缺乏知识。在 .Net 中,我们有像 Dapper 和 Petapoco (Npoco) 这样的 miro ORM,它们有一个单一的数据库工厂,所以你可以说“.save< MyObjectType >(object)”等。
我看到 Sprint Data JPA 每个实体都需要它自己的存储库,这很好,但我想知道是否有更好的(标准化)方法来做到这一点。以下是我的问题。
由于我使用的是“ICrudBaseRepository”,所以连接将是单一连接吗?所以我可以在一个方法中引用多个存储库(如下面的“SaveGames”),并且它只会使用一个连接?
我知道我的布局与标准 Spring 模板有点不同,但总的来说,我希望我的存储库像存储库服务一样,而我的实际 CRUD 存储库位于“CrudRepositories”下。基本上,我希望任何引用存储库(称为数据库)的内容都从我的服务层中抽象出来。正如您所看到的,我必须注入我的“GameRepository”服务使用的每个存储库,我想知道是否有更好(更标准化)的方法来处理注入所有这些(也许是制作通用包装器的一种方法) .
注意:我知道还有其他 ORM,如 Mybatis、JDBI 等,但我不想做任何复杂的数据库工作,并且想要最现代/标准的 CRUD 操作方式,所以最终选择了 spring-data-jpa .
预先感谢您的任何反馈。
是的,如果您在调用各种存储库的方法上方使用 @Transactional 注释,它将把所有内容包装在一个事务下(下面的示例)。这对我来说表明这也是一种单一的联系。我并不为此特别需要一个基本的 JPA 存储库,但我还是使用了一个。
public class GameRepository extends BaseRepository implements IGameRepository
{
private IGameDB _gameDB;
private ILevelDB _levelDB;
public GameRepository(IGameDB gameDB, ILevelDB levelDB) {
_gameDB = gameDB;
_levelDB = levelDB;
}
@Transactional(rollbackFor = { Exception.class })
public void SaveGames(List<Game> games, List<Level> levels)
{
for (Game game : games)
{
var gameLevels = levels.stream().filter(x -> x.gameid == game.id).collect(Collectors.toList());
_levelDB.saveAll(gameLevels);
_gameDB.save(game);
}
}
}
我觉得这个设计很好,也很有意义。就像上面的示例一样,您经常会在一种方法中调用多个 jpa 存储库(如复杂的对象保存)。将该层作为实际的“存储库”,然后将 jpa 存储库放在它们自己的文件夹/命名空间中是有意义的。我喜欢引用我的数据库的所有内容都从我的存储库层到 jpa 存储库。下面是我的布局。