zhangzhenhuajack / spring-data-jpa-guide

spring-data-jpa-guide,Spring Data JPA实战,SpringDataJpa详解
http://www.jackzhang.cn/spring-data-jpa-guide/
363 stars 157 forks source link

entityName动态entity的使用例子 #41

Open zhangzhenhuajack opened 2 years ago

zhangzhenhuajack commented 2 years ago

公共GenericTokenRepository

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.NoRepositoryBean;
import org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Transactional;

import java.time.Instant;
import java.util.List;
import java.util.Optional;

/**
 * GenericTokenRepository 共同接口
 *
 * @param <T> UserToken/TeacherToken  这两个实体公用一个GenericTokenRepository
 */
@NoRepositoryBean
public interface GenericTokenRepository<T extends GenericToken> extends JpaRepository<T, Long> {
    /**
     * 根据 token 查找 UserToken
     *
     * @param token
     * @return
     */
    Optional<T> findByToken(String token);

    /**
     * 查找操作
     * @param userId
     * @param  expiresInBorder
     * @return
     */
    @Query(value = "select t from #{#entityName} t where t.userId = :userId and t.expiresIn > :expiresInBorder and t.deactivatedAt is null")
    List<T> findValidTokens(@Param("userId") Long userId, @Param("expiresInBorder") Long expiresInBorder);

    /**
     * 更新操作
     * @param ids
     * @param reason
     * @param deactivatedAt
     */
    @Modifying
    @Query(value = "update #{#entityName} set deactivationReason = :deactivationReason, deactivatedAt = :deactivatedAt where id in :ids and deactivatedAt is null")
    @Transactional
    void expireTokensWithReason(@Param("ids") Iterable<Long> ids, @Param("deactivationReason") DeactivationReason reason,
                                @Param("deactivatedAt") Instant deactivatedAt);

}

GenericTokenRepository的两个子类

public interface UserTokenRepository extends GenericTokenRepository<UserToken> {
}
public interface TeacherTokenRepository extends GenericTokenRepository<TeacherToken> {
}

GenericToken父类实体

import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;

import javax.persistence.*;
import java.time.Instant;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;

@Getter
@Setter
@EqualsAndHashCode(of = {"id"}, callSuper = true)
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class GenericToken {
    @Id
    @Override
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private Instant createdAt;
    private Instant updatedAt;
    private Integer version;
    private Long refreshTokenId;
    private String serviceName;
    private String token;
    private Long expiresIn;
    private Instant deactivatedAt;
    private Long userId;
    private String uuid;
}

TeacherToken 和 UserToken 代表两个表,其中teacher的字段有一个不一样

@Getter
@Setter
@Entity
@Table(name = "tpuser_tokens")
@AttributeOverride(name = "userId", column = @Column(name = "teacher_id"))
public class TeacherToken extends GenericToken{
}
@Getter
@Setter
@Entity
@Table(name = "user_tokens")
public class UserToken extends GenericToken {
}

使用的时候,不同的业务逻辑调用各自的Repository 即可