Hibernate - сложный запрос от нескольких таблиц к одному объекту - PullRequest
12 голосов
/ 08 февраля 2012

У меня сложный запрос, пересекающий 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";

Ответы [ 4 ]

6 голосов
/ 30 июня 2014

Это два способа сделать это.

1. Вы получите массив объектов списка.

 List<Object[]>

Здесь один элемент массива представляет одну строку вашего запроса.

2. Вы можете использовать функцию гибернации ResultTransformer - Создатьпростой класс для вывода вашего запроса.- Создать ResultTransformer.

Пример.

 public class MyResultTransformer implements ResultTransformer {


/*
Method to convert to generic type list
*/
    @Override
    public List<Employee> transformList(List arg0) {
        List<Employee> employees = new ArrayList<Employee>();
        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<Employee> employees=query.list();
6 голосов
/ 08 февраля 2012

Вам не нужен SQL для выполнения этого запроса.HQL подойдет.И такой запрос возвращает List<Object[]>, каждый Object[] содержит строку набора результатов.Таким образом, вы найдете идентификатор клиента по индексу 0, карточку по индексу 1 и т. Д. Вам просто нужно циклически проходить по строкам и создавать экземпляр вашего легкого объекта на каждой итерации.

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

4 голосов
/ 08 февраля 2012

Наконец-то я смог решить, используя этот код:

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

0 голосов
/ 08 февраля 2012

Итак, насколько я вижу, это соединение из 7 таблиц.Если вы используете hibernate, вы должны сопоставить каждую из этих таблиц с сущностями, а затем использовать @JoinColumn для сопоставления с каждой из ее зависимостей.Это своего рода SQL-запрос, который используется в спящем режиме, чтобы предотвратить возникновение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...