كيفية تنفيذ عمليات التاريخ في السبات
سؤال
أرغب في إجراء عمليات وقت البيانات باستخدام HQL للإسبات.
أريد إضافة وطرح تاريخين وكذلك أريد طرح سنة واحدة أو شهر واحد من تاريخ معين.
كيف يكون هذا ممكنًا باستخدام HQL في وضع السبات؟
المحلول
وانظر التسجيل المسرحية / الوقت الرياضيات في HQL؟ على سبيل المثال.
لاستخدام مزود مخصص يجب كتب السبات اللهجة الخاصة وتسجيل:
registerFunction("weekday",
new SQLFunctionTemplate(Hibernate.INTEGER, "to_char(?1,'D')") );
نصائح أخرى
وتحتاج إلى إنشاء لهجة الخاصة بك. شيء كما يلي:
public class MyDialect extends MySQLInnoDBDialect{
public myDialect() {
super();
registerFunction("date_add_interval", new SQLFunctionTemplate(Hibernate.DATE, "date_add(?1, INTERVAL ?2 ?3)"));
}
}
في السبات / ماي (على الأقل) يمكنك تحويل من وإلى يونكس الطابع الزمني. منذ الطابع الزمني يونكس هو عدد صحيح يمكنك إضافة عدد صحيح من ثانية لذلك.
FROM_UNIXTIME(UNIX_TIMESTAMP(date)+ (allowedTimeWindow*86400)) as deadline
وولكنه محدود ولكن من الأسهل بكثير من النهج أعلاه.
وهذه قضية مفتوحة في السبات. اعتبارا من السبات 3.3 لا توجد وسيلة معيارية للتعامل مع مقارنات تاريخ بحتة في HQL:
https://hibernate.atlassian.net/browse/HHH-2434
والسبات 4.3 يوفر وظائف للوصول التاريخ / الوقت في HQL وهي:
current_timestamp() , current_date() , current_time()
ويمكن أن تدار العمليات الحسابية حسب:
SECOND(...) , MINUTE(...) , HOUR(...) , DAY(...) , MONTH(...) , YEAR(...)
تنويه: انا مبتدئ جافا
وكنت قادرا على استخدام current_date() >= fromDate AND dateadd(day, -1, getdate()) <= toDate
في بيان HQL ضد ديسيبل سايبيس في السبات 3.5.3، دون تسجيل أية وظائف.
نموذج استخدام لهجة JPA + Hibernate 4.3.1 + MySQL 5
الطبقة العامة SampleMySQL5InnoDBdialect تمتد org.hibernate.dialect.MySQL5InnoDBdialect {
public SampleMySQL5InnoDBDialect() {
super();
registerFunction("date_sub_days", new SQLFunctionTemplate(StandardBasicTypes.DATE, "date_sub(?1, interval ?2 day)"));
}
ثم لفصلك مع شرح التعيين:
@NamedQuery(name = "SampleEntity.getSampleEntitiesForGapOverlapCalculations", query = "from SampleEntity as se where "
+ "((se.toDate between :startDate and :endDate) or (date_sub_days(se.toDate, se.duration) between :startDate and :endDate)) order by se.toDate asc, se.duration desc")
SampleEntity لديه ان يذهب في موعد حقل من النوع java.sql.Date و مدة حقل عدد صحيح (المدة بالأيام) ونحن نقوم بالحساب fromDate = toDate - المدة واختيار جميع الجهات التي لديها من التاريخ أو ان يذهب في موعد داخل الفاصل [تاريخ البدء تاريخ الانتهاء].
وHibernate4.3 يوفر وظائف الأم للوصول إلى تواريخ / الطوابع ولتنفيذ عمليات الحسابية عليها
current_date(), current_time(), and current_timestamp()
ويمكن القيام بعمليات الحساب باتباع. هذه المهام تأخذ الوقت كمدخل:
second(...), minute(...), hour(...), day(...), month(...), and year(...)
ويمكن للمرء أن يحصل الاختلاف المطلق في HQL التي كتبها
current_timestamp() - dateInstance
وحيث dateInstance يمكن أن يكون تعريف
@Column(name = "updated_at")
@Temporal(TemporalType.TIMESTAMP)
private java.util.Date updatedAt;
وكانت النتيجة في 0.1 ثانية. ذلك لاختلاف المطلق لل1 ثانية، فإن التعبير أعلاه تعطي نتيجة إلى 10.
وهكذا استعلام ستبدو:
select t from Table t where (current_timestamp() - updatedAt)>600
والمستخدمين بوستجرس ...
registerFunction("dateadd", new SQLFunctionTemplate(StandardBasicTypes.DATE, "(?1 + INTERVAL ?2)"));
ومع استخدام SQL مثل:
now() < dateadd(:mydate, '-1 day')