使用 Ebean,填充 属性 存储另一个相关实体的实体列表的值 属性
using Ebean, fill property value of entity list stored another related entity property
我将尝试直接用代码描述我的问题,然后说出我需要什么,请注意,我将我的代码最小化以解决我遇到的问题:
我从实体获取提要列表:
@Entity
public class Feed {
@Id
@Column
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@ManyToOne
@JoinColumn(name = "event_id")
private Event event;
@ManyToOne
@JoinColumn(name = "event_trigger_id")
private EventTypeTrigger eventTrigger;
}
在这里,我试图让这个实体填充正确的 count
值。
@Entity
public class EventTrigger {
@Id
@Column
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@Column(nullable = false)
private String title;
@Transient
private int count;
}
存储计数数据的 Feed 实体。
@Entity
public class EventTriggerFeed {
@Id
@Column
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@Column(nullable = false)
private int count;
@ManyToOne
@JoinColumn(name = "event_id", nullable = false)
@JsonBackReference
private Event event;
@ManyToOne
@JoinColumn(name = "event_trigger_id", nullable = false)
@JsonBackReference
private EventTrigger eventTrigger;
}
从我尝试调用的服务中:
public List<Feed> findUserFeeds(int userId) {
return Ebean.find(Feed.class).findList();
}
我可以像这样获取每个触发器的计数:
public int getCountFromEventTriggerFeed(int triggerId, int eventId) {
return Ebean.find(EventTriggerFeed.class)
.where().eq("eventTrigger.id",triggerId).eq("event.id",eventId)
.findUnique().getCount();
}
我只想获取 Feed
的列表,其中包含 Event
信息和 EventTrigger
信息,并且 count
属性 填充了计数值来自 EventTriggerFeed
我只是在没有太多迭代的情况下坚持使用完美的方法,我正在考虑获取 Feed
行中每个 EventTrigger
的计数值,但这可能会让我得到很多调用:
for (Feed feed : findUserFeeds(userId)) {
int eventId = feed.getEvent().getId();
int triggerId = feed.getEventTrigger().getId();
feed.getEventTrigger().setCount(getCountFromEventTriggerFeed(triggerId, eventId))
}
但是你能想象如果我有 50 个提要吗?
有没有关于如何优化这个令人头疼的想法?
我通过在 .sql
文件中创建视图来解决这个问题,如下所示:
CREATE OR REPLACE VIEW `event_feed_summary_view` AS
SELECT
max(feed.trigger_count) * up.amount AS total_amount,
feed.trigger_count,
uf.feed_id,
feed.event_id,
feed.event_trigger_id,
up.amount
FROM event_trigger_feeds feed
INNER JOIN event_type_triggers trig ON feed.event_trigger_id AND trig.id
INNER JOIN user_feed uf ON uf.event_id = feed.event_id AND uf.event_trigger_id = feed.event_trigger_id
GROUP BY uf.feed_id, feed.event_id, feed.event_trigger_id;
我把这段代码放在里面 conf/db_views/create_views.sql
我在我的模块 OnStartup
中启动时调用了这个文件:
@Singleton
public class OnStartup {
@Inject
public OnStartup(final Configuration configuration, final Environment environment, Database db) {
// Create views
Logger.info("Creating / Replacing the Tables views in database");
InputStream is = environment.classLoader().getResourceAsStream("db_views/create_views.sql");
String sql;
try {
sql = IOUtils.toString(is);
if (sql != null) {
Connection conn = db.getConnection();
try {
Statement stmt = conn.createStatement();
try {
stmt.execute(sql);
Logger.info("Views Created");
} finally {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
} catch (SQLException e) {
Logger.error("Could create Statement ");
e.printStackTrace();
} finally {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
} catch (IOException e) {
Logger.error("Could not find create view script");
e.printStackTrace();
}
}
}
使用 Ebean 我得到的结果是 SqlQuery
:
public long getTotal(int feedId) {
String sql = "select sum(total_amount) as total from event_feed_summary_view where feed_id = :feed_id;";
SqlQuery sqlQuery = Ebean.createSqlQuery(sql);
sqlQuery.setParameter("feed_id", feedId);
SqlRow r = sqlQuery.findUnique();
if (r != null && r.getLong("total") != null) {
return r.getLong("total");
}
return 0;
}
我将尝试直接用代码描述我的问题,然后说出我需要什么,请注意,我将我的代码最小化以解决我遇到的问题:
我从实体获取提要列表:
@Entity
public class Feed {
@Id
@Column
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@ManyToOne
@JoinColumn(name = "event_id")
private Event event;
@ManyToOne
@JoinColumn(name = "event_trigger_id")
private EventTypeTrigger eventTrigger;
}
在这里,我试图让这个实体填充正确的 count
值。
@Entity
public class EventTrigger {
@Id
@Column
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@Column(nullable = false)
private String title;
@Transient
private int count;
}
存储计数数据的 Feed 实体。
@Entity
public class EventTriggerFeed {
@Id
@Column
@GeneratedValue(strategy = GenerationType.AUTO)
private Integer id;
@Column(nullable = false)
private int count;
@ManyToOne
@JoinColumn(name = "event_id", nullable = false)
@JsonBackReference
private Event event;
@ManyToOne
@JoinColumn(name = "event_trigger_id", nullable = false)
@JsonBackReference
private EventTrigger eventTrigger;
}
从我尝试调用的服务中:
public List<Feed> findUserFeeds(int userId) {
return Ebean.find(Feed.class).findList();
}
我可以像这样获取每个触发器的计数:
public int getCountFromEventTriggerFeed(int triggerId, int eventId) {
return Ebean.find(EventTriggerFeed.class)
.where().eq("eventTrigger.id",triggerId).eq("event.id",eventId)
.findUnique().getCount();
}
我只想获取 Feed
的列表,其中包含 Event
信息和 EventTrigger
信息,并且 count
属性 填充了计数值来自 EventTriggerFeed
我只是在没有太多迭代的情况下坚持使用完美的方法,我正在考虑获取 Feed
行中每个 EventTrigger
的计数值,但这可能会让我得到很多调用:
for (Feed feed : findUserFeeds(userId)) {
int eventId = feed.getEvent().getId();
int triggerId = feed.getEventTrigger().getId();
feed.getEventTrigger().setCount(getCountFromEventTriggerFeed(triggerId, eventId))
}
但是你能想象如果我有 50 个提要吗?
有没有关于如何优化这个令人头疼的想法?
我通过在 .sql
文件中创建视图来解决这个问题,如下所示:
CREATE OR REPLACE VIEW `event_feed_summary_view` AS
SELECT
max(feed.trigger_count) * up.amount AS total_amount,
feed.trigger_count,
uf.feed_id,
feed.event_id,
feed.event_trigger_id,
up.amount
FROM event_trigger_feeds feed
INNER JOIN event_type_triggers trig ON feed.event_trigger_id AND trig.id
INNER JOIN user_feed uf ON uf.event_id = feed.event_id AND uf.event_trigger_id = feed.event_trigger_id
GROUP BY uf.feed_id, feed.event_id, feed.event_trigger_id;
我把这段代码放在里面 conf/db_views/create_views.sql
我在我的模块 OnStartup
中启动时调用了这个文件:
@Singleton
public class OnStartup {
@Inject
public OnStartup(final Configuration configuration, final Environment environment, Database db) {
// Create views
Logger.info("Creating / Replacing the Tables views in database");
InputStream is = environment.classLoader().getResourceAsStream("db_views/create_views.sql");
String sql;
try {
sql = IOUtils.toString(is);
if (sql != null) {
Connection conn = db.getConnection();
try {
Statement stmt = conn.createStatement();
try {
stmt.execute(sql);
Logger.info("Views Created");
} finally {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
} catch (SQLException e) {
Logger.error("Could create Statement ");
e.printStackTrace();
} finally {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
} catch (IOException e) {
Logger.error("Could not find create view script");
e.printStackTrace();
}
}
}
使用 Ebean 我得到的结果是 SqlQuery
:
public long getTotal(int feedId) {
String sql = "select sum(total_amount) as total from event_feed_summary_view where feed_id = :feed_id;";
SqlQuery sqlQuery = Ebean.createSqlQuery(sql);
sqlQuery.setParameter("feed_id", feedId);
SqlRow r = sqlQuery.findUnique();
if (r != null && r.getLong("total") != null) {
return r.getLong("total");
}
return 0;
}