001package io.ebean;
002
003import javax.annotation.Nonnull;
004import javax.annotation.Nullable;
005import java.util.List;
006import java.util.Optional;
007
008/**
009 * Provides finder functionality for use with "Dependency Injection style" use of Ebean.
010 * <p>
011 * Note that typically users would extend BeanRepository rather than BeanFinder.
012 * </p>
013 * <pre>{@code
014 *
015 * public class CustomerFinder extends BeanFinder<Long,Customer> {
016 *
017 *   @Inject
018 *   public CustomerFinder(Database database) {
019 *     super(Customer.class, database);
020 *   }
021 *
022 *   // ... add customer specific finders
023 * }
024 *
025 * }</pre>
026 *
027 * @param <I> The ID type
028 * @param <T> The Bean type
029 */
030public abstract class BeanFinder<I,T> {
031
032  protected final Database server;
033
034  protected final Class<T> type;
035
036  /**
037   * Create with the given bean type and Database instance.
038   *
039   * @param type The bean type
040   * @param server The Database instance typically created via Spring factory or equivalent.
041   */
042  protected BeanFinder(Class<T> type, Database server) {
043    this.type = type;
044    this.server = server;
045  }
046
047  /**
048   * Return the Database to use.
049   */
050  public Database db() {
051    return server;
052  }
053
054  /**
055   * Return the current transaction.
056   */
057  public Transaction currentTransaction() {
058    return db().currentTransaction();
059  }
060
061  /**
062   * Flush the JDBC batch on the current transaction.
063   */
064  public void flush() {
065    db().flush();
066  }
067
068  /**
069   * Return typically a different Database to the default.
070   * <p>
071   * This is equivalent to {@link DB#byName(String)}
072   *
073   * @param server The name of the Database. If this is null then the default Database is returned.
074   */
075  public Database db(String server) {
076    return DB.byName(server);
077  }
078
079  /**
080   * Creates an entity reference for this ID.
081   * <p>
082   * Equivalent to {@link Database#getReference(Class, Object)}
083   */
084  @Nonnull
085  public T ref(I id) {
086    return db().getReference(type, id);
087  }
088
089  /**
090   * Retrieves an entity by ID.
091   */
092  @Nullable
093  public T findById(I id) {
094    return db().find(type, id);
095  }
096
097  /**
098   * Find an entity by ID returning an Optional.
099   */
100  @Nullable
101  public Optional<T> findByIdOrEmpty(I id) {
102    return db().find(type).setId(id).findOneOrEmpty();
103  }
104
105  /**
106   * Delete a bean by Id.
107   */
108  public void deleteById(I id) {
109    db().delete(type, id);
110  }
111
112  /**
113   * Retrieves all entities of the given type.
114   */
115  @Nonnull
116  public List<T> findAll() {
117    return query().findList();
118  }
119
120  /**
121   * Creates an update query.
122   *
123   * <pre>{@code
124   *
125   *  int rows =
126   *      updateQuery()
127   *      .set("status", Customer.Status.ACTIVE)
128   *      .set("updtime", new Timestamp(System.currentTimeMillis()))
129   *      .where()
130   *        .gt("id", 1000)
131   *        .update();
132   *
133   * }</pre>
134   *
135   * <p>
136   * Equivalent to {@link Database#update(Class)}
137   */
138  protected UpdateQuery<T> updateQuery() {
139    return db().update(type);
140  }
141
142  /**
143   * Creates a query.
144   * <p>
145   * Equivalent to {@link Database#find(Class)}
146   */
147  protected Query<T> query() {
148    return db().find(type);
149  }
150
151  /**
152   * Creates a native sql query.
153   */
154  protected Query<T> nativeSql(String nativeSql) {
155    return db().findNative(type, nativeSql);
156  }
157
158  /**
159   * Creates a query using the ORM query language.
160   */
161  protected Query<T> query(String ormQuery) {
162    return db().createQuery(type, ormQuery);
163  }
164}