0

在 spring 中使用 hibernate 时,通常我们将代码编写为如下所示的接口

public interface UserRepository {
    Collection<User> findByLastName(String lastName) throws DataAccessException;
    //more methods
}

@Repository
public class JpaUserRepositoryImpl implements UserRepository {
    @PersistenceContext
    private EntityManager em;
    
    @SuppressWarnings("unchecked")
    public Collection<User> findByLastName(String lastName) {
        Query query = this.em.createQuery("SELECT DISTINCT user FROM User user  WHERE user.lastName LIKE :lastName");
        query.setParameter("lastName", lastName + "%");
        return query.getResultList();
    }
}
@Entity
@Table(name = "users")
public class User {
..
}

我们如何在 Panache 中做同样的事情?

public interface UserRepository extends PanacheRepositoryBase<User, Integer> {

    Collection<User> findByLastName(String lastName) ;
    //more methods
}

@ApplicationScoped
public class JpaUserRepositoryImpl implements UserRepository {

    @Inject
    private EntityManager em;

    @SuppressWarnings("unchecked")
    public Collection<User> findByLastName(String lastName) {
        Query query = this.em.createQuery("SELECT DISTINCT user FROM User user  WHERE user.lastName LIKE :lastName");
        query.setParameter("lastName", lastName + "%");
        return query.getResultList();
    }
}

它抛出

[2] Unsatisfied dependency for type javax.persistence.EntityManager and qualifiers [@Default]
        - java member: org....repository.jpa.JpaUserRepositoryImpl#em
        - declared on CLASS bean [types=[org....repository.jpa.JpaUserRepositoryImpl, org....repository.UserRepository, io.quarkus.hibernate.orm.panache.PanacheRepositoryBase<org.....model.User, java.lang.Integer>, java.lang.Object], qualifiers=[@Default, @Any], target=org.....repository.jpa.JpaUserRepositoryImpl]
[
4

1 回答 1

1

你可以让你的生活更轻松一些:

@ApplicationScoped
public class UserRepository implements PanacheRepository<User, Integer> {

   public List<User> findByLastName(String lastName) {
       return list("lastName", lastName);
   }
}

@ApplicationScoped
public class UserService {
    @Inject
    private UserRepository userRepository;

    @Transactional
    public List<User> findByLastName(String lastName) {
        return userRepository.findByLastName(lastName);
    }
}

使用 Panache,您实际上不需要使用此存储库模式(尽管您可以)。我现在喜欢的工作方式是这样的:

@Entity
// Because you have defined your own ID (Integer), you should extend PanacheEntityBase. If you don't have a specific reason for defining a custom ID, I'd recommend to extend PanacheEntity, you'll get a Long ID for free.
public class User extends PanacheEntity {
    public String lastName;
    
    public static List<User> findByLastName(String lastName) {
        return list("lastName", lastName);
    }
}

@ApplicationScoped
public class UserService {
    @Transactional
    public List<User> findByLastName(String lastName) {
        return User.findByLastName(lastName);
    }
}

请注意,当您使用 PanacheEntity 模式时,您应该将所有实例字段定义为“公共”。Panache 包装了这些字段,因此您将保留所需的封装!(因此,如果您为此字段定义自定义设置器,则当有人这样做时会调用该设置器:

user.lastName = "VanderLastName";

我不得不承认,我花了一段时间才习惯它。因此,特别是当你不想对你习惯的(Spring)有太大的改变时,你可能会更好地实现存储库模式。好消息:这完全是您自己的选择!

Quarkus 文档:https ://quarkus.io/guides/hibernate-orm-panache

于 2021-01-19T10:47:12.990 回答