[R2DBC-Spring-Data-kofu]:在条件API中表达不同
[R2DBC-Spring-Data-kofu]:Expressing distinct in criteria API
您好,我尝试将 jpql 查询转换为条件 api。
sql 查询是
SELECT COUNT(DISTINCT id) FROM `user` WHERE login != :anonymousUser
我刚刚成功地达到了这个查询条件
SELECT COUNT(id) FROM `user` WHERE login != :anonymousUser
这是代码:
class UserRepository(
private val repo: R2dbcEntityOperations
) {
companion object {
@JvmStatic
private val userModel by lazy { User::class.java }
}
// expected query:
//"SELECT COUNT(DISTINCT id) FROM `user` WHERE login != :anonymousUser"
fun countAllByLoginNot(anonymousUser: String): Mono<Long> {
return repo.select(userModel)
//current query:
//"SELECT COUNT(id) FROM `user` WHERE login != :anonymousUser"
.matching(
query(
where("login")
.not(anonymousUser).ignoreCase(true)
)
)
.count()
}
}
如何使用标准 API 引入不同?
我也遇到过类似的问题。
虽然我使用的是 java,但我似乎找到了一些相关的东西,希望对您有所帮助:
// template : R2dbcEntityTemplate
final StatementMapper statementMapper = template.getDataAccessStrategy().getStatementMapper();
statementMapper.createSelect("table_name")
.distinct() // distinct!
.doWithTable((table, spec) -> {
// Do with table.
// See org.springframework.data.r2dbc.core.R2dbcEntityTemplate#doSelect or other.
return // return something
});
如果要对count函数进行去重,可能需要参考org.springframework.data.relational.core.sql.SimpleFunction
实现一个新的class,比如CountDistinctFunction
。你可以参考这个:
/**
*
* Function: {@code COUNT(DISTINCT ... )}
*
* @see org.springframework.data.relational.core.sql.Functions
* @see org.springframework.data.relational.core.sql.SimpleFunction
* @author ForteScarlet
*/
public class CountDistinctFunction implements Expression {
private static final String FUNCTION_NAME = "COUNT";
private final List<Expression> expressions;
private CountDistinctFunction(List<Expression> expressions) {
this.expressions = expressions;
}
/** getInstance. */
public static CountDistinctFunction getInstance(Expression... expressions) {
return new CountDistinctFunction(Arrays.asList(expressions));
}
/**
* @see SimpleFunction#toString()
*/
@Override
public @NotNull String toString() {
return FUNCTION_NAME + "(DISTINCT " + StringUtils.collectionToDelimitedString(expressions, ", ") + ")";
}
/**
* @see SimpleFunction#getFunctionName()
*/
public String getFunctionName() {
return FUNCTION_NAME;
}
/**
* @see SimpleFunction#getExpressions()
*/
public List<Expression> getExpressions() {
return Collections.unmodifiableList(expressions);
}
/**
* @see org.springframework.data.relational.core.sql.AbstractSegment
*/
@SuppressWarnings("JavadocReference")
@Override
public void visit(@NotNull Visitor visitor) {
Assert.notNull(visitor, "Visitor must not be null!");
visitor.enter(this);
visitor.leave(this);
}
/**
* @see org.springframework.data.relational.core.sql.AbstractSegment
*/
@SuppressWarnings("JavadocReference")
@Override
public int hashCode() {
return toString().hashCode();
}
/**
* @see org.springframework.data.relational.core.sql.AbstractSegment
*/
@SuppressWarnings("JavadocReference")
@Override
public boolean equals(Object obj) {
return obj instanceof Segment && toString().equals(obj.toString());
}
}
并使用它:
R2dbcEntityTemplate template; = // template instance
final StatementMapper statementMapper = template.getDataAccessStrategy().getStatementMapper();
final StatementMapper.SelectSpec selectSpec = statementMapper.createSelect("your_table_name")
.withCriteria(criteria)
.doWithTable((table, spec) -> spec.withProjection(CountDistinctFunction.getInstance(table.column("id"))));
final PreparedOperation<?> operation = statementMapper.getMappedObject(selectSpec);
final Mono<Long> count = template.getDatabaseClient().sql(operation).map(r -> r.get(0, Long.class)).first();
虽然这个 post 已经很久了,但我还是会发表我的意见。如果有谁看到了,有更好的方案,也请告诉我,万分感谢!
(由 DeepL 翻译)
您好,我尝试将 jpql 查询转换为条件 api。
sql 查询是
SELECT COUNT(DISTINCT id) FROM `user` WHERE login != :anonymousUser
我刚刚成功地达到了这个查询条件
SELECT COUNT(id) FROM `user` WHERE login != :anonymousUser
这是代码:
class UserRepository(
private val repo: R2dbcEntityOperations
) {
companion object {
@JvmStatic
private val userModel by lazy { User::class.java }
}
// expected query:
//"SELECT COUNT(DISTINCT id) FROM `user` WHERE login != :anonymousUser"
fun countAllByLoginNot(anonymousUser: String): Mono<Long> {
return repo.select(userModel)
//current query:
//"SELECT COUNT(id) FROM `user` WHERE login != :anonymousUser"
.matching(
query(
where("login")
.not(anonymousUser).ignoreCase(true)
)
)
.count()
}
}
如何使用标准 API 引入不同?
我也遇到过类似的问题。 虽然我使用的是 java,但我似乎找到了一些相关的东西,希望对您有所帮助:
// template : R2dbcEntityTemplate
final StatementMapper statementMapper = template.getDataAccessStrategy().getStatementMapper();
statementMapper.createSelect("table_name")
.distinct() // distinct!
.doWithTable((table, spec) -> {
// Do with table.
// See org.springframework.data.r2dbc.core.R2dbcEntityTemplate#doSelect or other.
return // return something
});
如果要对count函数进行去重,可能需要参考org.springframework.data.relational.core.sql.SimpleFunction
实现一个新的class,比如CountDistinctFunction
。你可以参考这个:
/**
*
* Function: {@code COUNT(DISTINCT ... )}
*
* @see org.springframework.data.relational.core.sql.Functions
* @see org.springframework.data.relational.core.sql.SimpleFunction
* @author ForteScarlet
*/
public class CountDistinctFunction implements Expression {
private static final String FUNCTION_NAME = "COUNT";
private final List<Expression> expressions;
private CountDistinctFunction(List<Expression> expressions) {
this.expressions = expressions;
}
/** getInstance. */
public static CountDistinctFunction getInstance(Expression... expressions) {
return new CountDistinctFunction(Arrays.asList(expressions));
}
/**
* @see SimpleFunction#toString()
*/
@Override
public @NotNull String toString() {
return FUNCTION_NAME + "(DISTINCT " + StringUtils.collectionToDelimitedString(expressions, ", ") + ")";
}
/**
* @see SimpleFunction#getFunctionName()
*/
public String getFunctionName() {
return FUNCTION_NAME;
}
/**
* @see SimpleFunction#getExpressions()
*/
public List<Expression> getExpressions() {
return Collections.unmodifiableList(expressions);
}
/**
* @see org.springframework.data.relational.core.sql.AbstractSegment
*/
@SuppressWarnings("JavadocReference")
@Override
public void visit(@NotNull Visitor visitor) {
Assert.notNull(visitor, "Visitor must not be null!");
visitor.enter(this);
visitor.leave(this);
}
/**
* @see org.springframework.data.relational.core.sql.AbstractSegment
*/
@SuppressWarnings("JavadocReference")
@Override
public int hashCode() {
return toString().hashCode();
}
/**
* @see org.springframework.data.relational.core.sql.AbstractSegment
*/
@SuppressWarnings("JavadocReference")
@Override
public boolean equals(Object obj) {
return obj instanceof Segment && toString().equals(obj.toString());
}
}
并使用它:
R2dbcEntityTemplate template; = // template instance
final StatementMapper statementMapper = template.getDataAccessStrategy().getStatementMapper();
final StatementMapper.SelectSpec selectSpec = statementMapper.createSelect("your_table_name")
.withCriteria(criteria)
.doWithTable((table, spec) -> spec.withProjection(CountDistinctFunction.getInstance(table.column("id"))));
final PreparedOperation<?> operation = statementMapper.getMappedObject(selectSpec);
final Mono<Long> count = template.getDatabaseClient().sql(operation).map(r -> r.get(0, Long.class)).first();
虽然这个 post 已经很久了,但我还是会发表我的意见。如果有谁看到了,有更好的方案,也请告诉我,万分感谢!
(由 DeepL 翻译)