Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 关于: 在常规的@Repository界面中定义自定义方法(除了Spring数据方法之外) 在任何地方(甚至不需要在同一个包中)创建一个类MyEntityRepositoryImpl(@Impl后缀是魔法),该类只实现自定义方法,并注释@Component**(@Repository将不起作用)。 这个类甚至可以通过@Autowired注入MyEntityRepository,以便在自定义方法中使用 例子:_Java_Spring Data_Spring Data Jpa - Fatal编程技术网

Java 关于: 在常规的@Repository界面中定义自定义方法(除了Spring数据方法之外) 在任何地方(甚至不需要在同一个包中)创建一个类MyEntityRepositoryImpl(@Impl后缀是魔法),该类只实现自定义方法,并注释@Component**(@Repository将不起作用)。 这个类甚至可以通过@Autowired注入MyEntityRepository,以便在自定义方法中使用 例子:

Java 关于: 在常规的@Repository界面中定义自定义方法(除了Spring数据方法之外) 在任何地方(甚至不需要在同一个包中)创建一个类MyEntityRepositoryImpl(@Impl后缀是魔法),该类只实现自定义方法,并注释@Component**(@Repository将不起作用)。 这个类甚至可以通过@Autowired注入MyEntityRepository,以便在自定义方法中使用 例子:,java,spring-data,spring-data-jpa,Java,Spring Data,Spring Data Jpa,实体类别(完整性): 存储库接口: public class AccountRepositoryImpl implements AccountRepositoryCustom { @Autowired @Lazy AccountRepository accountRepository; /* Optional - if you need it */ public void customMethod() { ... } } package myapp.dom

实体类别(完整性):

存储库接口:

public class AccountRepositoryImpl implements AccountRepositoryCustom {

    @Autowired
    @Lazy
    AccountRepository accountRepository;  /* Optional - if you need it */

    public void customMethod() { ... }
}
package myapp.domain.myentity;

@Repository
public interface MyEntityRepository extends JpaRepository<MyEntity, Long> {

    // EXAMPLE SPRING DATA METHOD
    List<MyEntity> findByCommentEndsWith(String x);

    List<MyEntity> doSomeHql(Long id);   // custom method, code at *Impl class below

    List<MyEntity> useTheRepo(Long id);  // custom method, code at *Impl class below

}
public interface UserCustomRepository {
 List<User> findAllUsersBySomeCriteria(UserCriteriaRequest criteriaRequest);
}
就这样,除了您已经拥有的SpringDataRepo接口之外,不需要任何其他接口


我发现的唯一可能的缺点是:

  • Impl
    类中的自定义方法被编译器标记为未使用,因此
    @SuppressWarnings(“未使用”)
    建议
  • 您有一个
    Impl
    类的限制。(而在常规片段接口实现中,您可以有很多。)
  • 如果您将
    Impl
    类放在不同的包中,并且您的测试只使用
    @DataJpaTest
    ,那么您必须将
    @ComponentScan(“package.of.the.Impl.clazz”)
    添加到测试中,以便Spring加载它

向所有存储库添加自定义行为:

要向所有存储库添加自定义行为,首先添加一个中间接口来声明共享行为

public interface MyRepository <T, ID extends Serializable> extends JpaRepository<T, ID>
{
    
    void sharedCustomMethod( ID id );
}
公共接口MyRepository扩展了JpaRepository
{
作废sharedCustomMethod(ID);
}
现在,您的各个存储库接口将扩展此中间接口,而不是存储库接口,以包括声明的功能

接下来,创建一个中间接口的实现,该接口扩展了特定于持久性技术的存储库基类。然后,此类将充当存储库代理的自定义基类

public class MyRepositoryImpl <T, ID extends Serializable> extends SimpleJpaRepository<T, ID> implements MyRepository<T, ID>
{
    
    private EntityManager entityManager;
    
       // There are two constructors to choose from, either can be used.
    public MyRepositoryImpl(Class<T> domainClass, EntityManager entityManager)
    {
        super( domainClass, entityManager );
        
        // This is the recommended method for accessing inherited class dependencies.
        this.entityManager = entityManager;
    }
    
    
    public void sharedCustomMethod( ID id )
    {
        // implementation goes here
    }
}
公共类MyRepositoryImpl扩展了SimpleParepository实现MyRepository
{
私人实体管理者实体管理者;
//有两个构造函数可供选择,任何一个都可以使用。
公共MyRepositoryImpl(类domainClass,EntityManager EntityManager)
{
超级(域类、实体管理器);
//这是访问继承的类依赖项的推荐方法。
this.entityManager=entityManager;
}
公共无效sharedCustomMethod(ID)
{
//实现就在这里
}
}


我使用SimpleParepository作为存储库实现的基类,并在接口中添加自定义方法,例如:

public interface UserRepository  {
    User FindOrInsert(int userId);
}

@Repository
public class UserRepositoryImpl extends SimpleJpaRepository implements UserRepository {

    private RedisClient redisClient;

