GORM Запрос, где фильтр не является прямым атрибутом класса - PullRequest
1 голос
/ 22 октября 2010

Я пытаюсь найти наиболее эффективный / эффективный способ выполнения запроса определенного типа с использованием Grails GORM.

Это сценарий, в котором я хочу запросить все дочерние / связанные элементы в отношении многие-к-одному.Это односторонние отношения, при которых многие стороны использовали идентификатор того, с чем оно связано.

Одним из примеров является связь между учебным годом и семестрами этого учебного года.В таблице семестров в таблице хранится идентификатор учебного года, к которому относится семестр.Учебный год, однако, не имеет ничего, кроме таблицы, на которую он ссылается.Это сделано для того, чтобы количество семестров было гибким.Я надеялся использовать что-то вроде HQL для извлечения всех семестров, которые принадлежат одному и тому же учебному году.В обычном SQL мы можем фильтровать строки, используя столбец идентификатора учебного года таблицы семестра.В HQL это не так просто.Идентификатор учебного года недоступен как свойство класса домена.Вместо этого Hibernate просто использует его для загрузки объекта учебного года.

Должно ли в этом случае работать что-то похожее на приведенное ниже?

select from Semester as s where s.year.id = ?

В этом случае свойство класса домена семестра, в котором содержится учебный год, называется годом.Запрос берет свойство year и идентификатор этого года и использует его для фильтрации семестров.

Это всего лишь один пример, но система, которую я разрабатываю, содержит более одного аналогичного устройства, где было бы желательнозагрузить группу объектов домена, которые имеют один и тот же связанный объект домена.

Может быть более эффективный / действенный способ сделать это.Одним из примеров было бы сделать фактическое значение идентификатора учебного года доступным из класса домена.Это, однако, означало бы, что один и тот же столбец сопоставлен с более чем одним свойством класса домена.Это может и не быть необходимым, но это еще один возможный способ решения такого рода проблем.

Имейте некоторый опыт работы в Hibernate, но некоторые проблемы усложняются в Hibernate, когда вы хотите делать более необычные вещи.

Ответы [ 2 ]

1 голос
/ 22 октября 2010

Это похоже на базовые отношения 1: M, которые обрабатываются сопоставления ownTo / hasMany.Это не заставляет родительскую таблицу хранить какие-либо дополнительные данные.Просто имейте доменные объекты:

class AcademicYear {
    static hasMany = [semesters: Semester]
}

class Semester {
    static belongsTo = AcademicYear
}

И у Semester магически есть свойство «acadeYear», на которое вы можете ссылаться.И все, просто сделайте это так:

AcademicYear y = AcademicYear.findByYear(2010)
Semester s = Semester.get(1)
y.addToSemesters(s)
y.semesters.each{ println it }
String year = s.academicYear.name
def a = s.academicYear.id

Попробуйте сначала в "консоли Grails" и наслаждайтесь.

0 голосов
/ 18 августа 2015

Хотя gorm - это еще один слой после спящего режима, он предоставляет эффективные критерии-запросы и динамические средства поиска для обычных сценариев, а когда дело доходит до необычных сценариев, мы должны рассмотреть запросы критериев.И когда дело доходит до еще более необычных сценариев, мы должны взглянуть на hql, а для еще более сложных случаев мы можем написать и базовый sql.

Ниже приводятся различные способы верхнего уровня, которые можно использовать для достижения того или другого.Тип задач уровня запроса.

Предположим, у нас есть домен Сотрудника, как показано ниже:

class Employee{
String name
int age
Designation designation

static hasMany = [teams:Team]
}
  1. Динамические искатели GORM:

     Employee.findByName("Ajay")
    
  2. Запрос критериев:

    Employee.createCriteria().list {
            eq 'name', 'Ajay'   
    }
    
  3. где предложение:

    Employee.where {
        name == 'ajay' && (age > 25 && age < 30)
    }.list()
    
  4. HQL:

    Employee.findAll('from Employee as e where e.name = :name', [name: 'Ajay'])
    
  5. Base sql:

    String query = $/
    SELECT * from employee e
    WHERE e.name = :name
    /$  
    new Employee()
    .domainClass
    .grailsApplication
    .mainContext
    .sessionFactory
    .currentSession
    .createSQLQuery(query)
        .setString('name', 'Ajay')
        .list()
    

Ниже приведена более детальная иерархия для того же, где yes для подходящего или применимого:

                    dynamic finder          where clause    criteria    HQL     SQL

    simple queries         yes                Yes             Yes        Yes    Yes

    complex filters                           Yes             Yes        Yes    Yes

    associations                              Yes             Yes        Yes    Yes

    property comparisons                      Yes             Yes        Yes    Yes

    some subqueries                           Yes             Yes        Yes    Yes

    eager fetches w/ complex filters                          Yes        Yes    Yes 

    projections                                               Yes        Yes    Yes 
    queries with arbitrary return sets                                   Yes    Yes

    highly complex queries (like self joins)                                    Yes

    some database specific features                                             Yes

    performance-optimized queries                                               Yes

Больше можно прочитать из http://tatiyants.com/how-and-when-to-use-various-gorm-querying-options/

...