mirror of
https://github.com/ebean-orm/ebean.git
synced 2026-10-24 03:57:45 +00:00
#1607 - ENH: Add query.exists() query ... as a convenience for "does a row exist" check
This commit is contained in:
@@ -226,6 +226,32 @@ public interface ExpressionList<T> {
|
||||
*/
|
||||
int update(Transaction transaction);
|
||||
|
||||
/**
|
||||
* Execute the query returning true if a row is found.
|
||||
* <p>
|
||||
* The query is executed using max rows of 1 and will only select the id property.
|
||||
* This method is really just a convenient way to optimise a query to perform a
|
||||
* 'does a row exist in the db' check.
|
||||
* </p>
|
||||
*
|
||||
* <h2>Example:</h2>
|
||||
* <pre>{@code
|
||||
*
|
||||
* boolean userExists = query().where().eq("email", "rob@foo.com").exists();
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* <h2>Example using a query bean:</h2>
|
||||
* <pre>{@code
|
||||
*
|
||||
* boolean userExists = new QContact().email.equalTo("rob@foo.com").exists();
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* @return True if the query finds a matching row in the database
|
||||
*/
|
||||
boolean exists();
|
||||
|
||||
/**
|
||||
* Execute the query iterating over the results.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package io.ebean;
|
||||
|
||||
import io.ebeaninternal.api.SpiQuery;
|
||||
import io.ebeaninternal.api.SpiTransaction;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.persistence.NonUniqueResultException;
|
||||
@@ -42,6 +45,32 @@ public interface ExtendedServer {
|
||||
*/
|
||||
void setClock(Clock clock);
|
||||
|
||||
/**
|
||||
* Execute the query returning true if a row is found.
|
||||
* <p>
|
||||
* The query is executed using max rows of 1 and will only select the id property.
|
||||
* This method is really just a convenient way to optimise a query to perform a
|
||||
* 'does a row exist in the db' check.
|
||||
* </p>
|
||||
*
|
||||
* <h2>Example:</h2>
|
||||
* <pre>{@code
|
||||
*
|
||||
* boolean userExists = query().where().eq("email", "rob@foo.com").exists();
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* <h2>Example using a query bean:</h2>
|
||||
* <pre>{@code
|
||||
*
|
||||
* boolean userExists = new QContact().email.equalTo("rob@foo.com").exists();
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* @return True if the query finds a matching row in the database
|
||||
*/
|
||||
<T> boolean exists(SpiQuery<?> ormQuery, SpiTransaction transaction);
|
||||
|
||||
/**
|
||||
* Return the number of 'top level' or 'root' entities this query should return.
|
||||
*
|
||||
|
||||
@@ -868,6 +868,32 @@ public interface Query<T> {
|
||||
*/
|
||||
boolean isCountDistinct();
|
||||
|
||||
/**
|
||||
* Execute the query returning true if a row is found.
|
||||
* <p>
|
||||
* The query is executed using max rows of 1 and will only select the id property.
|
||||
* This method is really just a convenient way to optimise a query to perform a
|
||||
* 'does a row exist in the db' check.
|
||||
* </p>
|
||||
*
|
||||
* <h2>Example:</h2>
|
||||
* <pre>{@code
|
||||
*
|
||||
* boolean userExists = query().where().eq("email", "rob@foo.com").exists();
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* <h2>Example using a query bean:</h2>
|
||||
* <pre>{@code
|
||||
*
|
||||
* boolean userExists = new QContact().email.equalTo("rob@foo.com").exists();
|
||||
*
|
||||
* }</pre>
|
||||
*
|
||||
* @return True if the query finds a matching row in the database
|
||||
*/
|
||||
boolean exists();
|
||||
|
||||
/**
|
||||
* Execute the query returning either a single bean or null (if no matching
|
||||
* bean is found).
|
||||
|
||||
@@ -1363,6 +1363,21 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
return !ids.isEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> boolean exists(SpiQuery<?> ormQuery, SpiTransaction transaction) {
|
||||
|
||||
ormQuery.setMaxRows(1);
|
||||
SpiOrmQueryRequest<?> request = createQueryRequest(Type.ID_LIST, ormQuery, transaction);
|
||||
try {
|
||||
request.initTransIfRequired();
|
||||
List<Object> ids = request.findIds();
|
||||
return !ids.isEmpty();
|
||||
|
||||
} finally {
|
||||
request.endTransIfRequired();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public <A, T> List<A> findIds(Query<T> query, Transaction t) {
|
||||
|
||||
@@ -1444,10 +1459,6 @@ public final class DefaultServer implements SpiServer, SpiEbeanServer {
|
||||
return queryFuture;
|
||||
}
|
||||
|
||||
public <T> FutureRowCount<T> findFutureRowCount(Query<T> q, Transaction t) {
|
||||
return findFutureCount(q, t);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> FutureIds<T> findFutureIds(Query<T> query, Transaction t) {
|
||||
|
||||
|
||||
@@ -443,6 +443,11 @@ public class DefaultExpressionList<T> implements SpiExpressionList<T> {
|
||||
return query.findSingleAttributeList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exists() {
|
||||
return query.exists();
|
||||
}
|
||||
|
||||
@Override
|
||||
public T findOne() {
|
||||
return query.findOne();
|
||||
|
||||
@@ -99,6 +99,11 @@ public class FilterExpressionList<T> extends DefaultExpressionList<T> {
|
||||
return rootQuery.findOneOrEmpty();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exists() {
|
||||
return rootQuery.exists();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExpressionList<T> having() {
|
||||
throw new PersistenceException(notAllowedMessage);
|
||||
|
||||
@@ -375,6 +375,11 @@ class JunctionExpression<T> implements SpiJunction<T>, SpiExpression, Expression
|
||||
return exprList.apply(fetchPath);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exists() {
|
||||
return exprList.exists();
|
||||
}
|
||||
|
||||
@Override
|
||||
public FutureIds<T> findFutureIds() {
|
||||
return exprList.findFutureIds();
|
||||
|
||||
@@ -1398,6 +1398,11 @@ public class DefaultOrmQuery<T> implements SpiQuery<T> {
|
||||
return server.findIds(this, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean exists() {
|
||||
return server.exists(this, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int findCount() {
|
||||
// a copy of this query is made in the server
|
||||
|
||||
@@ -632,6 +632,11 @@ public class TDSpiEbeanServer implements SpiEbeanServer {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> boolean exists(SpiQuery<?> ormQuery, SpiTransaction transaction) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T find(Class<T> beanType, Object uid) {
|
||||
return null;
|
||||
|
||||
@@ -3,11 +3,10 @@ package org.tests.query;
|
||||
import io.ebean.BaseTestCase;
|
||||
import io.ebean.Ebean;
|
||||
import io.ebean.Query;
|
||||
import org.junit.Test;
|
||||
import org.tests.model.basic.Customer;
|
||||
import org.tests.model.basic.Order;
|
||||
import org.tests.model.basic.ResetBasicData;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -15,6 +14,27 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class TestQueryExists extends BaseTestCase {
|
||||
|
||||
@Test
|
||||
public void testExistsBoolean_basic() {
|
||||
|
||||
ResetBasicData.reset();
|
||||
|
||||
Query<Order> query = Ebean.find(Order.class)
|
||||
.where().gt("id", 1)
|
||||
.query();
|
||||
|
||||
boolean check = query.exists();
|
||||
assertThat(check).isTrue();
|
||||
|
||||
String sql = sqlOf(query);
|
||||
if (isH2() || isPostgres()) {
|
||||
assertThat(sql).contains("select t0.id from o_order t0 where t0.id > ? limit 1");
|
||||
}
|
||||
|
||||
assertThat(Ebean.find(Order.class).where().gt("id", 1).exists()).isTrue();
|
||||
assertThat(Ebean.find(Order.class).where().or().gt("id", 1).isNull("shipDate").exists()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExists_orders_onOneToMany() {
|
||||
|
||||
@@ -73,7 +93,7 @@ public class TestQueryExists extends BaseTestCase {
|
||||
query.findList();
|
||||
String sql = query.getGeneratedSql();
|
||||
|
||||
Assert.assertTrue(sql.indexOf("exists (") > 0);
|
||||
assertThat(sql).contains("exists (");
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -86,6 +106,6 @@ public class TestQueryExists extends BaseTestCase {
|
||||
query.findList();
|
||||
String sql = query.getGeneratedSql();
|
||||
|
||||
Assert.assertTrue(sql.indexOf("not exists (") > 0);
|
||||
assertThat(sql).contains("not exists (");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user