    public UserRepositoryImpl(RedisClient redisClient, EntityManager em) {
        super(User.class, em);
        this.redisClient = redisClient;
    }


@Override
public User FindOrInsert(int userId) {

    User u = redisClient.getOrSet("test key.. User.class, () -> {
        Optional<User> ou = this.findById(Integer.valueOf(userId));
        return ou.get();
    });
    …………
    return u;
}
公共接口用户存储库{
用户FindOrInsert(int userId);
}
@存储库
公共类UserRepositoryImpl扩展了SimpleParepository实现了UserRepository{
私人再贴现客户;
公共用户RepositoryImpl(RedisClient、EntityManager em){
super(User.class,em);
this.redisClient=redisClient;
}
@凌驾
公共用户FindOrInsert(int userId){
用户u=redisClient.getOrSet(“测试键..User.class,()->”{
可选ou=this.findById(Integer.valueOf(userId));
返回ou.get();
});
…………
返回u;
}

我喜欢Danila的解决方案并开始使用它,但团队中没有人喜欢为每个存储库创建4个类。Danila的解决方案是这里唯一一个让您在Impl类中使用Spring数据方法的解决方案。不过,我找到了一种只使用一个类的方法:

public interface UserRepository extends MongoAccess, PagingAndSortingRepository<User> {

    List<User> getByUsername(String username);


    default List<User> getByUsernameCustom(String username) {
        // Can call Spring Data methods!
        findAll();

        // Can write your own!
        MongoOperations operations = getMongoOperations();
        return operations.find(new Query(Criteria.where("username").is(username)), User.class);
    }
}
其中BeanAccessor是:

@Component
public class BeanAccessor implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    public static <T> T getSingleton(Class<T> clazz){
        return applicationContext.getBean(clazz);
    }

    public static <T> T getSingleton(String beanName, Class<T> clazz){
        return applicationContext.getBean(beanName, clazz);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        BeanAccessor.applicationContext = applicationContext;
    }

}
@组件
公共类BeanAccessor实现ApplicationContextAware{
私有静态应用上下文应用上下文;
公共静态T getSingleton(类clazz){
返回applicationContext.getBean(clazz);
}
公共静态T getSingleton(字符串beanName,类clazz){
返回applicationContext.getBean(beanName,clazz);
}
@凌驾
public void setApplicationContext(ApplicationContext ApplicationContext)抛出BeansException{
BeanAccessor.applicationContext=applicationContext;
}
}

不幸的是,您不能在接口中使用@Autowire。您可以将bean自动连接到MongoAccessImpl中,并在接口中提供访问它的方法,但Spring数据崩溃了。我认为它甚至不希望看到与PagingAndSortingRepository间接关联的Impl。

我在使用mongo和Spring时遇到了这个问题。所以让我们假设we使用MongoRepository提供基本crud操作,假设我们需要使用mongoTemplate实现一些自定义条件查询操作。要实现一个接口来为crud和自定义注入存储库,我们需要指定:

自定义接口:

public class AccountRepositoryImpl implements AccountRepositoryCustom {

    @Autowired
    @Lazy
    AccountRepository accountRepository;  /* Optional - if you need it */

    public void customMethod() { ... }
}
package myapp.domain.myentity;

@Repository
public interface MyEntityRepository extends JpaRepository<MyEntity, Long> {

    // EXAMPLE SPRING DATA METHOD
    List<MyEntity> findByCommentEndsWith(String x);

    List<MyEntity> doSomeHql(Long id);   // custom method, code at *Impl class below

    List<MyEntity> useTheRepo(Long id);  // custom method, code at *Impl class below

}
public interface UserCustomRepository {
 List<User> findAllUsersBySomeCriteria(UserCriteriaRequest criteriaRequest);
}
公共接口UserCustomRepository{
列出findAllUsersBySomeCriteria(UserCriteriaRequest-criteriaRequest);
}
UserRepository接口“必须”首先扩展UserCustomRepository,然后扩展MongoRepository

@Repository
public interface UserRepository extends UserCustomRepository, MongoRepository<User, ObjectId> {
}
@存储库
公共接口UserRepository扩展了UserCustomRepository,MongoRepository{
}
UserRepositoryImpl必须与带有*Impl后缀的crud接口具有相同的名称

@Component
@NoArgsConstructor
@AllArgsConstructor(onConstructor = @__(@Autowired))
public class UserRepositoryImpl implements UserCustomRepository {

 private MongoTemplate mongoTemplate;

 @Override
 public List<User> findAllUsersBySomeCriteria(UserCriteriaRequest criteriaRequest){
  //some impl
 }
}
@组件
@诺尔格构装师
@AllArgsConstructor(onConstructor=@_uuz(@Autowired))
公共类UserRepositoryImpl实现UserCustomRepository{
私有MongoTemplate MongoTemplate;
@凌驾
公共列表FindAllUserBySomeCriteria(UserCriteriaRequest-criteriaRequest){
//一些简单的
}
}
让我们impl一些服务-这里我们只注入UserRepository接口,并使用来自crud repository和自定义类impl的方法

