英文:
Is there a way to make a Java method that maps an SQL result list to an entity class generic?
问题
以下是翻译好的部分:
我有这个成功执行本地 SQL 查询的方法。没有问题。它将查询的结果列表映射到相关的实体类:
@Data
public class DemoManager {
Transaction transaction;
static Session session;
Query query;
DemoEntity demoResultList;
String url = "...";
String username = "...";
String password = "...";
Class<DemoEntity> demoEntity = DemoEntity.class;
public void executiveQuery(String sql) {
session = Base.getSessionFactory(url, username, password, demoEntity).openSession();
transaction = session.beginTransaction();
query = session.createNativeQuery(sql, demoEntity);
demoResultList = (DemoEntity) query.getResultList().get(0);
session.close();
}
现在的问题是,我想将 `executiveQuery()` 方法变成通用的,这样当它被调用时,可以传递任何实体类作为参数,而不是每次出现新的实体时都要创建一个新方法。为了尝试实现这一点,我尝试了这样:
...
public static Class<T> resultList;
Class<T> entity;
...
public <T> void executiveQuery(String sql, Class<T> entity) {
session = Base.getSessionFactory(url, username, password, entity).openSession();
transaction = session.beginTransaction();
query = session.createNativeQuery(sql, entity);
resultList = (entity) query.getResultList().get(0); // 这一行上的实体无法编译
session.close();
}
我无法使该方法编译。我应该如何使 `executiveQuery()` 通用,以接受任何实体类,以便我可以像这样在 `returnList` 中获取数据库列:
public String getTestColmn() {
return resultList.getTestId();
}
然后调用 `executeQuery()` 并传递任何实体类给它,可能是这样的:
public void callExecuteQuery(String sql, Class<T> entity) {
demoManager.executeQuery(sql, DemoEntity.class);
}
我做错了什么?
如果您需要更多帮助或其他翻译,请告诉我。
英文:
I have this method that executes a native SQL query successfully. No issues. It maps the result list from the query to the relevant entity class:
@Data
public class DemoManager {
Transaction transaction;
static Session session;
Query query;
DemoEntity demoResultList;
String url = "...";
String username = "...";
String password = "...";
Class<DemoEntity> demoEntity = DemoEntity.class;
public void executiveQuery(String sql) {
session = Base.getSessionFactory(url, username, password, demoEntity).openSession();
transaction = session.beginTransaction();
query = session.createNativeQuery(sql, demoEntity);
demoResultList = (DemoEntity) query.getResultList().get(0);
session.close();
}
Now, the problem. I want to make the executeQuery()
method generic, so that when it is called, any entity class can be passed as an argument, instead of creating a new method whenever there is a new entity. To try achieve that, I tried this:
...
public static Class<T> resultList;
Class<T> entity;
...
public <T> void executiveQuery(String sql, Class<T> entity) {
session = Base.getSessionFactory(url, username, password, entity).openSession();
transaction = session.beginTransaction();
query = session.createNativeQuery(sql, entity);
resultList = (entity) query.getResultList().get(0); // the entity on this line could not be compiled
session.close();
}
I couldn't get that method to compile. How do I make the executiveQuery()
generic to accept any entity class so that I can get my database column returned in returnList
like this:
public String getTestColmn() {
return resultList.getTestId();
}
And then call executeQuery()
and pass any entity class to it, perhaps something like this:
public void callExecuteQuery(String sql, Class<T> entity) {
demoManager.executeQuery(sql, DemoEntity.class);
}
What am I doing wrong?
答案1
得分: 1
要使方法通用,你需要使类也成为泛型。
public class DemoManager<T> {
T resultList;
@SuppressWarnings("unchecked")
public void executiveQuery(String sql) {
...
resultList = (T) query.getResultList().get(0);
...
}
}
...
// 并且你需要更改创建 `DemoManager` 的方式
DemoManager<DemoEntity> demoManager = new DemoManager<>();
demoManager.executiveQuery(sql);
String testColumn = demoManager.getResultList().getTestColmn();
请注意,如果在进行类型转换时出现类型不匹配,它将在运行时抛出错误。
另一种选择是将 executiveQuery
设为静态方法,并将 session
和泛型类作为参数传递。
public class DemoManager {
@SuppressWarnings("unchecked")
public <T> static T executiveQuery(Session session, String sql, Class<T> entity) {
transaction = session.beginTransaction();
query = session.createNativeQuery(sql, demoEntity);
return (T) query.getResultList().get(0);
}
}
...
Session session = ...;
DemoEntity entity = DemoManager.executiveQuery(session, sql, DemoEntity.class);
String testColumn = entity.getTestColumn();
英文:
To make a method generic you need the class to be generic as well
public class DemoManager<T> {
T resultList;
@SuppressWarnings("unchecked")
public void executiveQuery(String sql) {
...
resultList = (T) query.getResultList().get(0);
...
}
}
...
// And you need to change the creation of the `DemoManager`
DemoManager<DemoEntity> demoManager = new DemoManager<>(...);
demoManager.executiveQuery(sql);
String testColumn = demoManager.getResultList().getTestColmn();
Noting that if there is a type mismatch during the casting it will throw an error at runtime.
Another option is to have the executeQuery
as static and get the session
and the generic class as parameters
public class DemoManager {
@SuppressWarnings("unchecked")
public <T> static T executiveQuery(Session session, String sql, Class<T> entity) {
transaction = session.beginTransaction();
query = session.createNativeQuery(sql, demoEntity);
return (entity) query.getResultList().get(0);
}
}
...
Session session = ...;
DemoEntity entity = DemoManager.executiveQuery(session, sql, DemoEntity.class);
String testColumn = entity.getTestColumn();
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论