HQL с конвертированием часового пояса - PullRequest
1 голос
/ 17 марта 2011

У меня следующий запрос в SQL

Select 
count(*) as cnt, 
DATE_FORMAT(CONVERT_TZ(wrdTrk.createdOnGMTDate,'+00:00',:zone),'%Y-%m-%d') as dat
 from
 t_twitter_tracking wrdTrk 
where 
wrdTrk.word like (:word) and wrdTrk.createdOnGMTDate  between  :stDate and :endDate  group by dat;

Я нахожусь в процессе переноса всего этого в Hibernate, у меня есть два вопроса, связанных с этим,

  1. Как можноЯ пишу тот же запрос на HQL?
  2. Может ли Hibernate кеш (ehcache) кешировать нативный SQL и как он работает.Было бы замечательно, если бы кто-то указал мне правильное направление, чтобы понять кэширование запросов на нативном SQL

С уважением, Рохит

1 Ответ

1 голос
/ 28 октября 2011

Это действительно сложный вопрос, потому что нужно учитывать несколько вещей.Часть «AS» вашего запроса игнорируется в HQL, потому что NHibernate удаляет его и создает свой собственный.К сожалению, это означает, что запрос становится безобразным.Вы заметите, что длинную функцию, начинающуюся с «date_format (convert_tz»), нужно повторить в части запроса GROUP BY.

string hql = @"SELECT 
                count(*), 
                date_format(
                   convert_tz(wrdTrk.createdOnGMTDate,
                              '+00:00', :zone),'%Y-%m-%d')
               FROM
                 t_twitter_tracking wrdTrk 
               WHERE
                 wrdTrk.word LIKE (:word) 
                   AND wrdTrk.createdOnGMTDate 
                       BETWEEN :stDate and :endDate
               GROUP BY
                 date_format(
                   convert_tz(wrdTrk.createdOnGMTDate,
                              '+00:00',:zone),'%Y-%m-%d')";

var list = session.CreateQuery(hql)
                    .SetParameter("zone", zone)
                    .SetParameter("word", word)
                    .SetParameter("stDate", stDate)
                    .SetParameter("endDate", endDate)
                    .List<object[]>();

foreach (var item in list)
{
    int count = (int)item[0];
    DateTime date = (DateTime)item[1];
    Console.WriteLine("Count: {0}, Date: {1}", count, date.ToString());
}

К сожалению, ваша работа на этом может не закончиться. Вы можете получить этоошибка, если функции "date_format" или "convert_tz" не зарегистрированы в классе MySQLDialect.

Нет типа данных для узла: MethodNode ((date_format и т. д., и т. д., и т. д.

Если это не так, вам нужно зарегистрировать их самостоятельно с помощью этого кода.

public class MyDialect : MySQL5Dialect
{
    public MyDialect()
    {
        RegisterFunction("date_format", 
           new StandardSQLFunction(NHibernateUtil.Date, "date_format(?1, ?2)"));
        RegisterFunction("convert_tz", 
           new StandardSQLFunction(NHibernateUtil.Date, "convert_tz(?1, ?2, ?3)"));
    }
}

Затем вам нужно зарегистрировать свой собственный диалект в файле "hibernate.cfg.xml", как показано ниже ("Ns1"это просто заполнитель для вашего пространства имен).

<property name="dialect">Ns1.MyDialect, MyProgram</property>
...