@Service
@NoArgsConstructor
@AllArgsConstructor(onConstructor = @__(@Autowired))
public class UserService {

 private UserRepository userReposityry;

 public List<User> getUserByCriteria(UserCriteriaRequest request) {
   userRepository.findById(request.getUserId); // Crud repository method
   userRepository.findAllUsersBySomeCriteria(request); // custom method.
 }
}
@服务
@诺尔格构装师
@AllArgsConstructor(onConstructor=@_uuz(@Autowired))
公共类用户服务{
私人用户
package myapp.infrastructure.myentity;

@Component // Must be @Component !!
public class MyEntityRepositoryImpl { // must have the exact repo name + Impl !!

    @PersistenceContext
    private EntityManager entityManager;

    @Autowired
    private MyEntityRepository myEntityRepository;

    @SuppressWarnings("unused")
    public List<MyEntity> doSomeHql(Long id) {
        String hql = "SELECT eFROM MyEntity e WHERE e.id = :id";
        TypedQuery<MyEntity> query = entityManager.createQuery(hql, MyEntity.class);
        query.setParameter("id", id);
        return query.getResultList();
    }

    @SuppressWarnings("unused")
    public List<MyEntity> useTheRepo(Long id) {
        List<MyEntity> es = doSomeHql(id);
        es.addAll(myEntityRepository.findByCommentEndsWith("DO"));
        es.add(myEntityRepository.findById(2L).get());
        return es;
    }

}
// You just autowire the the MyEntityRepository as usual
// (the Impl class is just impl detail, the clients don't even know about it)
@Service
public class SomeService {
    @Autowired
    private MyEntityRepository myEntityRepository;

    public void someMethod(String x, long y) {
        // call any method as usual
        myEntityRepository.findByCommentEndsWith(x);
        myEntityRepository.doSomeHql(y);
    }
}
public interface MyRepository <T, ID extends Serializable> extends JpaRepository<T, ID>
{
    
    void sharedCustomMethod( ID id );
}
public class MyRepositoryImpl <T, ID extends Serializable> extends SimpleJpaRepository<T, ID> implements MyRepository<T, ID>
{
    
    private EntityManager entityManager;
    
       // There are two constructors to choose from, either can be used.
    public MyRepositoryImpl(Class<T> domainClass, EntityManager entityManager)
    {
        super( domainClass, entityManager );
        
        // This is the recommended method for accessing inherited class dependencies.
        this.entityManager = entityManager;
    }
    
    
    public void sharedCustomMethod( ID id )
    {
        // implementation goes here
    }
}
public interface UserRepository  {
    User FindOrInsert(int userId);
}

@Repository
public class UserRepositoryImpl extends SimpleJpaRepository implements UserRepository {

    private RedisClient redisClient;

    public UserRepositoryImpl(RedisClient redisClient, EntityManager em) {
        super(User.class, em);
        this.redisClient = redisClient;
    }


@Override
public User FindOrInsert(int userId) {

    User u = redisClient.getOrSet("test key.. User.class, () -> {
        Optional<User> ou = this.findById(Integer.valueOf(userId));
        return ou.get();
    });
    …………
    return u;
}
public interface UserRepository extends MongoAccess, PagingAndSortingRepository<User> {

    List<User> getByUsername(String username);


    default List<User> getByUsernameCustom(String username) {
        // Can call Spring Data methods!
        findAll();

        // Can write your own!
        MongoOperations operations = getMongoOperations();
        return operations.find(new Query(Criteria.where("username").is(username)), User.class);
    }
}
public interface MongoAccess {
    default MongoOperations getMongoOperations() {
        return BeanAccessor.getSingleton(MongoOperations.class);
    }
}
@Component
public class BeanAccessor implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

    public static <T> T getSingleton(Class<T> clazz){
        return applicationContext.getBean(clazz);
    }

    public static <T> T getSingleton(String beanName, Class<T> clazz){
        return applicationContext.getBean(beanName, clazz);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        BeanAccessor.applicationContext = applicationContext;
    }

}
public interface UserCustomRepository {
 List<User> findAllUsersBySomeCriteria(UserCriteriaRequest criteriaRequest);
}
@Repository
public interface UserRepository extends UserCustomRepository, MongoRepository<User, ObjectId> {
}
@Component
@NoArgsConstructor
@AllArgsConstructor(onConstructor = @__(@Autowired))
public class UserRepositoryImpl implements UserCustomRepository {

 private MongoTemplate mongoTemplate;

 @Override
 public List<User> findAllUsersBySomeCriteria(UserCriteriaRequest criteriaRequest){
  //some impl
 }
}
@Service
@NoArgsConstructor
@AllArgsConstructor(onConstructor = @__(@Autowired))
public class UserService {

 private UserRepository userReposityry;

 public List<User> getUserByCriteria(UserCriteriaRequest request) {
   userRepository.findById(request.getUserId); // Crud repository method
   userRepository.findAllUsersBySomeCriteria(request); // custom method.
 }
}