项目档案

向Hibernate添加Spring数据

在上一组讲义中,我介绍了Hibernate,我们看到了如何构造一组Entity类来为存储在拍卖数据库中的对象建模。我还展示了示例代码,演示了如何使用EntityManager将对象移进和移出数据库。

在这节课中,我们将使用Spring Data框架来简化对数据库的访问。我们仍将使用实体类,但不再直接使用EntityManager对象。

使用Spring数据存储库

Spring Data是一个框架,旨在使处理各种不同类型的数据存储变得更容易。在本例中,我将使用Spring Data与关系数据库进行交互。在后面的讲座中,我们将看到如何使用相同的Spring Data机制与NoSQL数据库交互的示例。

Spring Data中的数据访问是通过使用Spring Data存储库对象来管理的。在一个使用关系数据库的项目中,Spring Data希望我们为数据库中的每个表创建一个存储库。

这里有一个非常简单的例子。拍卖数据库中的一个表是出价表,我们将在其中存储出价对象。下面是我们将用来访问该表的Spring Data存储库的代码:

BidRepository扩展jparerepository <Bid,Integer> {}

这里有一些关于这段代码的注意事项:

教科书在第7章讨论了JpaRepository接口。您也可以在此界面上在线查找文档。

JpaRepository接口包含许多有用的方法,但在某些情况下,我们可能需要用一些自定义方法来补充该接口。下面是一个简单的例子:这是我们将用来与users表交互的存储库:

UserRepository扩展JpaRepository<User,UUID>{List<User> findByName(String name);}

这个示例显示了一个自定义查找方法的示例。当Spring Data为这个接口生成一个类时,它将根据我们提供的名称自动构造这个方法的代码。本例将搜索用户表以查找具有特定名称的赢博体育用户。

Spring Data可以仅根据方法的名称自动生成范围广泛的自定义方法。您可以在第七章中阅读更多关于Spring Data自动代码生成的内容。

最后,尽管jparerepository中的内置方法和自动方法生成技术将允许我们处理几乎赢博体育我们需要做的事情,但是在一些不寻常的情况下,我们将需要构造自定义代码。为了实现这一点,Spring Data还允许我们构造自定义查询。

这里有一个例子。在购买过程中,我们将需要运行许多自定义查询来定位购买过程中特定步骤的Purchase记录。下面是处理Purchase对象的存储库:

public interface PurchaseRepository extends JpaRepository<Purchase,UUID>{@Query("select p from Purchase p where p.status='Won_bid' and p.bid.bidder.userid=:user") List<Purchase> findOffers(UUID user);@查询("select p from Purchase p where p.status='Confirmed' and p.bid.auction.seller.userid=:user") List<Purchase> findSales(UUID user);@查询("select p from Purchase p where p.status=‘已收费’ and p.bid.bidder.userid=:user") List<Purchase> findBills(UUID user);@查询("select p from Purchase p where p.status='Paid' and p.bid.auction.seller.userid=:user") List<Purchase> findSoldBills(UUID user);@查询("select p from Purchase p where p.status=‘已收费’ and p.bid.bidder.userid=:user") List<Purchase> findShippedBills(UUID user);}

在每一种情况下,我都用包含一些JPQL代码的@Query注释了一个自定义查找方法。当Spring Boot生成与此接口配套的类时,它将自动为每个方法生成代码,这些代码将执行我们提供的JPQL查询。

在这个示例中,您还可以看到每个查询都具有占位符。为了确保在查询运行时正确地填充这些占位符,我们设置了方法参数,该方法将使用这些参数为占位符提供值。最重要的是,参数名与我们希望与之匹配的JPQL占位符的名称相匹配。

从DAO类到Service类

这些存储库现在将为我们提供对我们需要的数据库的赢博体育访问。这也意味着我们将不再构造DAO类来管理数据库交互。

以前的DAO类为我们做了一件新存储库类不能做的事情,那就是为我们的赢博体育程序管理赢博体育程序逻辑。例如,当用户想要向系统发布一个新的user对象时,我们必须检查以确保系统中没有具有相同用户名的user。

为了给这个赢博体育程序逻辑一个归宿,我们将用服务类来补充存储库类。服务类将与存储库通信,而控制器则只与服务类通信。新版本的项目有UserService、AuctionService和purchasesservice类。控制器类已经全部重写,以便与新的服务类一起工作。

下面是其中一个新服务类的代码示例。下面是将一个新用户插入系统的方法。

@Service公共类UserService {@Autowired PasswordService;@Autowired UserRepository;public String save(UserDTO用户){List< user > existing = userRepository.findByName(user. getname ());if(exists .size() >) return "Duplicate";用户newUser =新用户();newUser.setName (user.getName ());String hash = passwordService.hashPassword(user.getPassword());newUser.setPassword(散列);userRepository.save(列出);.toString返回newUser.getUserid () ();}}