将ResultSet转换为泛型类,其中类构造函数是通过工厂定义的

时间:2018-10-11 14:38:58

标签: java mysql design-patterns factory

我已经定义了一种方法,可以将MySQl选择查询的结果解析为通用类。

此方法如下:

df0 %>%
  group_by(x1, x2) %>%
  summarise(y = sum(y)) %>%
  mutate(share_in_group = y / sum(y)) %>%
  ungroup() %>%
  mutate(share_all_df = y / sum(y))
#> # A tibble: 4 x 5
#>   x1    x2        y share_in_group share_all_df
#>   <fct> <fct> <dbl>          <dbl>        <dbl>
#> 1 A     a        12          0.857       0.255 
#> 2 A     b         2          0.143       0.0426
#> 3 B     a        10          0.303       0.213 
#> 4 B     b        23          0.697       0.489

我用它来对我已为其定义架构的两个数据库表执行选择。

以前,我已经定义了上述功能适用的架构。全班看起来像这样。

public <T> List<T> selectFromDb(Class<T> _class, String tableName,
                                     String searchKeyName, String searchKeyValue)
    throws SQLException, IllegalAccessException,
    InstantiationException, NoSuchMethodException, InvocationTargetException, ClassNotFoundException {

    List<T> listDbData = new ArrayList<>();

    final String selectQuery = String.format("select * from %s.%s where %s = ?;",
        schemaName, tableName, searchKeyName);
    PreparedStatement selectStatement = connection.prepareStatement(selectQuery);

    try {
        selectStatement.setString(1, searchKeyValue);
        ResultSet result = selectStatement.executeQuery();
        while (result.next()) {

            T t = _class.getDeclaredConstructor(ResultSet.class).newInstance(result);

            listDbData.add(t);
        }

        selectStatement.close();
    }catch (SQLException e) {
        log.error("Query failed:" + selectQuery);
        throw e;
    } finally {
        selectStatement.close();
    }

    return listDbData;
}

现在,我定义了一个工厂以使该类不可变。我想知道如何修改selectFromDb代码以处理修改后的类。

   @Getter //lombok
   @Setter
    public class C extends A {
        private String varA;
        private String varB;
        private String varC;


       public C(String s1, String s2) {
        ...
        ...
       }

       public C (ResultSet resultSet) {
       ....
       ...
       }

       //Other class methods

    }

谢谢。 斯瓦加蒂卡

1 个答案:

答案 0 :(得分:1)

您声明

public <T> List<T> selectFromDb(Function<ResultSet,T> factory, String tableName,
                                 String searchKeyName, String searchKeyValue)

您通过创建实例

while (result.next()) {

    T t = factory.apply(result);

    listDbData.add(t);
}

您打电话给的

selectFromDb(CFactory::from, searchKeyName, searchKeyValue);

实际上,您本来可以做到这一点,并通过YourClass::new作为对通过反射在代码中检索的构造函数的方法引用。

作为旁注,您可以保留构造函数-不会使您的类不那么不变。此外,为什么不使用工厂方法static? (我的代码示例假设是这样)