Java 8流中的数据库CRUD操作

在开始使用新工具时要克服的最大障碍是让您着手处理小事情。 到目前为止,您可能对新的Java 8 Stream API的工作方式充满信心,但是您可能尚未将其用于数据库查询。 为了帮助您开始使用Stream API创建,修改和读取SQL数据库,我整理了此快速入门。 希望它可以帮助您将信息流提升到一个新的水平!

背景

Speedment是一个开源工具包 ,可用于生成Java实体和管理器以与数据库进行通信。 使用图形工具,您可以连接到数据库并生成一个完整的ORM,量身定制以代表您的域模型。 但是Speedment不仅是代码生成器,还是插入应用程序的运行时,并可以将Java 8流转换为优化的SQL查询。 这是我将在本文中重点介绍的部分。

产生程式码

要开始在Maven项目中使用Speedment,请将以下行添加到pom.xml文件中。 在此示例中,我使用的是MySQL,但您也可以使用PostgreSQL或MariaDB。 企业客户可以使用Oracle等专有数据库的连接器。

pom.xml

<properties>
  <speedment.version>3.0.1</speedment.version>
  <db.groupId>mysql</db.groupId>
  <db.artifactId>mysql-connector-java</db.artifactId>
  <db.version>5.1.39</db.version>
</properties>

<dependencies>
  <dependency>
    <groupId>com.speedment</groupId>
    <artifactId>runtime</artifactId>
    <version>${speedment.version}</version>
    <type>pom</type>
  </dependency>
        
  <dependency>
    <groupId>${db.groupId}</groupId>
    <artifactId>${db.artifactId}</artifactId>
    <version>${db.version}</version>
  </dependency>
</dependencies>

<build>
  <plugins>
    <plugin>
      <groupId>com.speedment</groupId>
      <artifactId>speedment-maven-plugin</artifactId>
      <version>${speedment.version}</version>

      <dependencies>
        <dependency>
          <groupId>${db.groupId}</groupId>
          <artifactId>${db.artifactId}</artifactId>
          <version>${db.version}</version>
        </dependency>
      </dependencies>
    </plugin>
  </plugins>
</build>

现在,您可以访问许多新的Maven目标,这些目标使使用工具包变得更加容易。 启动Speedment UI,执行:

mvn speedment:tool

这将指导您完成连接数据库和配置代码生成的过程。 开始时最简单的方法就是您与默认设置一起运行。 一旦按下“ Generate”,Speedment将分析您的数据库元数据,并用诸如实体和经理类之类的新资源填充您的项目。

初始化速度

生成域模型后,轻松设置Speedment。 创建一个新的Main.java文件并添加以下行。 您看到的所有类都是生成的,因此它们的名称将取决于数据库模式,表和列的名称。

Main.java

public class Main {
  public static void main(String... param) {
    final HaresApplication app = new HaresApplicationBuilder()
      .withPassword("password")
      .build();
  }
}

上面的代码使用生成的生成器模式创建一个新的应用程序实例。 使用该构建器可以设置任何运行时配置详细信息,例如数据库密码。

有了应用程序实例后,就可以使用它来访问生成的管理器。 在这种情况下,数据库中有四个表。 “野兔”,“胡萝卜”,“人”和“朋友”。 (您可以在此处查看整个数据库定义 )。

final CarrotManager carrots = app.getOrThrow(CarrotManager.class);
final HareManager hares     = app.getOrThrow(HareManager.class);
final HumanManager humans   = app.getOrThrow(HumanManager.class);
final FriendManager hares   = app.getOrThrow(FriendManager.class);

这些管理器现在可以用来执行我们的所有CRUD操作。

创建实体

创建实体非常简单。 我们使用生成的实体实现,为列设置所需的值,然后将其持久化到数据源。

hares.persist(
  new HareImpl()
    .setName("Harry")
    .setColor("Gray")
    .setAge(8)
);

persist方法返回一个(可能)新的Hare实例,其中已设置了自动生成的键(例如“ id”)。 如果我们要在持久化Harry后再使用Harry,则应使用由persist返回的实例。

final Hare harry = hares.persist(
  new HareImpl()
    .setName("Harry")
    .setColor("Gray")
    .setAge(8)
);

如果持久性失败(例如,如果外键或唯一约束失败),则抛出SpeedmentException。 如果有什么阻止我们坚持野兔,我们应该检查并显示错误。

