Skip to content

Commit

Permalink
style: format
Browse files Browse the repository at this point in the history
  • Loading branch information
shihyuho committed Apr 23, 2022
1 parent 0d8d925 commit 5ea8df3
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 49 deletions.
17 changes: 14 additions & 3 deletions starter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,17 @@ public class PersonService {

在配置的過程中, QBS 會自動配置 Spring Data JPA 的 [Base Repository](https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.customize-base-repository), 預設的實作為 [`QueryBySpecExecutorImpl`](./src/main/java/tw/com/softleader/data/jpa/spec/repository/support/QueryBySpecExecutorImpl.java)

如果你的應用有自己的 Base Repository, 則該 Base Repository 必須改成實作 `QueryBySpecExecutorImpl`, 如:
由於 Java 只能單一繼承, 為了方便應用程式可以保留原有的 Parent Base Repository, QBS 還多提供了 [`QueryBySpecExecutorAdapter`](./src/main/java/tw/com/softleader/data/jpa/spec/repository/support/QueryBySpecExecutorAdapter.java) 擴展點

你的應用程式可以視情況選擇繼承 `QueryBySpecExecutorImpl` 或實作 `QueryBySpecExecutorAdapter` 去客製化 Base Repository, 如:

```java
class MyRepositoryImpl<T, ID>
extends QueryBySpecExecutorImpl<T, ID> {
class MyRepositoryImpl<T, ID> extends SimpleJpaRepository<T, ID>
implements QueryBySpecExecutorAdapter<T> {
@Setter
@Getter
private SpecMapper specMapper;
private final EntityManager entityManager;
Expand All @@ -84,6 +90,11 @@ class MyRepositoryImpl<T, ID>
this.entityManager = entityManager;
}
@Override
public Class<T> getDomainClass() {
return super.getDomainClass();
}
@Transactional
public <S extends T> S mySave(S entity) {
// implementation goes here
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
import tw.com.softleader.data.jpa.spec.SpecificationResolver.SpecificationResolverBuilder;
import tw.com.softleader.data.jpa.spec.SpecificationResolverCodecBuilder;
import tw.com.softleader.data.jpa.spec.repository.support.JpaRepositoryFactoryBeanPostProcessor;
import tw.com.softleader.data.jpa.spec.repository.support.QueryBySpecExecutorImpl;
import tw.com.softleader.data.jpa.spec.repository.support.QueryBySpecExecutorAdapter;

/**
* @author Matt Ho
Expand Down Expand Up @@ -108,16 +108,17 @@ RepositoryFactoryCustomizer repositoryBaseClassCustomizer(SpecMapperProperties p
@Bean
RepositoryFactoryCustomizer specMapperCustomizer(SpecMapper specMapper) {
return factory -> factory.addRepositoryProxyPostProcessor(
(proxyFactory, repositoryInformation) -> getQueryBySpecExecutorImpl(proxyFactory)
(proxyFactory, repositoryInformation) -> getQueryBySpecExecutorAdapter(proxyFactory)
.ifPresent(target -> target.setSpecMapper(specMapper)));
}

@SneakyThrows
@SuppressWarnings({ "rawtypes" })
private Optional<QueryBySpecExecutorImpl> getQueryBySpecExecutorImpl(ProxyFactory factory) {
private Optional<QueryBySpecExecutorAdapter> getQueryBySpecExecutorAdapter(
ProxyFactory factory) {
return ofNullable(factory.getTargetSource().getTarget())
.filter(QueryBySpecExecutorImpl.class::isInstance)
.map(QueryBySpecExecutorImpl.class::cast);
.filter(QueryBySpecExecutorAdapter.class::isInstance)
.map(QueryBySpecExecutorAdapter.class::cast);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import tw.com.softleader.data.jpa.spec.repository.support.QueryBySpecExecutorAdapter;
import tw.com.softleader.data.jpa.spec.repository.support.QueryBySpecExecutorImpl;

/**
Expand All @@ -37,9 +38,11 @@ public class SpecMapperProperties {
boolean enabled = true;

/**
* Configures the repository base class. the given class must extends QueryBySpecExecutorImpl
* Configures the repository base class. the given class must implement
* QueryBySpecExecutorAdapter
*
* @see QueryBySpecExecutorAdapter
* @see QueryBySpecExecutorImpl
*/
Class<? extends QueryBySpecExecutorImpl> repositoryBaseClass = QueryBySpecExecutorImpl.class;
Class<? extends QueryBySpecExecutorAdapter> repositoryBaseClass = QueryBySpecExecutorImpl.class;
}
Original file line number Diff line number Diff line change
@@ -1,2 +1,76 @@
package tw.com.softleader.data.jpa.spec.repository.support;public interface QueryBySpecExecutorAdapter {
/*
* Copyright © 2022 SoftLeader
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 tw.com.softleader.data.jpa.spec.repository.support;

import java.util.List;
import lombok.NonNull;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.transaction.annotation.Transactional;
import tw.com.softleader.data.jpa.spec.SpecMapper;
import tw.com.softleader.data.jpa.spec.repository.QueryBySpecExecutor;

/**
* Default implementation of {@code QueryBySpecExecutor}
*
* @author Matt Ho
*/
public interface QueryBySpecExecutorAdapter<T> extends JpaSpecificationExecutor<T>,
QueryBySpecExecutor<T> {

@Override
@Transactional(readOnly = true)
default List<T> findBySpec(Object spec) {
return findAll(getSpecMapper().toSpec(spec, getDomainClass()));
}

@Override
@Transactional(readOnly = true)
default List<T> findBySpec(Object spec, @NonNull Sort sort) {
return findAll(getSpecMapper().toSpec(spec, getDomainClass()), sort);
}

@Override
@Transactional(readOnly = true)
default Page<T> findBySpec(Object spec, @NonNull Pageable pageable) {
return findAll(getSpecMapper().toSpec(spec, getDomainClass()), pageable);
}

@Override
@Transactional(readOnly = true)
default long countBySpec(Object spec) {
return count(getSpecMapper().toSpec(spec, getDomainClass()));
}

@Override
@Transactional(readOnly = true)
default boolean existsBySpec(Object spec) {
return count(getSpecMapper().toSpec(spec, getDomainClass())) > 0;
}

SpecMapper getSpecMapper();

void setSpecMapper(SpecMapper specMapper);

Class<T> getDomainClass();
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,33 +20,25 @@
*/
package tw.com.softleader.data.jpa.spec.repository.support;

import static lombok.AccessLevel.PROTECTED;

import java.io.Serializable;
import java.util.List;
import javax.persistence.EntityManager;
import lombok.Getter;
import lombok.NonNull;
import lombok.Setter;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.support.JpaEntityInformation;
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
import org.springframework.transaction.annotation.Transactional;
import tw.com.softleader.data.jpa.spec.SpecMapper;
import tw.com.softleader.data.jpa.spec.repository.QueryBySpecExecutor;

/**
* Default implementation for {@code QueryBySpecExecutor}
* Default implementation of {@code QueryBySpecExecutor}
*
* @author Matt Ho
*/
public class QueryBySpecExecutorImpl<T, ID extends Serializable> extends SimpleJpaRepository<T, ID>
implements QueryBySpecExecutor<T> {
implements QueryBySpecExecutorAdapter<T> {

@Setter
@Getter(PROTECTED)
@Getter
private SpecMapper specMapper;

public QueryBySpecExecutorImpl(
Expand All @@ -56,32 +48,7 @@ public QueryBySpecExecutorImpl(
}

@Override
@Transactional(readOnly = true)
public List<T> findBySpec(Object spec) {
return findAll(getSpecMapper().toSpec(spec, getDomainClass()));
}

@Override
@Transactional(readOnly = true)
public List<T> findBySpec(Object spec, @NonNull Sort sort) {
return findAll(getSpecMapper().toSpec(spec, getDomainClass()), sort);
}

@Override
@Transactional(readOnly = true)
public Page<T> findBySpec(Object spec, @NonNull Pageable pageable) {
return findAll(getSpecMapper().toSpec(spec, getDomainClass()), pageable);
}

@Override
@Transactional(readOnly = true)
public long countBySpec(Object spec) {
return count(getSpecMapper().toSpec(spec, getDomainClass()));
}

@Override
@Transactional(readOnly = true)
public boolean existsBySpec(Object spec) {
return count(getSpecMapper().toSpec(spec, getDomainClass())) > 0;
public Class<T> getDomainClass() {
return super.getDomainClass();
}
}

0 comments on commit 5ea8df3

Please sign in to comment.