001package com.avaje.ebean; 002 003import org.jetbrains.annotations.Nullable; 004 005import java.util.List; 006 007/** 008 * Intended to be used as a base class for 'Finder' implementations that can then 009 * be injected or used as public static fields on the associated entity bean. 010 * <p> 011 * These 'finders' are a place to organise all the finder methods for that bean type 012 * and specific finder methods are expected to be added (find by unique properties etc). 013 * </p> 014 * 015 * <h3>Testing</h3> 016 * <p> 017 * For testing the mocki-ebean project has the ability to replace the finder implementation 018 * 019 * </p> 020 * <pre>{@code 021 * 022 * public class CustomerFinder extends Finder<Customer> { 023 * 024 * public CustomerFinder() { 025 * super(Customer.class); 026 * } 027 * 028 * // Add your customer finder methods ... 029 * 030 * public Customer byName(String name) { 031 * return query().eq("name", name).findUnique(); 032 * } 033 * 034 * public List<Customer> findNew() { 035 * return query() 036 * .eq("status", Customer.Status.NEW) 037 * .orderBy("name") 038 * .findList() 039 * } 040 * } 041 * 042 * @Entity 043 * public class Customer extends BaseModel { 044 * 045 * public static final CustomerFinder find = new CustomerFinder(); 046 * ... 047 * 048 * }</pre> 049 */ 050public class Finder<I, T> { 051 052 /** 053 * The entity bean type. 054 */ 055 private final Class<T> type; 056 057 /** 058 * The name of the EbeanServer, null for the default server. 059 */ 060 private final String serverName; 061 062 /** 063 * Create with the type of the entity bean. 064 * 065 * <pre>{@code 066 * 067 * public class CustomerFinder extends Finder<Customer> { 068 * 069 * public CustomerFinder() { 070 * super(Customer.class); 071 * } 072 * 073 * // ... add extra customer specific finder methods 074 * } 075 * 076 * @Entity 077 * public class Customer extends BaseModel { 078 * 079 * public static final CustomerFinder find = new CustomerFinder(); 080 * ... 081 * 082 * }</pre> 083 */ 084 public Finder(Class<T> type) { 085 this.type = type; 086 this.serverName = null; 087 } 088 089 /** 090 * Create with the type of the entity bean and specific server name. 091 */ 092 public Finder(Class<T> type, String serverName) { 093 this.type = type; 094 this.serverName = serverName; 095 } 096 097 /** 098 * Return the underlying 'default' EbeanServer. 099 * 100 * <p> 101 * This provides full access to the API such as explicit transaction demarcation etc. 102 * 103 */ 104 public EbeanServer db() { 105 return Ebean.getServer(serverName); 106 } 107 108 /** 109 * Return typically a different EbeanServer to the default. 110 * <p> 111 * This is equivalent to {@link Ebean#getServer(String)} 112 * 113 * @param server 114 * The name of the EbeanServer. If this is null then the default EbeanServer is 115 * returned. 116 */ 117 public EbeanServer db(String server) { 118 return Ebean.getServer(server); 119 } 120 121 /** 122 * Creates an entity reference for this ID. 123 * 124 * <p> 125 * Equivalent to {@link EbeanServer#getReference(Class, Object)} 126 */ 127 public T ref(I id) { 128 return db().getReference(type, id); 129 } 130 131 /** 132 * Retrieves an entity by ID. 133 * 134 * <p> 135 * Equivalent to {@link EbeanServer#find(Class, Object)} 136 */ 137 @Nullable 138 public T byId(I id) { 139 return db().find(type, id); 140 } 141 142 /** 143 * Delete a bean by Id. 144 * <p> 145 * Equivalent to {@link EbeanServer#delete(Class, Object)} 146 */ 147 public void deleteById(I id) { 148 db().delete(type, id); 149 } 150 151 /** 152 * Retrieves all entities of the given type. 153 */ 154 public List<T> all() { 155 return query().findList(); 156 } 157 158 /** 159 * Creates a query. 160 * <p> 161 * Equivalent to {@link EbeanServer#find(Class)} 162 */ 163 public Query<T> query() { 164 return db().find(type); 165 } 166 167}