try {
  final Hare harry = hares.persist(
    new HareImpl()
      .setName("Harry")
      .setColor("Gray")
      .setAge(8)
  );
} catch (final SpeedmentException ex) {
  System.err.println(ex.getMessage());
  return;
}

读取实体

Speedment运行时中最酷的功能是可以使用Java 8 Streams流化数据库中的数据。 “为什么这么酷?” 你可能会问自己。 “如今,即使Hibernate也支持流 !”

Speedment流的美丽之处在于,在构造流时,它们考虑了中介和终止操作。 这意味着,如果在创建流之后向该流添加过滤器,则在构建SQL语句时仍将其考虑在内。

这是一个例子。 我们要计算数据库中的野兔总数。

final long haresTotal = hares.stream().count();
System.out.format("There are %d hares in total.%n", haresTotal);

将生成的SQL查询如下:

SELECT COUNT(*) FROM hares.hare;

终止操作是.count(),因此Speedment知道它是要创建的SELECT COUNT(…)语句。 还知道“ hare”表的主键是“ id”列,这使得将发送给数据库的整个语句缩减到此范围内成为可能。

一个更复杂的示例可能是查找名称以字母“ rry”结尾且年龄大于或等于5的野兔数量。可以这样写:

final long complexTotal = hares.stream()
  .filter(Hare.NAME.endsWith("rry"))
  .filter(Hare.AGE.greaterOrEqual(5))
  .count();

我们使用Speedment为我们生成的谓词构建器来定义过滤器。 这使我们可以以编程方式分析流并将其简化为以下SQL语句:

SELECT COUNT(id) FROM hares.hare
WHERE hare.name LIKE CONCAT("%", ?)
AND hare.age >= 5;

如果我们向流添加无法优化Speedment的操作,它将像任何Java 8流一样被解析。 我们绝不仅限于使用生成的谓词构建器,它只是使流更有效。

final long inefficientTotal = hares.stream()
  .filter(h -> h.getName().hashCode() == 52)
  .count();

这将产生以下效率极低的语句,但仍将起作用。

SELECT id,name,color,age FROM hares.hare;

更新实体

更新现有实体的方式与读取和保留实体的方式非常相似。 在我们在管理器中调用update()方法之前,对实体的本地副本所做的更改不会影响数据库。

在这种情况下,我们采用了哈利先前创建的野兔,并希望将其颜色更改为棕色:

harry.setColor("brown");
final Hare updatedHarry = hares.update(harry);

如果更新被接受,管理员将返回新的野兔副本,因此在此之后我们应该继续使用该实例。 就像在“创建”示例中一样,更新可能会失败。 也许将颜色定义为“唯一”列,并且已经存在“棕色”兔子。 在这种情况下,将抛出SpeedmentException。

我们还可以通过将其与流组合来同时更新多个实体。 假设我们要将所有名为“哈利”的野兔都变成棕色。 在这种情况下,我们这样做:

hares.stream()
  .filter(Hare.NAME.equal("Harry"))
  .map(Hare.COLOR.setTo("Brown"))
  .forEach(hares.updater()); // Updates remaining elements in the Stream

我们还应该将其包装在try-catch中,以确保在约束失败时向用户发出警告。

try {
  hares.stream()
    .filter(Hare.NAME.equal("Harry"))
    .map(Hare.COLOR.setTo("Brown"))
    .forEach(hares.updater());
} catch (final SpeedmentException ex) {
  System.err.println(ex.getMessage());
  return;
}

移除实体

我们需要知道的最后一个CRUD操作是如何从数据库中删除实体。 这几乎与“更新”相同。 假设我们要删除所有10年以上的野兔。 然后,我们这样做:

try {
  hares.stream()
    .filter(Hare.AGE.greaterThan(10))
    .forEach(hares.remover()); // Removes remaining hares
} catch (final SpeedmentException ex) {
  System.err.println(ex.getMessage());
  return;
}

摘要

在本文中,您学习了如何在Maven项目中设置Speedment,以及如何使用Java 8 Streams从数据库创建,更新,读取和删除实体。 这只是Speedment可以做的所有事情的一小部分,但是它是开始弄脏双手的很好的介绍。 可以在GitHub-page上找到更多示例和更高级的用例。

直到下一次!

翻译自: https://www.javacodegeeks.com/2016/10/database-crud-operations-java-8-streams.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值