Java 8 Streams中的数据库CRUD操作

简介:


接触一个新工具的时候,刚开始要克服的最大障碍就是如何让你自己先尝试做出一个小东西来。现在你也许对 Java 8 中新的 Stream API 的运作方式在理解上比较自信,但你也许并没用它来进行过数据库查询操作。为了帮助你开始使用 Stream API 来对 SQL 数据库进行创建、修改和读取操作, 我已经在这个快速开始的教程中把它们整合到了一起。希望它能帮助你提升对流式API的使用水平!

背景

Speedment 是一个开放源代码的工具集,它可以被用来生成 Java 实体,并且能将我们同数据库的通信过程管理起来。你可以利用一个图形工具连接到数据库并生成出一套完整的 ORM 框架代码来表示域模型。但是 Speedment 不单单只是一个代码生成器而已,它还是一个能插入应用程序中的运行时程序,这样就有可能将你的 Java 8 流式代码翻译成优化过的SQL查询。这也是我将会在本文中专门讲述的一个部分。

生成代码

要在一个 Maven 工程中开始使用 Speedment,需要你将下面几行代码添加到你的 pom.xml 文件中。在本例中,我使用的是 MySQL,而你也可以选择使用 PostgreSQL 或者 MariaDB。面向于像Oracle这样的专有数据库可用于企业级客户。

Pom.xml


 
 
  1. <properties> 
  2.   <speedment.version>3.0.1</speedment.version> 
  3.   <db.groupId>mysql</db.groupId> 
  4.   <db.artifactId>mysql-connector-java</db.artifactId> 
  5.   <db.version>5.1.39</db.version> 
  6. </properties>  
  7. <dependencies> 
  8.   <dependency> 
  9.     <groupId>com.speedment</groupId> 
  10.     <artifactId>runtime</artifactId> 
  11.     <version>${speedment.version}</version> 
  12.     <type>pom</type> 
  13.   </dependency>  
  14.   <dependency> 
  15.     <groupId>${db.groupId}</groupId> 
  16.     <artifactId>${db.artifactId}</artifactId> 
  17.     <version>${db.version}</version> 
  18.   </dependency> 
  19. </dependencies>  
  20. <build> 
  21.   <plugins> 
  22.     <plugin> 
  23.       <groupId>com.speedment</groupId> 
  24.       <artifactId>speedment-maven-plugin</artifactId> 
  25.       <version>${speedment.version}</version>  
  26.       <dependencies> 
  27.         <dependency> 
  28.           <groupId>${db.groupId}</groupId> 
  29.           <artifactId>${db.artifactId}</artifactId> 
  30.           <version>${db.version}</version> 
  31.         </dependency> 
  32.       </dependencies> 
  33.     </plugin> 
  34.   </plugins> 
  35. </build> 

现在你可以访问到许多新的 Maven 资源库,它们能让你更加轻松的使用这个工具包。要启动 Speedment UI, 执行如下命令:


 
 
  1. mvn speedment:tool 

这样就会有一个过程引导你连接到数据库并对代码生成进行配置。一开始最简单的方法就是用默认的设置先跑起来再说。当你按下生成按钮“Generate,” Speedment 就会对你的数据库元数据进行分析,然后在你的工程中添加像实体和实体管理器这样的类。

初始化 Speedment

当你的域模型生成好了以后,Speedment 的设置就容易了。创建一个新的 Main.java 文件然后添加如下几行代码。你看到的类都是生成的,因此它们的命名都是根据数据库模式、表以及列的名称来决定的。

Main.java  

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

上面的代码创建了一个新的应用程序实体,它使用了一种生成的构造器模式。构造器是的对任何运行时配置细节的设置成为可能,例如数据库的密码。

当我们有了一个应用实体,就可以用它来访问生成的实体管理器了。在这里,我的数据库中有了四个表; “hare”, “carrot”, “human”, 以及 “friend”. (你可以在这里找到完整的数据库定义)。


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

现在这些实体管理器可以被用来执行所有的CRUD操作了。

创建实体

创建实体的方式非常直接。我们就使用实体生成的实现,把列的值设置好然后持久化到数据源就可以了。


 
 
  1. hares.persist(  
  2. new HareImpl()  
  3. .setName("Harry")  
  4. .setColor("Gray")  
  5. .setAge(8) 
  6.  ); 

