Java 在DAO层中将方法转换为泛型方法

Java 在DAO层中将方法转换为泛型方法,java,generic-programming,Java,Generic Programming,目前,我的DAO层中有一些方法具有多个select查询。我所想的是对这三种方法都有一个通用的方法,这样它也可以用于进一步的研究。以下是我的方法 public List<Customer> findAll(){ String sql = "SELECT * FROM CUSTOMER"; List<Customer> customers = getJdbcTemplate().query(sql, new BeanPropertyRow

目前,我的DAO层中有一些方法具有多个select查询。我所想的是对这三种方法都有一个通用的方法,这样它也可以用于进一步的研究。以下是我的方法

public List<Customer> findAll(){

    String sql = "SELECT * FROM CUSTOMER";

    List<Customer> customers  = getJdbcTemplate().query(sql,
        new BeanPropertyRowMapper(Customer.class));

    return customers;
} 
公共列表findAll(){
String sql=“选择*来自客户”;
List customers=getJdbcTemplate().query(sql,
新BeanPropertyRowMapper(Customer.class));
返回客户;
} 
用于查找客户的电话号码

public List<Phone> findPhoneNumbers(int custId){

    String sql = "SELECT * FROM PHONE WHERE CUST_ID="+custId;

    List<Phone> phoneNumbers  = getJdbcTemplate().query(sql,
        new BeanPropertyRowMapper(Phone.class));

    return phoneNumbers;
} 
公共列表findPhoneNumbers(int-custId){
String sql=“从电话中选择*,其中CUST_ID=“+custId;
List phoneNumbers=getJdbcTemplate().query(sql,
新BeanPropertyRowMapper(Phone.class));
返回电话号码;
} 
等等


这些方法可以在单个泛型方法中转换,以便可以从我的服务层调用它。如果您有任何建议或想法,我们将不胜感激。

您可以使用继承来实现这一点

1)
分类客户

2)
class PhoneNumber扩展了客户

3)
类地址扩展客户

4) 将方法声明为

public List<T> findPhoneNumbers(Customer customer){ 
if(customer instanceOf PhoneNumber) {sql ="get phone number query ...."}
else if(customer instanceOf Address) {sql ="get address query ...."}
else {sql = get customer query}
}
public List findPhoneNumbers(客户){
if(电话号码的客户实例){sql=“获取电话号码查询…”
else if(客户实例of Address){sql=“get Address query…”
else{sql=get customer query}
}

现在在调用方法(ServiceLayer)中,您可以传递适当的对象以选择查询并获取结果

您可以使用泛型方法并让调用方指定类

对于
findAll

public <T> List<T> findAll(Class<T> entityClass, String tableName){

    String sql = "SELECT * FROM " + tableName;

    return getJdbcTemplate().query(sql,
        new BeanPropertyRowMapper(entityClass));

    return phoneNumbers;
} 
这将允许您的
findAll
方法如下所示:

public <T> List<T> findAll(Class<T> entityClass){

    String sql = "SELECT * FROM " + entityClass
      .getAnnotation(MappedTable.class).tableName();

    return getJdbcTemplate().query(sql,
        new BeanPropertyRowMapper(entityClass));

    return phoneNumbers;
} 
公共列表findAll(类entityClass){
String sql=“SELECT*FROM”+entityClass
.getAnnotation(MappedTable.class).tableName();
返回getJdbcTemplate().query(sql,
新BeanPropertyRowMapper(entityClass));
返回电话号码;
} 
实现
findByXyZ
将更加棘手,但您可以使用类似的方法,从调用方获取完整查询,或者使用其他基于注释的元数据

注意这类代码的复杂性增长非常快。这就是为什么考虑使用ORM工具而不是重新创建它们是一个好主意(以上只是针对问题中的简单案例的一个想法)。 如果您需要一种方法,但需要为多个数据返回
List
,为单个数据返回
T
。试试这个:

public <T> Object findAll(String sql, Class<T> clazz, bool one) {
    List<T> all = getJdbcTemplate().query(sql, new BeanPropertyRowMapper(clazz));
    return one ? all.get(0) : all;
}
公共对象findAll(字符串sql、类clazz、bool one){
List all=getJdbcTemplate();
返回一个?全部。获取(0):全部;
}

但我并不真的建议这种方法。我认为没有必要返回单个项目而不是包含单个项目的列表。

您的两种方法有不同的参数。您可以有一个单一的遗传方法
列出findAll(stringsql,Class clazz){…}
。但是,在调用该方法之前,您必须先构造sql语句。@zhh,请您在回答中详细说明哪一个方法适合这两种方法?Ashish,这应该也适用于其他类型。这不是一种通用的方法,因为还有一些其他类与Customer或PhoneNumberNest都不相关,我将其与“您可以通过使用类元数据(例如指定注释)来进一步改进它:”。@Syed我已编辑以显示完整的方法。事实上,使方法泛型不仅仅意味着返回类型。您还需要更改要查询的表名。有很多方法可以处理这个问题,其中之一就是从调用方获取完整的查询。对于
findAll
,您也可以只取表名。使用在实体类上使用的注释可以通过删除
表名
参数来简化方法…如果我有select query with JOIN在里面呢?我觉得让zhh回答来实现这一点很简单。。在之前创建SQL查询itself@Syed当然,这可能会变得非常复杂。这就是为什么我们应该坚持使用成熟的工具,比如JPA/Hibernate、GORM等。但是如果你只是想用一种简单的方法打电话,比如在你的例子中,那么这只是给你一个如何处理的想法。我很欣赏你的想法。但不幸的是,我没有权利决定使用任何ORM技术来进行集成。zhh,如果我想要有一行,比如只返回Customer对象而不是List,我该如何处理?刚才看到..这里我需要有两个方法,比如findAll和findOne,只有一个不同之处是“return result.isEmpty()?null:结果。获取(0)”;我们仍然可以优化findAll方法,对吗?是的,
findOne
依赖于
findAll
。那么,我们应该使用findOne还是findAll?我想对所有select查询使用一个方法,而不是两个方法。请参阅我的更新答案。为什么必须返回单个项目而不是包含单个项目的列表?
public <T> List<T> findAll(String sql, Class<T> clazz) {
   return getJdbcTemplate().query(sql, new BeanPropertyRowMapper(clazz));
}
String sql = "SELECT * FROM CUSTOMER";
List<Customer> customers = findAll(sql, Customer.class);
String sql = "SELECT * FROM PHONE WHERE CUST_ID="+custId;
List<Phone> phoneNumbers = findAll(sql, Phone.class);
public <T> List<T> findAll(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy,  Class<T> clazz) {
    String sql = // construct sql statement
    return getJdbcTemplate().query(sql, new BeanPropertyRowMapper(clazz));
}
public <T> T findOne(String sql, Class<T> clazz) {
    // your sql statement should contains something like "limit 1"
    List<T> result = findAll(sql, clazz);
    return result.isEmpty() ? null : result.get(0);
}
public <T> Object findAll(String sql, Class<T> clazz, bool one) {
    List<T> all = getJdbcTemplate().query(sql, new BeanPropertyRowMapper(clazz));
    return one ? all.get(0) : all;
}