如何使用具有 Java Spring 的泛型类型来实现存储库模式
How can I implement the Repository pattern using Generic Types with Java Spring
我正在尝试找到一种方法,我可以使用 spring 引导和通用类型来实现存储库模式。到目前为止,我查看了这篇文章:
https://thoughts-on-java.org/implementing-the-repository-pattern-with-jpa-and-hibernate/
并尝试根据此问题的解决方案使用泛型类型实施此解决方案:
我尝试使用 JPA 和 Hibernate 这样做,但对我来说,当我尝试 return 指定类型参数上实体的 class 时出现错误。
以下是我使用 JPA 和 Hibernate 的用户模型:
package models;
import javax.persistence.*;
@Entity
public class User extends Model {
@Id
@Column(name = "id", updatable = false, nullable = false)
private String id;
public String username;
private String password;
public User(String username, String password) {
super();
this.username = username;
this.password = password;
}
public String getPassword() {
return password;
}
}
下面是我的基本CRUD操作界面:
package repositories;
import models.Model;
import java.util.UUID;
public interface IRepository<T> {
void add(T entity);
void delete(String id);
void update(T entity);
T get(String id);
boolean exists(String id);
}
然后我为所有存储库创建了一个摘要 class 以避免为所有模型重复我自己。
package repositories;
import models.Model;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
public abstract class Repository<T> implements IRepository<T>{
private EntityManager em;
public Repository(EntityManager em){
this.em = em;
}
@Override
public void add(T entity) {
em.persist(entity);
}
@Override
public void delete(String id) {
T entity = get(id);
em.remove(entity);
}
@Override
public void update(T entity) {
em.merge(entity);
}
@Override
public T get(String id) {
return em.find(getEntityClass(), id);
}
public boolean exists(String id) {
return em.contains(get(id));
}
// link to an explanation can be found at:
// when a class extends this class, all is needed is to fill out the method body of to return the class.
public abstract Class<T> getEntityClass();
}
摘要 class 是我 return 属于 T
的 class
这是用户的特定存储库:
package repositories;
import models.Model;
import models.User;
import javax.persistence.EntityManager;
public class UserRepository<User> extends Repository<User> {
public UserRepository(EntityManager em) {
super(em);
}
@Override
public Class<User> getEntityClass() {
return null;
}
}
理想情况下,对于 getEntityClass 方法,我想 return User.class,但我在 IDE 上收到错误消息 "Cannot select from type variable" .我在网上看了几个问题,人们尝试的另一件事是在用户存储库中放置一个类型为 Class 的参数或有一个类型为 Class 的成员。我尝试了两种方法,但都没有用,有什么想法吗?
class UserRepository<User>
应该只是 class UserRepository
。否则,User
就像 T
一样,是一个通用类型。不是 class User
.
但你正在重新发明轮子。学习和使用 Spring Data JPA,它带来了通用存储库等。
我正在尝试找到一种方法,我可以使用 spring 引导和通用类型来实现存储库模式。到目前为止,我查看了这篇文章:
https://thoughts-on-java.org/implementing-the-repository-pattern-with-jpa-and-hibernate/
并尝试根据此问题的解决方案使用泛型类型实施此解决方案:
我尝试使用 JPA 和 Hibernate 这样做,但对我来说,当我尝试 return 指定类型参数上实体的 class 时出现错误。
以下是我使用 JPA 和 Hibernate 的用户模型:
package models;
import javax.persistence.*;
@Entity
public class User extends Model {
@Id
@Column(name = "id", updatable = false, nullable = false)
private String id;
public String username;
private String password;
public User(String username, String password) {
super();
this.username = username;
this.password = password;
}
public String getPassword() {
return password;
}
}
下面是我的基本CRUD操作界面:
package repositories;
import models.Model;
import java.util.UUID;
public interface IRepository<T> {
void add(T entity);
void delete(String id);
void update(T entity);
T get(String id);
boolean exists(String id);
}
然后我为所有存储库创建了一个摘要 class 以避免为所有模型重复我自己。
package repositories;
import models.Model;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
public abstract class Repository<T> implements IRepository<T>{
private EntityManager em;
public Repository(EntityManager em){
this.em = em;
}
@Override
public void add(T entity) {
em.persist(entity);
}
@Override
public void delete(String id) {
T entity = get(id);
em.remove(entity);
}
@Override
public void update(T entity) {
em.merge(entity);
}
@Override
public T get(String id) {
return em.find(getEntityClass(), id);
}
public boolean exists(String id) {
return em.contains(get(id));
}
// link to an explanation can be found at:
// when a class extends this class, all is needed is to fill out the method body of to return the class.
public abstract Class<T> getEntityClass();
}
摘要 class 是我 return 属于 T
的 class这是用户的特定存储库:
package repositories;
import models.Model;
import models.User;
import javax.persistence.EntityManager;
public class UserRepository<User> extends Repository<User> {
public UserRepository(EntityManager em) {
super(em);
}
@Override
public Class<User> getEntityClass() {
return null;
}
}
理想情况下,对于 getEntityClass 方法,我想 return User.class,但我在 IDE 上收到错误消息 "Cannot select from type variable" .我在网上看了几个问题,人们尝试的另一件事是在用户存储库中放置一个类型为 Class 的参数或有一个类型为 Class 的成员。我尝试了两种方法,但都没有用,有什么想法吗?
class UserRepository<User>
应该只是 class UserRepository
。否则,User
就像 T
一样,是一个通用类型。不是 class User
.
但你正在重新发明轮子。学习和使用 Spring Data JPA,它带来了通用存储库等。