我有几张包含大量数据的表(大约1亿条记录).所以我不能将这些数据存储在内存中,但是我希望使用类来传输这个结果集java.util.stream
并将此流传递给另一个类.我读了关于Stream.of
和Stream.Builder
运算符,但它们是内存中的缓冲流.那么有什么方法可以解决这个问题吗?提前致谢.
更新#1
好吧,我用Google搜索并找到了jooq库.我不确定,但看起来它可能适用于我的测试用例.总而言之,我有几张包含大量数据的表格.我想流式传输我的结果集并将此流传输到另一个方法.像这样的东西:
// why return Stream<String>? Because my result set has String type
private Stream<Record> writeTableToStream(DataSource dataSource, String table) {
Stream<Record> record = null;
try (Connection connection = dataSource.getConnection()) {
String sql = "select * from " + table;
try (PreparedStatement pSt = connection.prepareStatement(sql)) {
connection.setAutoCommit(false);
pSt.setFetchSize(5000);
ResultSet resultSet = pSt.executeQuery();
//
record = DSL.using(connection)
.fetch(resultSet).stream();
}
} catch (SQLException sqlEx) {
logger.error(sqlEx);
}
return record;
}
Run Code Online (Sandbox Code Playgroud)
可以请有人建议,我是否正确?谢谢.
更新#2
我在 …
我正在开发一个新的Java Web应用程序,我正在探索新的方法(对我来说是新的!)来保存数据.我主要有JPA和Hibernate的经验,但除了简单的情况,我认为这种完整的ORM会变得非常复杂.另外,我不喜欢和他们一起工作.我正在寻找一种新的解决方案,可能更接近SQL.
我正在调查的解决方案:
但与Hibernate相比,我有两个使用案例,我担心这些解决方案.我想知道这些用例的推荐模式是什么.
Person
实体.
Person
有一个相关的Address
实体.
Address
有一个相关的City
实体.
City
实体有一个name
属性.从人员实体开始,访问城市名称的完整路径是:
person.address.city.name
Run Code Online (Sandbox Code Playgroud)
现在,假设我PersonService
使用以下方法从a加载Person实体:
public Person findPersonById(long id)
{
// ...
}
Run Code Online (Sandbox Code Playgroud)
使用Hibernate,Person
可以根据需要延迟加载与之关联的实体,因此可以访问person.address.city.name
并确保我可以访问此属性(只要该链中的所有实体都不可为空).
但是使用我正在研究的3种解决方案中的任何一种,它都会更复杂.有了这些解决方案,有哪些推荐的模式来处理这个用例?在前面,我看到3种可能的模式:
可以通过所使用的SQL查询急切地加载所有必需的关联子孙实体.
但是我在这个解决方案中看到的问题是,可能还有一些其他代码需要从实体访问其他实体/属性路径Person
.例如,可能需要访问一些代码person.job.salary.currency
.如果我想重用findPersonById()
我已经拥有的方法,那么SQL查询将需要加载更多信息!不仅是相关address->city
实体,还包括相关job->salary
实体.
现在如果还有10个其他地方需要从人员实体开始访问其他信息呢?我是否应该急切地加载所有可能需要的信息?或者可能有12种不同的服务方法来加载一个人实体?:
findPersonById_simple(long id)
findPersonById_withAdressCity(long id)
findPersonById_withJob(long id)
findPersonById_withAdressCityAndJob(long id)
...
Run Code Online (Sandbox Code Playgroud)
但是每当我使用一个Person
实体时,我就必须知道装载它的是什么以及什么没有...它可能非常麻烦,对吧? …
我正在尝试使用jOOQ库在PostgreSQL中执行UPSERT.
为此,我目前正在尝试在jOOQ中实现以下SQL语句:https://stackoverflow.com/a/6527838
到目前为止我的代码看起来像这样:
public class UpsertExecutor {
private static final Logger logger = LoggerFactory.getLogger(UpsertExecutor.class);
private final JOOQContextProvider jooqProvider;
@Inject
public UpsertExecutor(JOOQContextProvider jooqProvider) {
Preconditions.checkNotNull(jooqProvider);
this.jooqProvider = jooqProvider;
}
@Transactional
public <T extends Record> void executeUpsert(Table<T> table, Condition condition, Map<? extends Field<?>, ?> recordValues) {
/*
* All of this is for trying to do an UPSERT on PostgreSQL. See:
* https://stackoverflow.com/a/6527838
*/
SelectConditionStep<Record1<Integer>> notExistsSelect = jooqProvider.getDSLContext().selectOne().from(table).where(condition);
SelectConditionStep<Record> insertIntoSelect = jooqProvider.getDSLContext().select(recordValues).whereNotExists(notExistsSelect);
try {
int[] result = jooqProvider.getDSLContext().batch(
jooqProvider.getDSLContext().update(table).set(recordValues).where(condition),
jooqProvider.getDSLContext().insertInto(table).select(insertIntoSelect) …
Run Code Online (Sandbox Code Playgroud) 有人能指出一些关于可用于Java的不同Query DSL库之间性能比较的资源,如:Querydsl,jOOQ,JEQUEL,activejdbc,iciql等等......
背景:我使用Spring JDBC模板,但仍然需要以纯字符串格式编写查询.虽然我在编写直接查询时没有问题,但我担心直接依赖于DB表名.我不想使用任何ORM框架,如Hibernate或JPA/EclipseLink.我需要尽可能高的原始性能(IMO,它们适用于更多以CRUD为中心的应用程序).我可以为这些DSL提供一些轻微的开销,只要它有点(我相信,它主要是StringBuilder/String连接!)
我考虑过在某些xml中使用外部化的命名查询.但只是试图评估不同的Query DSL库提供的价值.
编辑:更多关于我的要求: 我想知道使用他们的API方法构建中等复杂查询时这些之间的性能比较.我需要的是使用任何这些查询DSL库生成查询字符串并将其传递给Spring JDBC模板.所以,我想知道如果添加这个中间步骤会导致相当大的性能损失,我想使用命名查询或构建我自己的库,它只使用StingBuilder或类似的方法
用jOOQ,iciql,QueryDSL更新我的经验:
虽然我错过了在我的原帖中提到这一点,但我也热衷于易用性和我在实体类中需要的开销(如果需要任何额外的注释或实现).
jOOQ:
Iciql:
QueryDSL:
(所有观察对我都知之甚少;如果其中任何一个不正确,请更正)
综上所述,我坚持编写命名查询:(但由于Lukas Eder的答案似乎解释了我原来的帖子关注(表现),我接受了他的.
有人试过在Spring框架中使用JOOQ,还是我开辟了新天地?
我是JooQ的忠实粉丝,不幸的是,自从3.3升级后,每次我的代码退出之前都会向控制台输出一条非常烦人的消息:
Feb 02, 2015 7:28:06 AM org.jooq.tools.JooqLogger info
INFO:
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
<snip>
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ Thank you for using jOOQ 3.5.1
Run Code Online (Sandbox Code Playgroud)
不幸的是,我根本无法删除此日志.
请注意,我不使用slf4j,也不使用log4j或任何日志API; 因此,我唯一可用的机制是jul
我试图使用它完全禁用它:
static {
Stream.of(Logger.getAnonymousLogger(), Logger.getGlobal(),
Logger.getLogger("org.jooq.tools.JooqLogger")
).forEach(l -> {
l.setLevel(Level.OFF);
final Handler[] handlers = l.getHandlers();
Arrays.stream(handlers).forEach(l::removeHandler);
});
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,它不起作用,消息仍然出现.
如何在修改代码时使这条消息消失,我想避免在这里?
我现在正在将Pure SQL转换为jOOQ
("SELECT Count(*) Count From Table ");
Run Code Online (Sandbox Code Playgroud)
我必须在jOOQ写这个怎么写呢?
selectQueryRecord.addSelect(Here Count Function );
selectQueryRecord.addFrom(Table);
Run Code Online (Sandbox Code Playgroud) 我在PostgreSQL数据库中定义了一个类型T
和一个视图V
.
CREATE TYPE my_type AS
(
mt_column1 smallint NOT NULL
);
CREATE VIEW my_view
AS SELECT
some_column_id integer
ARRAY(SELECT
ROW(an_int)::my_type
FROM a_table
) AS my_view_types
FROM a_regular_table
WHERE my_condition_hold);
Run Code Online (Sandbox Code Playgroud)
使用版本3.7上的代码生成,我得到了一个UDT记录类MyTypeRecord
和一个表记录类MyViewRecord
以及UDT POJO类MyType
和表POJO类MyView
.
所述MyView
生成的类具有的阵列MyTypeRecord
.
public class MyView extends Object implements Serializable, Cloneable, IMyView {
private static final long serialVersionUID = 1984808170;
private final Long some_column_id;
private final MyTypeRecord[] my_view_types;
}
Run Code Online (Sandbox Code Playgroud)
而在POJO中我会期待一系列POJO,例如:
private final MyType[] …
Run Code Online (Sandbox Code Playgroud) java ×10
jooq ×10
sql ×5
postgresql ×2
database ×1
hibernate ×1
java-stream ×1
jdbc ×1
lambda ×1
logging ×1
mybatis ×1
performance ×1
persistence ×1
querydsl ×1
spring ×1
spring-jdbc ×1
sqlbuilder ×1
upsert ×1