persist 方法会返回一个 (潜在的) Hare 新实例,里面像“id”这种自动生成键已经设置好了。如果我们想在持久化之后继续使用 Harry, 那就可以使用 persist 方法返回的这个:


 
 
  1. final Hare harry = hares.persist(  
  2. new HareImpl()  
  3. .setName("Harry")  
  4. .setColor("Gray")  
  5. .setAge(8)  
  6. ); 

如果持久化操作失败了,例如如果有一个外键违反了唯一性约束,就会有一个 SpeedmentException 抛出。我们应该对此进行检查,如果有默写东西会阻止我们对这条 hare 记录进行持久化,就应该显示一条错误信息。


 
 
  1. try {  
  2. final Hare harry = hares.persist(  
  3. new HareImpl()  
  4. .setName("Harry")  
  5. .setColor("Gray")  
  6. .setAge(8)  
  7. );  
  8. } catch (final SpeedmentException ex) {  
  9. System.err.println(ex.getMessage());  
  10. return;  

读取实体

Speedment 运行时中最酷的功能特性就是能够使用 Java 8 的 Stream API对数据库中的数据进行流式操作。“为什么这样做会很酷呢?” 你可能会这样问你自己。“如今甚至Hibernate 都已经支持流式操作了!”这就是回答。

使用 Speedment 流式操作最美好的事情就是它们把构建流的中间和终止动作都考虑进去了。这就意味着如果你在流已经被创建之后添加一个过滤器进去,那么在构建 SQL 语句时这个过滤器也会被考虑进去。

下面是一个示例,我们想要计算数据库中 hare 记录的总数。


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

这段代码将会生成的SQL查询如下:


 
 
  1. SELECT COUNT(id) FROM hares.hare; 

这里的终止操作就是 .count() ,因此 Speedment 就知道是要创建一个 SELECT COUNT(…) 语句。它也知道 “hare”表的主键是“id”这个列,如此就有可能将发送给数据库的整个语句 减少到这个样子。

更加复杂的示例可能就是找出名称以 “rry” 并且年龄大于等于 5 的兔子的数量。这个可以这样写:


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

我们使用由 Speedment 为我们生成的位于构建器来定义过滤器。这使得我们以编程的方式对流进行分析并且将其简化到如下这样一条SQL语句成为可能:


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

如果我们添加了一个 Speedment 不可以对流进行优化的操作, 它就会像一般的 Java 8 流那被处理。我们永远都不会限制生成的位于构建器的使用,它能是流式操作更加的高效。


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

上述代码会产生一条如下极其低效的语句,但是它仍然可以跑起来。


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

更新实体

更新存在的实体和读取以及持久化实体非常相似。在我们调用update()方法之前,对实体本地拷贝的改变,不会影响数据库内容。

下面,我们拿到之前使用Hare创建的Harry,并将他的颜色变为棕色:


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

如果更新被接受了,那么管理器会返回hare的一个新的拷贝,因为我们在后面会继续使用这个实例。就想做“创建”的例子中,更新可能会失败。也许颜色被定义为“值唯一”,棕色已经存在于hare中。那样的话,会抛出一个SpeedmentException异常.

我们也可以通过合并多个实体到一个流中来同时更新他们。加入我们想将所有名字为Harry的hare变为棕色,我们可以这样做:


 
 
  1. hares.stream()  
  2. .filter(Hare.NAME.equal("Harry")) 
  3. .map(Hare.COLOR.setTo("Brown"))  
  4. .forEach(hares.updater()); // 更新流中存在的元素 

我们还应该使用try-catch语句来确保在运行过程中有失败发生时警告用户。


 
 
  1. try {  
  2. hares.stream()  
  3. .filter(Hare.NAME.equal("Harry"))  
  4. .map(Hare.COLOR.setTo("Brown"))  
  5. .forEach(hares.updater());  
  6. } catch (final SpeedmentException ex) {  
  7. System.err.println(ex.getMessage());  
  8. return
  9.  } 

实体删除

我们需要知道的最后一个 CRUD 操作就是从数据库中删除实体。这个操作几乎和“更新”操作时等同的。假如说我们要把年龄超过10岁的兔子的记录都删除,就要这样做:


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

总结

通过阅读本文你已经了解了如何在一个 Maven 工程中对 Speedment 进行设置,还有如何使用 Java 8 的 Stream API 来从数据库中创建、更新、读取以及删除实体。这是你可以利用 Speedment 所能进行的操作的一个小的子集, 但已经是一个能让你上手的好的开始了。更多的示例以及更加高级的使用场景可以在GitHub-page上找到。


作者:佚名

来源:51CTO

相关文章
|
负载均衡 算法 关系型数据库
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
本文聚焦 MySQL 集群架构中的负载均衡算法,阐述其重要性。详细介绍轮询、加权轮询、最少连接、加权最少连接、随机、源地址哈希等常用算法,分析各自优缺点及适用场景。并提供 Java 语言代码实现示例,助力直观理解。文章结构清晰,语言通俗易懂,对理解和应用负载均衡算法具有实用价值和参考价值。
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
|
NoSQL Java API
在Java环境下如何进行Redis数据库的操作
总的来说,使用Jedis在Java环境下进行Redis数据库的操作,是一种简单而高效的方法。只需要几行代码,就可以实现复杂的数据操作。同时,Jedis的API设计得非常直观,即使是初学者,也可以快速上手。
528 94
|
XML Java 数据库连接
性能提升秘籍:如何高效使用Java连接池管理数据库连接
在Java应用中,数据库连接管理至关重要。随着访问量增加,频繁创建和关闭连接会影响性能。为此,Java连接池技术应运而生,如HikariCP。本文通过代码示例介绍如何引入HikariCP依赖、配置连接池参数及使用连接池高效管理数据库连接,提升系统性能。
347 5
|
人工智能 JavaScript 关系型数据库
【02】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-ui设计图figmaUI设计准备-figma汉化插件-mysql数据库设计-优雅草卓伊凡商业项目实战
【02】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-ui设计图figmaUI设计准备-figma汉化插件-mysql数据库设计-优雅草卓伊凡商业项目实战
614 14
【02】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-ui设计图figmaUI设计准备-figma汉化插件-mysql数据库设计-优雅草卓伊凡商业项目实战
|
人工智能 JavaScript 安全
【01】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-需求改为思维导图-设计数据库-确定基础架构和设计-优雅草卓伊凡商业项目实战
【01】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-需求改为思维导图-设计数据库-确定基础架构和设计-优雅草卓伊凡商业项目实战
1144 13
【01】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-需求改为思维导图-设计数据库-确定基础架构和设计-优雅草卓伊凡商业项目实战
|
Java 关系型数据库 MySQL
Java汽车租赁系统源码(含数据库脚本)
Java汽车租赁系统源码(含数据库脚本)
736 4
|
存储 缓存 Java
java语言后台管理ruoyi后台管理框架-登录提示“无效的会话,或者会话已过期,请重新登录。”-扩展知识数据库中密码加密的方法-问题如何解决-以及如何重置若依后台管理框架admin密码-优雅草卓伊凡
java语言后台管理ruoyi后台管理框架-登录提示“无效的会话,或者会话已过期,请重新登录。”-扩展知识数据库中密码加密的方法-问题如何解决-以及如何重置若依后台管理框架admin密码-优雅草卓伊凡
2721 3
java语言后台管理ruoyi后台管理框架-登录提示“无效的会话,或者会话已过期,请重新登录。”-扩展知识数据库中密码加密的方法-问题如何解决-以及如何重置若依后台管理框架admin密码-优雅草卓伊凡
|
前端开发 JavaScript Java
[Java计算机毕设]基于ssm的OA办公管理系统的设计与实现,附源码+数据库+论文+开题,包安装调试
OA办公管理系统是一款基于Java和SSM框架开发的B/S架构应用,适用于Windows系统。项目包含管理员、项目管理人员和普通用户三种角色,分别负责系统管理、请假审批、图书借阅等日常办公事务。系统使用Vue、HTML、JavaScript、CSS和LayUI构建前端,后端采用SSM框架,数据库为MySQL,共24张表。提供完整演示视频和详细文档截图,支持远程安装调试,确保顺利运行。
583 17
|
JSON Java 关系型数据库
Java更新数据库报错:Data truncation: Cannot create a JSON value from a string with CHARACTER SET 'binary'.
在Java中,使用mybatis-plus更新实体类对象到mysql,其中一个字段对应数据库中json数据类型,更新时报错:Data truncation: Cannot create a JSON value from a string with CHARACTER SET 'binary'.
1858 4
Java更新数据库报错:Data truncation: Cannot create a JSON value from a string with CHARACTER SET 'binary'.
|
SQL Java 关系型数据库
使用 JDBC 实现 Java 数据库操作
JDBC(Java Database Connectivity)是 Java 提供的数据库访问技术,允许通过 SQL 语句与数据库交互。本文详细介绍了 JDBC 的使用方法,包括环境准备、编程步骤和完整示例。
1376 7

热门文章

最新文章