之前按提到过Jimmer在复杂统计上的问题。这里提供一些“邪修”思路:关闭数据库合法性校验,使用视图解决
案例
现在有一个data表,里面记录了部分设备的运转记录。这个表的结构如下:
create table public.data
(
id bigserial
constraint data_pk
primary key,
datetime timestamp not null,
device_id text not null,
value numeric,
constraint data_pk_2
unique (datetime, device_id)
);
alter table public.data
owner to postgres;
接下来,编写一下对应视图,查询每天每个设备的value的平均值。
SELECT row_number() OVER (ORDER BY date) AS id, -- 这里用rowNumber作为id,在下面的实体类映射中用到
value_avg,
device_id,
date
FROM ( SELECT avg(data.value) AS value_avg,
data.device_id,
to_char(data.datetime, 'YYYY-MM-DD'::text) AS date
FROM data
GROUP BY (to_char(data.datetime, 'YYYY-MM-DD'::text)), data.device_id) unnamed_subquery然后给这个视图命名为 data_daily_value
然后,编写对应的实体类
Entity
interface DataDailyAvg {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
val id: Long
@IdView
val deviceId: String?
@ManyToOne
val device: Device?
val date: LocalDate?
val value: BigDecimal?
}然后编写一个查询接口(这里接口仅仅作为示范作用):
@GetMapping("/dailyData")
fun getData(): ApiResponse<List<DataDailyAvg>> {
val data = sql.createQuery(DataDailyAvg::class) {
where(table.date le LocalDate.now())
select(table.fetchBy {
allScalarFields()
device {
allScalarFields()
}
})
}.execute()
return ApiResponse.success(data)
}此时如果运行,可能现下面的报错:

报错的原因是:jimmer发现,DataDailyAvg实体类的id在数据库是可为空的。但是实际上,这个视图的id实际上不会为空。因此,我们需要降低Jimmer的database-validation-mode 等级,使得其不至于妨碍项目的运行,同时也能给我们输出检查的对应结果。
解决办法是在配置文件中,设置 database-validation-mode 为WARNING。这样既能输出对应的检查结果,也能不妨碍项目运行。