我有一个实体UserFood,该实体包含另一个实体(食品和用户)的字段。 当我仅使用JDBC时,我创建了此查询,以按用户ID和日期从“食物”搜索中选择总计:
"SELECT SUM(f.calories * uf.count) AS total_calories, ROUND(SUM(f.protein * uf.count),1) AS total_protein, ROUND(SUM(f.fat * uf.count),2) AS total_fat, ROUND(SUM(f.carbohydrate * uf.count),2) AS total_carbohydrate FROM users_food uf INNER JOIN food f ON uf.food_id = f.food_id WHERE uf.user_id = ? AND uf.date_added = ?;"
然后我可以将结果放入Map中,在其中我可以从表中将键设置为字段名称(total_calories,total_protein,total_fat,total_carbohydrate)
如何使用JPA(没有Hibernate和Spring)来做同样的事情?
我尝试至少从函数SUM中获取值,但出现错误。 下面是我尝试做的事情:
public List findFoodFieldsTotalsByUserIdAndDate(Integer userId, LocalDate date) {
EntityManagerFactory factory = Persistence.createEntityManagerFactory("mysql");
EntityManager em = factory.createEntityManager();
EntityTransaction transaction = em.getTransaction();
transaction.begin();
Query query = em.createQuery
("SELECT SUM(Food.calories * uf.count) AS total_calories, SUM(Food.protein * uf.count) AS total_protein, SUM(Food.fat * uf.count) AS total_fat, SUM(Food.carbohydrate * uf.count) AS total_carbohydrate FROM UserFood uf WHERE uf.user.id = :userId AND uf.dateAdded = :date");
query.setParameter("userId", userId);
query.setParameter("date", date);
List resultList = query.getResultList();
transaction.commit();
em.close();
factory.close();
return resultList;
}
我知道该错误恰好在查询中的某个地方,因为我创建了更简单的方法,并且一切正常:
public List<UserFood> findByUserIdAndDate(Integer userId, LocalDate date) {
EntityManagerFactory factory = Persistence.createEntityManagerFactory("mysql");
EntityManager em = factory.createEntityManager();
EntityTransaction transaction = em.getTransaction();
transaction.begin();
TypedQuery<UserFood> query = em.createQuery
("SELECT uf FROM UserFood uf WHERE uf.user.id = :userId AND uf.dateAdded = :date", UserFood.class);
query.setParameter("userId", userId);
query.setParameter("date", date);
List<UserFood> userFoodList = query.getResultList();
transaction.commit();
em.close();
factory.close();
return userFoodList;
}
在我的实体下面:
UserFood:
@EqualsAndHashCode
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Getter
@Entity
@Table(name = "user_food")
public class UserFood {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "user_food_id")
private int id;
@ManyToOne
@JoinColumn(name = "user_fk_id")
private User user;
@OneToOne(cascade = CascadeType.PERSIST)
@JoinColumn(name = "food_fk_id")
private Food food;
private int count;
@Column(name = "date_added")
private LocalDate dateAdded;
}
用户:
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Getter
@Setter
@Entity
public class User {
@Id
@GeneratedValue
@Column(name = "user_id")
private int id;
@Column(unique = true)
private String login;
@Column(length = 12)
private String password;
private LocalDate birthday;
private int height;
private int weight;
@Column(name = "norma_calories")
private int normaCalories;
@OneToOne(cascade = {CascadeType.PERSIST, CascadeType.REMOVE})
@JoinColumn(name = "activity_type_fk_id")
private ActivityType activityType;
@OneToOne(cascade = {CascadeType.PERSIST, CascadeType.REMOVE})
@JoinColumn(name = "role_fk_id")
private Role role;
}
食物:
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Getter
@Entity
@NamedQueries({@NamedQuery(name = "findAllFood", query = "FROM Food f")})
public class Food {
@Id
@GeneratedValue
@Column(name = "food_id")
private int id;
private String name;
private int calories;
@Column(precision = 1)
private double protein;
@Column(precision = 1)
private double fat;
@Column(precision = 1)
private double carbohydrate;
}