【问题标题】:Room Abstract Pojo房间抽象 Pojo
【发布时间】:2018-06-24 10:05:06
【问题描述】:

我正在创建一个跟踪支出的 Android 应用程序。我正在使用 Room 来保存用户的数据,并且我有显示每日/每周/每月摘要的 POJO。

这些类非常相似,因此我想要一个抽象 POJO,其中包含重新格式化为正确格式的字段和扩展。比如:

public abstract class PeriodInformation {

PeriodInformation(@NonNull Calendar mCalendar, Integer mPeriodSpendingCount, Float mPeriodSpendingSum) {
    this.mCalendar = mCalendar;
    this.mPeriodSpendingCount = mPeriodSpendingCount;
    this.mPeriodSpendingSum = mPeriodSpendingSum;
}

@ColumnInfo(name = "DateTime")
private final Calendar mCalendar;
@ColumnInfo(name = "SpendingCount")
private Integer mPeriodSpendingCount;
@ColumnInfo(name = "SpendingSum")
private Float mPeriodSpendingSum;

// Some other code, e.g., getters, equal override,...
}

这里是扩展名:

public class WeekInformation extends PeriodInformation{

public WeekInformation(@NonNull Calendar mCalendar, Integer mPeriodSpendingCount, Float mMonthSpendingSum) {
    super(mCalendar, mPeriodSpendingCount, mMonthSpendingSum);
}

@Override
public String getPeriodRepresentation() {
    //return representation;
}

}

但是,我收到以下有关 WeekInformation 类的错误消息:

错误:实体和 Pojos 必须有一个可用的公共构造函数。你可以有一个空的构造函数或一个参数与字段匹配的构造函数(按名称和类型)。

所以这似乎在 Room 中是不可能的,因此我很乐意得到一些建议,如何不必经常复制相同的代码。

谢谢。

编辑: 我使用以下 DAO 代码聚合到 POJO,列 calendarDate 具有以下格式“yyyy-MM-dd'T'HH:mm:ss.SSSXXX”:

@Query("SELECT date(datetime(calendarDate)) AS 'DateTime', count(uID) AS 'SpendingCount', sum(value)  AS 'SpendingSum' from spending GROUP BY date(datetime(calendarDate))")
LiveData<List<DayInformation>> loadDayInformation();

【问题讨论】:

    标签: java android abstract-class pojo android-room


    【解决方案1】:

    我能够为我完成这项工作,使用嵌入式注释,允许直接访问嵌入式数据类型的字段。

    public class DayInformation {
    
        @Embedded
        public PeriodInformation periodInformation;
    
        @Override
        public String toString() {
            return "DayInformation{" +
               "periodInformation=" + periodInformation +
               '}';
        }
    }
    

    public class PeriodInformation {
    
        PeriodInformation(Calendar timestamp,
                          int periodSpendingCount,
                          float periodSpendingSum) {
            this.timestamp = timestamp;
            this.periodSpendingCount = periodSpendingCount;
            this.periodSpendingSum = periodSpendingSum;
        }
    
        @ColumnInfo(name = "DateTime")
        public final Calendar timestamp;
        @ColumnInfo(name = "SpendingCount")
        public Integer periodSpendingCount;
        @ColumnInfo(name = "SpendingSum")
        public Float periodSpendingSum;
    
        @Override
        public String toString() {
            final DateFormat dateInstance = SimpleDateFormat.getDateInstance();
            String date = timestamp == null ? "null" : dateInstance.format(timestamp.getTime());
            return "PeriodInformation{" +
                   "timestamp='" + date + '\'' +
                   ", periodSpendingCount=" + periodSpendingCount +
                   ", periodSpendingSum=" + periodSpendingSum +
                   '}';
        }
    }
    

    @Entity
    public class Spending {
        @PrimaryKey(autoGenerate = true)
        public int uid;
    
        @ColumnInfo(name = "calendarDate")
        public Calendar timestamp;
    
        @ColumnInfo(name = "value")
        public float value;
    
        public Spending(@NonNull Calendar timestamp, float value) {
            this.timestamp = timestamp;
            this.value = value;
        }
    
        @Override
        public String toString() {
            final DateFormat dateInstance = SimpleDateFormat.getDateInstance();
            String date = timestamp == null ? "null" : dateInstance.format(timestamp.getTime());
    
    
            return "Spending{" +
                   "uid=" + uid +
                   ", timestamp='" + date + '\'' +
                   ", value=" + value +
                   '}';
        }
    }
    

    和一个 DAO

    @Dao
    public interface SpendingDao {
    
        @Insert
        void insertAll(Spending... spendings);
    
        @Query("SELECT * FROM spending")
        LiveData<List<Spending>> findAll();
    
        @Query("SELECT calendarDate AS 'DateTime', count(uID) AS 'SpendingCount', sum(value)  AS 'SpendingSum' from spending GROUP BY date(datetime(calendarDate))")
        LiveData<List<DayInformation>> loadDayInformation();
    }
    

    给出以下输出

    aggregated data is 
    DayInformation{periodInformation=PeriodInformation{timestamp='Jun 26, 2018', periodSpendingCount=8, periodSpendingSum=184.0}}
    spending data is Spending{uid=1, timestamp='Jun 26, 2018', value=23.0}
    spending data is Spending{uid=2, timestamp='Jun 26, 2018', value=23.0}
    spending data is Spending{uid=3, timestamp='Jun 26, 2018', value=23.0}
    spending data is Spending{uid=4, timestamp='Jun 26, 2018', value=23.0}
    spending data is Spending{uid=5, timestamp='Jun 26, 2018', value=23.0}
    spending data is Spending{uid=6, timestamp='Jun 26, 2018', value=23.0}
    spending data is Spending{uid=7, timestamp='Jun 26, 2018', value=23.0}
    spending data is Spending{uid=8, timestamp='Jun 26, 2018', value=23.0}
    

    【讨论】:

    • 感谢您的解释,但是问题不在于 DAO。在那里我可以汇总支出。问题只是,如何让它自动分配给一个 POJO。所以基本上,我想得到一个周/月/..类的列表。我将发布我使用的必要 DAO 查询。
    • @xecto 也许我没有看到这里的范围,但是如果你可以以低开销按需计算它们,为什么你需要/想要将聚合持久化在数据库中?
    • 我想在数据库中按需创建聚合,请参阅编辑中的查询。我想要的是将聚合保存在按房间创建的类中(周信息)。
    • @xecto 如果将抽象类的字段公开会怎样?如果继承抽象类是私有的,Room 甚至可以看到这些字段吗?
    • 是的,这是真的。 Embedded Annotation 非常适合这种情况。即使使用 getter 和 setter 正确曝光,从外面看也看不到!!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-31
    • 2021-06-10
    • 2021-01-24
    • 2021-06-25
    • 1970-01-01
    相关资源
    最近更新 更多