Hibernate – 从多个表到一个对象的复杂查询

我有一个复杂的查询跨越7个表,并想知道如何在Hibernate中实现它。

我目前的尝试是使用session.createSQLQuery进行查询,我会将结果映射到特定实体。

我不知道如何做到这一点,因为过去我只使用一个表到一个实体。 我需要在哪里指定我想使用可能跨越多个表的复杂查询? 这只是在我的代码中吗? 我的hbm.xml文件? 我无法想到除了目前的尝试之外的任何其他事情。

以下是我的查询示例:

String stringQuery = "select WI.Customer_Id, CU.Card, CU.Code, "+ "PI.Identity_Card, PI.Name, PI.Surname, PI.Gender, "+ "AD.Zip, AD.Geo_Lat, AD.Geo_Long, "+ "CO.City_Geo_Level, "+ "CU.Address_id, CA.Name, "+ "CU.Category_Id, "+ "CU.Status, "+ "Sum(MO.Charged_Points) as Charged_Points, "+ "Sum(MO.Total_Money) as Total_Money, "+ "Count(MO.id) as AmountTransWinner "+ "from Promotions_Winner WI "+ "join Customers CU "+ "on WI.Customer_id = CU.id "+ "join Personal_Info PI "+ "on CU.Personal_Info_Id = PI.id "+ "join Address AD "+ "on CU.Address_Id = AD.id "+ "join Countries CO "+ "on AD.country_id = CO.id "+ "join Campaigns CA "+ "on CU.Campaign_Id = CA.id "+ "join Movements MO "+ "on WI.Movement_Id = MO.id "+ "where WI.Promotion_Id = :pPromotionID "+ "group by "+ "WI.Customer_Id, CU.Card, CU.Fidely_Code, "+ "PI.Identity_Card, PI.Name, PI.Surname, PI.Gender, "+ "AD.Zip, AD.Geo_Lat, AD.Geo_Long, "+ "CO.City_Geo_Level, "+ "CU.Address_id, CA.Name, "+ "CU.Category_Id, "+ "CU.Status"; 

您不需要SQL来执行此查询。 HQL会很好。 这样的查询返回一个List ,每个Object[]包含一行结果集。 因此,您将在索引0处找到客户ID,在索引1处找到卡,等等。您只需循环遍历行并在每次迭代时创建轻量级对象的实例。

见http://docs.jboss.org/hibernate/core/3.6/reference/en-US/html_single/#queryhql-select

最后我可以使用这段代码解决:

 String stringQuery = "select " + "CU.Card as card, " + "CU.Fidely_Code as fidelyCode, "+ "PI.Identity_Card as identityCard, " + "PI.Name as name, " + "PI.Surname as surname, " + "PI.Gender as gender, "+ "AD.Zip as zip, " + "AD.Geo_Lat as geo_lat, " + "AD.Geo_Long as geo_long, "+ "CO.City_Geo_Level as cityGeoLevel, "+ "CA.Name as campaignName, "+ "CU.Status as status, "+ "Sum(MO.Charged_Points) as pointsCharged, "+ "Sum(MO.Total_Money) as amountPurchase, "+ "Count(MO.id) as amountTransWinner "+ "from Promotions_Winner WI "+ "join Customers CU "+ "on WI.Customer_id = CU.id "+ "join Personal_Info PI "+ "on CU.Personal_Info_Id = PI.id "+ "join Address AD "+ "on CU.Address_Id = AD.id "+ "join Countries CO "+ "on AD.country_id = CO.id "+ "join Campaigns CA "+ "on CU.Campaign_Id = CA.id "+ "join Movements MO "+ "on WI.Movement_Id = MO.id "+ "where WI.Promotion_Id = :pPromotionID "+ "group by "+ "WI.Customer_Id, CU.Card, CU.Fidely_Code, "+ "PI.Identity_Card, PI.Name, PI.Surname, PI.Gender, "+ "AD.Zip, AD.Geo_Lat, AD.Geo_Long, "+ "CO.City_Geo_Level, "+ "CU.Address_id, CA.Name, "+ "CU.Category_Id, "+ "CU.Status "; //Query query = this.getSession().createSQLQuery(stringQuery).addEntity("", PromotionsWinnerLittle.class); //Query query = this.getSession().createSQLQuery(stringQuery).setResultSetMapping("PromotionsWinnerLittle"); Query query = this.getSession().createSQLQuery(stringQuery) .addScalar("card", StandardBasicTypes.LONG) .addScalar("fidelyCode", StandardBasicTypes.LONG) .addScalar("identityCard", StandardBasicTypes.STRING) .addScalar("name", StandardBasicTypes.STRING) .addScalar("surname", StandardBasicTypes.STRING) .addScalar("gender", StandardBasicTypes.STRING) .addScalar("zip", StandardBasicTypes.STRING) .addScalar("geo_lat", StandardBasicTypes.BIG_DECIMAL) .addScalar("geo_long", StandardBasicTypes.BIG_DECIMAL) .addScalar("cityGeoLevel", StandardBasicTypes.LONG) .addScalar("campaignName", StandardBasicTypes.STRING) .addScalar("status", StandardBasicTypes.LONG) .addScalar("pointsCharged", StandardBasicTypes.BIG_DECIMAL) .addScalar("amountPurchase", StandardBasicTypes.LONG) .addScalar("amountTransWinner", StandardBasicTypes.LONG) .setResultTransformer(Transformers.aliasToBean(PromotionsWinnerLittle.class)); //Query query = this.getSession().createSQLQuery(stringQuery); query = query.setLong("pPromotionID", promotionID); List lista = query.list(); 

我刚刚在Select和addScalar + setResultTransformer上添加了“As”部分

他们有两种方法可以做到这一点。

1.您将获得一个列表对象数组。

  List 

这里一个数组元素代表查询的一行。

2.您可以使用hibernatefunctionResultTransformer – 为查询输出创建一个简单类。 – 创建ResultTransformer。

防爆。

  public class MyResultTransformer implements ResultTransformer { /* Method to convert to generic type list */ @Override public List transformList(List arg0) { List employees = new ArrayList(); for (Object employee : arg0) { employees.add((Employee) employee); } return employees; } /* Code to transform your query output to Object */ @Override public Employee transformTuple(Object[] arg0, String[] arg1) { System.out.println("MyResultTransformer.transformTuple()"); Employee tempEmp = new Employee(); tempEmp.setEmployee_id((BigInteger) arg0[0]); return tempEmp; } } 

– 将变换器设置为查询。

 Query query=session.createSQLQuery("SELECT * FROM employeedetail"); // You can use named query, SQL native also query.setResultTransformer(new MyResultTransformer()); List employees=query.list(); 

所以据我所知,这是7个表的连接。 如果您正在使用hibernate,则将每个表映射到实体,然后使用@JoinColumn映射到它的每个依赖项。 这是hibernate在那里防止发生的那种SQL查询。