001package io.ebean;
002
003import io.avaje.lang.NonNullApi;
004import io.avaje.lang.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 */
030@NonNullApi
031public abstract class BeanFinder<I,T> {
032
033  protected final Database server;
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#reference(Class, Object)}
083   */
084  public T ref(I id) {
085    return db().reference(type, id);
086  }
087
088  /**
089   * Retrieves an entity by ID.
090   */
091  @Nullable
092  public T findById(I id) {
093    return db().find(type, id);
094  }
095
096  /**
097   * Find an entity by ID returning an Optional.
098   */
099  public Optional<T> findByIdOrEmpty(I id) {
100    return db().find(type).setId(id).findOneOrEmpty();
101  }
102
103  /**
104   * Delete a bean by Id.
105   */
106  public void deleteById(I id) {
107    db().delete(type, id);
108  }
109
110  /**
111   * Retrieves all entities of the given type.
112   */
113  public List<T> findAll() {
114    return query().findList();
115  }
116
117  /**
118   * Creates an update query.
119   *
120   * <pre>{@code
121   *
122   *  int rows =
123   *      updateQuery()
124   *      .set("status", Customer.Status.ACTIVE)
125   *      .set("updtime", new Timestamp(System.currentTimeMillis()))
126   *      .where()
127   *        .gt("id", 1000)
128   *        .update();
129   *
130   * }</pre>
131   *
132   * <p>
133   * Equivalent to {@link Database#update(Class)}
134   */
135  protected UpdateQuery<T> updateQuery() {
136    return db().update(type);
137  }
138
139  /**
140   * Creates a query.
141   * <p>
142   * Equivalent to {@link Database#find(Class)}
143   */
144  protected Query<T> query() {
145    return db().find(type);
146  }
147
148  /**
149   * Creates a native sql query.
150   */
151  protected Query<T> nativeSql(String nativeSql) {
152    return db().findNative(type, nativeSql);
153  }
154
155  /**
156   * Creates a query using the ORM query language.
157   */
158  protected Query<T> query(String ormQuery) {
159    return db().createQuery(type, ormQuery);
160  }
161}