/* * Copyright 2017 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.springframework.data.ebean.repository.support; import io.ebean.*; import io.ebean.text.PathProperties; import org.springframework.data.domain.Example; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.ebean.repository.EbeanRepository; import org.springframework.data.ebean.util.Converters; import org.springframework.data.ebean.util.ExampleExpressionBuilder; import org.springframework.stereotype.Repository; import org.springframework.transaction.annotation.Transactional; import org.springframework.util.Assert; import org.springframework.util.StringUtils; import java.util.Collection; import java.util.List; import java.util.Optional; /** * Default implementation of the {@link org.springframework.data.repository.CrudRepository} interface. This will offer * you a more sophisticated interface than the plain {@link io.ebean.EbeanServer} . * * @param <T> the type of the entity to handle * @param <ID> the type of the entity's identifier * @author Xuegui Yuan */ @Repository @Transactional(rollbackFor = Exception.class) public class SimpleEbeanRepository<T, ID> implements EbeanRepository<T, ID> { private static final String ID_MUST_NOT_BE_NULL = "The given id must not be null!"; private static final String PROP_MUST_NOT_BE_NULL = "The given property must not be null!"; private EbeanServer ebeanServer; private Class<T> entityType; /** * Creates a new {@link SimpleEbeanRepository} to manage objects of the given domain type. * * @param entityType must not be {@literal null}. * @param ebeanServer must not be {@literal null}. */ public SimpleEbeanRepository(Class<T> entityType, EbeanServer ebeanServer) { this.entityType = entityType; this.ebeanServer = ebeanServer; } @Override public Page<T> findAll(Pageable pageable) { PagedList<T> pagedList = db().find(getEntityType()) .setMaxRows(pageable.getPageSize()) .setFirstRow((int) pageable.getOffset()) .setOrder(Converters.convertToEbeanOrderBy(pageable.getSort())) .findPagedList(); return Converters.convertToSpringDataPage(pagedList, pageable.getSort()); } @Override public EbeanServer db() { return ebeanServer; } private Class<T> getEntityType() { return entityType; } @Override public EbeanServer db(EbeanServer db) { this.ebeanServer = db; return this.ebeanServer; } @Override public UpdateQuery<T> updateQuery() { return db().update(getEntityType()); } @Override public SqlUpdate sqlUpdateOf(String sql) { return db().createSqlUpdate(sql); } @Override public <S extends T> S save(S s) { db().save(s); return s; } @Override public <S extends T> Iterable<S> saveAll(Iterable<S> entities) { Assert.notNull(entities, "The given Iterable of entities not be null!"); db().saveAll((Collection<?>) entities); return entities; } @Override public <S extends T> S update(S s) { db().update(s); return s; } @Override public Iterable<T> updateAll(Iterable<T> entities) { Assert.notNull(entities, "The given Iterable of entities not be null!"); db().updateAll((Collection<?>) entities); return entities; } @Override public void deleteById(ID id) { Assert.notNull(id, ID_MUST_NOT_BE_NULL); db().delete(getEntityType(), id); } @Override public void deletePermanentById(ID id) { Assert.notNull(id, ID_MUST_NOT_BE_NULL); db().deletePermanent(getEntityType(), id); } @Override public void delete(T t) { db().delete(t); } @Override public void deletePermanent(T t) { db().deletePermanent(t); } @Override public void deleteAll(Iterable<? extends T> entities) { Assert.notNull(entities, "The given Iterable of entities not be null!"); db().deleteAll((Collection<?>) entities); } @Override public void deletePermanentAll(Iterable<? extends T> entities) { Assert.notNull(entities, "The given Iterable of entities not be null!"); db().deleteAllPermanent((Collection<?>) entities); } @Override public void deleteAll() { query().delete(); } @Override public void deletePermanentAll() { query().setIncludeSoftDeletes().delete(); } @Override public Optional<T> findById(ID id) { Assert.notNull(id, ID_MUST_NOT_BE_NULL); return query().where().idEq(id).findOneOrEmpty(); } @Override public Optional<T> findById(String fetchPath, ID id) { Assert.notNull(id, ID_MUST_NOT_BE_NULL); return query(fetchPath) .where() .idEq(id) .findOneOrEmpty(); } @Override public Optional<T> findByProperty(String propertyName, Object propertyValue) { Assert.notNull(propertyName, PROP_MUST_NOT_BE_NULL); return query() .where() .eq(propertyName, propertyValue) .findOneOrEmpty(); } @Override public Optional<T> findByProperty(String fetchPath, String propertyName, Object propertyValue) { Assert.notNull(propertyName, PROP_MUST_NOT_BE_NULL); return query(fetchPath) .where() .eq(propertyName, propertyValue) .findOneOrEmpty(); } @Override public List<T> findAllByProperty(String propertyName, Object propertyValue) { return query() .where() .eq(propertyName, propertyValue) .findList(); } @Override public List<T> findAllByProperty(String fetchPath, String propertyName, Object propertyValue) { return query(fetchPath) .where() .eq(propertyName, propertyValue) .findList(); } @Override public List<T> findAllByProperty(String fetchPath, String propertyName, Object propertyValue, Sort sort) { return query(fetchPath, sort) .where() .eq(propertyName, propertyValue) .findList(); } @Override public List<T> findAllById(Iterable<ID> ids) { Assert.notNull(ids, "The given Iterable of Id's must not be null!"); return query() .where() .idIn((Collection<?>) ids) .findList(); } @Override public List<T> findAll() { return query() .findList(); } @Override public List<T> findAll(Sort sort) { return query() .setOrder(Converters.convertToEbeanOrderBy(sort)) .findList(); } @Override public List<T> findAll(String fetchPath) { return query(fetchPath) .findList(); } @Override public List<T> findAll(String fetchPath, Iterable<ID> ids) { Assert.notNull(ids, "The given Iterable of Id's must not be null!"); return query(fetchPath) .where() .idIn((Collection<?>) ids) .findList(); } @Override public List<T> findAll(String fetchPath, Sort sort) { return query(fetchPath, sort) .findList(); } @Override public Page<T> findAll(String fetchPath, Pageable pageable) { PagedList<T> pagedList = query(fetchPath) .setMaxRows(pageable.getPageSize()) .setFirstRow((int) pageable.getOffset()) .setOrder(Converters.convertToEbeanOrderBy(pageable.getSort())) .findPagedList(); return Converters.convertToSpringDataPage(pagedList, pageable.getSort()); } @Override public <S extends T> List<S> findAll(Example<S> example) { return queryByExample(example).findList(); } @Override public <S extends T> List<S> findAll(String fetchPath, Example<S> example) { return queryByExample(fetchPath, example) .findList(); } @Override public <S extends T> List<S> findAll(String fetchPath, Example<S> example, Sort sort) { return queryByExample(fetchPath, example, sort) .findList(); } @Override public <S extends T> List<S> findAll(Example<S> example, Sort sort) { return queryByExample(null, example, sort) .findList(); } @Override public <S extends T> Optional<S> findOne(Example<S> example) { return queryByExample(example).findOneOrEmpty(); } @Override public <S extends T> Page<S> findAll(Example<S> example, Pageable pageable) { PagedList<S> pagedList = queryByExample(example) .setMaxRows(pageable.getPageSize()) .setFirstRow((int) pageable.getOffset()) .setOrder(Converters.convertToEbeanOrderBy(pageable.getSort())) .findPagedList(); return Converters.convertToSpringDataPage(pagedList, pageable.getSort()); } @Override public <S extends T> Page<S> findAll(String fetchPath, Example<S> example, Pageable pageable) { PagedList<S> pagedList = queryByExample(fetchPath, example) .setMaxRows(pageable.getPageSize()) .setFirstRow((int) pageable.getOffset()) .setOrder(Converters.convertToEbeanOrderBy(pageable.getSort())) .findPagedList(); return Converters.convertToSpringDataPage(pagedList, pageable.getSort()); } @Override public <S extends T> long count(Example<S> example) { return queryByExample(example).findCount(); } @Override public <S extends T> boolean exists(Example<S> example) { return queryByExample(example).findCount() > 0; } @Override public boolean existsById(ID id) { Assert.notNull(id, ID_MUST_NOT_BE_NULL); return query().where().idEq(id).findCount() > 0; } @Override public long count() { return query().findCount(); } private Query<T> query() { return db().find(getEntityType()); } private Query<T> query(String fetchPath) { Query<T> query = query(); if (StringUtils.hasText(fetchPath)) { query.apply(PathProperties.parse(fetchPath)); } return query; } private Query<T> query(String fetchPath, Sort sort) { if (sort == null) { return query(fetchPath); } else { return query(fetchPath).setOrder(Converters.convertToEbeanOrderBy(sort)); } } private <S extends T> Query<S> queryByExample(Example<S> example) { return db().find(example.getProbeType()).where(ExampleExpressionBuilder.exampleExpression(db(), example)); } private <S extends T> Query<S> queryByExample(String fetchPath, Example<S> example) { Query<S> query = queryByExample(example); if (StringUtils.hasText(fetchPath)) { query.apply(PathProperties.parse(fetchPath)); } return query; } private <S extends T> Query<S> queryByExample(String fetchPath, Example<S> example, Sort sort) { Query<S> query = queryByExample(fetchPath, example); if (sort != null) { query.setOrder(Converters.convertToEbeanOrderBy(sort)); } return query; } }