如何使用流API从数据库加载数据?

时间:2016-10-10 12:52:20

标签: java database jdbc java-8 java-stream

例如,我想基于某些过滤器从数据库加载数据,将其转换(映射)到某些对象,限制数据并将其收集到列表中:

List<Person> people = new DbStream("PERSON").filter(...).limit(20l).map(...).collect(...);

我是否可以使用流API(可能在后台看不到JDBC)对数据库执行此操作?怎么样?

*我知道它绕过了SQL语言。只是想检查是否有办法...

2 个答案:

答案 0 :(得分:4)

您可以使用名为Speedment的外部库来执行此操作。它们允许您从数据库的元数据中生成代码,然后使用生成的类来流式传输数据库的表。

在此示例中,我们使用具有三个字段的数据库用户:

-----------------------------------
- UserName - Trusted - TimeOnline -                                -
-  VARCHAR -   INT   -  BIGINT    -
-----------------------------------

示例流(找到10个基本上第一个用户):

List<String> userNames = new LinkedList<>();
userDatabase.stream()
    .sorted( Users.USER_NAME.comparator() )
    .limit( 10 )
    .forEach( p ->  {
        users.add( p.getUsername() );
    } );
return users;

示例插入:

userDatabase.newEmptyEntity()
             .setUsername( "Gikkman" )
             .setIsTrusted( 1 )
             .setTimeOnline( 0 )
             .persist();  //This command persists the entry to the DB

答案 1 :(得分:0)

完全按照您的需要做什么

一个有趣的库,可以执行您要执行的操作JINQ,它执行符号字节码执行,将普通Java代码转换为SQL / JPQL或jOOQ查询。以下是从文档中获取的示例:

cityStream
   .where( c -> c.getPopulation() > 10000
         && c.getLandArea() > 300 );

以上内容将(大致)转换为以下SQL查询:

SELECT * FROM city c WHERE c.population > 10000 AND c.land_area > 300

或者,如果它由JPQL支持,它也可能生成完全不同的SQL查询,包括必要的连接,具体取决于您指定实体和关系的方式。

JINQ从LINQ I recommend reading this interesting interview with the author获取灵感。

几乎完成你需要做的事

评论中提到的另一个库是jOOQ。它不会将流调用映射到SQL,但允许您使用流畅的API编写SQL,然后使用流获取/转换结果。 E.g。

try (Stream<CityRecord> stream =
    DSL.using(configuration)
       .selectFrom(CITY)
       .where(CITY.POPULATION.gt(10000))
       .and(CITY.LAND_AREA.gt(300))) {

    stream.map(...).limit(...).collect(...);
}

但是,请注意,如果将数据库推送到SQL语句中,您的数据库通常会从.map().limit()等每个子句中获益。

(免责声明:我为jOOQ背后的公司工作)。