Java 在冬眠和节俭之间转换

Java 在冬眠和节俭之间转换,java,generics,Java,Generics,这与冬眠和节俭本身无关 我正在开发一个Java应用程序,通过Hibernate从数据库获取数据,并希望通过apache thrift服务为这些对象提供服务。到目前为止,我只有很少的模型,但对于每一个模型,我都必须遍历hibernate对象列表并构建节约对象列表 例如,考虑下面几段代码(这是节约服务处理程序,它将Hibernate集合作为IN并返回节俭集合): @覆盖 公共列表GetUserOutlets(int user_id)引发异常{ 列表结果=this.dataProvider.getOu

这与冬眠和节俭本身无关

我正在开发一个Java应用程序,通过Hibernate从数据库获取数据,并希望通过apache thrift服务为这些对象提供服务。到目前为止,我只有很少的模型,但对于每一个模型,我都必须遍历hibernate对象列表并构建节约对象列表

例如,考虑下面几段代码(这是节约服务处理程序,它将Hibernate集合作为IN并返回节俭集合):

@覆盖
公共列表GetUserOutlets(int user_id)引发异常{
列表结果=this.dataProvider.getOutcomesByUserId(用户id);
列表结果=新建ArrayList();
for(Iterator Iterator=outlets.Iterator();Iterator.hasNext();){
结果=(结果)迭代器.next();
TOutcome t_结果=新TOutcome(
(double)(Math.round(output.getAmount()*100))/100,
output.getUser().getName(),
字符串.valueOf(output.getCategory().getName());
t_output.setComment(output.getComment());
结果。添加(t_结果);
}
返回结果;
}
@凌驾
公共列表GetUserIncoments(int user_id)引发异常{
List incomes=this.dataProvider.getIncomesByUserId(用户id);
列表结果=新建ArrayList();
for(Iterator Iterator=increments.Iterator();Iterator.hasNext();){
收入=(收入)迭代器.next();
TIncome t_收入=新TIncome(
(双精度)(数学四舍五入(income.getAmount()*100))/100,
income.getUser().getName(),
字符串.valueOf(income.getCategory().getName());
t_income.setComment(income.getComment());
结果。加上(t_收入);
}
返回结果;
}
Outcome
Income
-这些是Hibernate注释类,
toutcom
TIncome
-是相关的节俭对象(共享80-90%的字段)

“干燥”原则现在被违反了,因为这个代码非常非常相似。我想提供一种迭代hibernate对象并返回thrift对象的通用方法。我在考虑泛型和设计模式


在动态语言中,我可以只使用字符串来构建类名和对象(没有类型检查)。我想在Java中也有可能使用泛型做类似的事情,但我不确定从哪里开始。

因为我看到只有大约10行代码是常见的,它们是偶然出现的,而不是业务需求。当然,您可以重构代码来提取几个接口:一个供数据提供者在
getOutcomesByUserId
getIncomesByUserId
之间进行选择,另一个供对象工厂选择-要么
newtincome
要么
newtoutcome
。或者使用反射。然而,这些代码变体看起来更复杂,更难支持。我认为现在已经足够好了,不值得改变。最好使用
for(Income:incomes)
而不是迭代器样板


但是,如果您要映射复杂但相似的数据结构,则有些库可以显著简化映射,例如,请查看。

,因为我看到只有大约10行代码是常见的,而且它们是偶然出现的,而不是根据业务需求。当然,您可以重构代码来提取几个接口:一个供数据提供者在
getOutcomesByUserId
getIncomesByUserId
之间进行选择,另一个供对象工厂选择-要么
newtincome
要么
newtoutcome
。或者使用反射。然而,这些代码变体看起来更复杂,更难支持。我认为现在已经足够好了,不值得改变。最好使用
for(Income:incomes)
而不是迭代器样板


但是,如果要映射复杂但相似的数据结构,有些库可以显著简化映射,例如,请查看。

能否重构代码以使用一个类来映射结果和收入公共数据?您可以使用继承或混合,但这并不是那么容易。[1] thrift中没有继承,而且[2]其他模型彼此不太相似(用户、类别和结果-几乎没有共同点-但迭代内容是相同的)。您可以使用Java反射设计一个组合,假设字段具有相同的名称或某些匹配元素来帮助您,但我认为@kan的建议可能有助于你更好地了解不同的模型有完全不同的领域(用户和收入——没有共同点)。你们不认为工厂+继承比只继承更好吗?它有一个方法
translate
被不同的参数类型覆盖:
translate(output)->toutcom
translate(Income)->TIncome
translate(User)->TUser
,等等。如果我设法为Hibernate和Thrift数据对象找到基类,继承将简化集合的迭代。您能重构代码以使用一个类来处理结果和收入公共数据吗?您可以使用继承或混合,但这并不是那么容易。[1] thrift中没有继承,而且[2]其他模型彼此不太相似(用户、类别和结果-几乎没有共同点-但迭代内容是相同的)。您可以使用Java反射设计一个组合,假设字段具有相同的名称或某些匹配元素来帮助您,但我认为@kan的建议可能有助于你更好地了解不同的模型有完全不同的领域(用户和收入——没有共同点)。你们不认为工厂+继承比只继承更好吗?它有一个方法
translate
被不同的参数类型覆盖:
translate(output)->toutcom
trans
@Override
public List<TOutcome> getUserOutcomes(int user_id) throws TException {
    List<Outcome> outcomes = this.dataProvider.getOutcomesByUserId(user_id);
    List<TOutcome> result = new ArrayList<>();
    for (Iterator iterator = outcomes.iterator(); iterator.hasNext();) {
        Outcome outcome = (Outcome) iterator.next();
        TOutcome t_outcome = new TOutcome(
                (double) (Math.round(outcome.getAmount() * 100)) / 100,
                outcome.getUser().getName(),
                String.valueOf(outcome.getCategory().getName()));
        t_outcome.setComment(outcome.getComment());
        result.add(t_outcome);
    }
    return result;
}

@Override
public List<TIncome> getUserIncomes(int user_id) throws TException {
    List<Income> incomes = this.dataProvider.getIncomesByUserId(user_id);
    List<TIncome> result = new ArrayList<>();
    for (Iterator iterator = incomes.iterator(); iterator.hasNext();) {
        Income income = (Income) iterator.next();
        TIncome t_income = new TIncome(
                (double) (Math.round(income.getAmount() * 100)) / 100,
                income.getUser().getName(),
                String.valueOf(income.getCategory().getName()));
        t_income.setComment(income.getComment());
        result.add(t_income);
    }
    return result;
}