มีโซลูชันใหม่ทั้งหมดเพื่อให้เริ่มต้นแบบรวมและสิ้นสุดแบบเอกสิทธิ์เฉพาะบุคคลใน QueryDSL / Oracle SQL หรือไม่

ฉันกำลังพยายามสร้างแบบสอบถามสำหรับช่วงเวลาโดยใช้ QueryDSL (รวมเริ่มต้น วันที่สิ้นสุดพิเศษ)

ใน เอกสารประกอบของ QueryDSL ฉันพบว่า public BooleanExpression between(Expression<T> from, Expression<T> to); เป็นเอกสิทธิ์เฉพาะทั้งสองด้าน

รับนิพจน์แรก ‹ นี้ ‹ ที่สอง

อย่างไรก็ตาม มันแปลเป็น Oracle SQL BETWEEN ซึ่งรวมทั้งสองด้าน
(เทียบเท่ากับ first <= this <= second)

QueryDSL เช่นนี้:

[...]
person.name.like(n)
  .and(person.birthdate.between(from, to))
[...]

แปลเป็น Oracle SQL ดังนี้:

SELECT *
FROM PERSON
WHERE NAME LIKE n
  AND BIRTHDATE BETWEEN from AND to;

ไม่มีใครรู้เหตุผล/ตรรกะเบื้องหลังเรื่องนี้หรือไม่
มันเป็นเพียงเอกสารที่ 'เน่าเสีย' หรือไม่

เห็นได้ชัดว่าระหว่างนี้ใช้ไม่ได้ผลสำหรับฉัน

ฉันควรจะใช้สิ่งที่เป็นก้อนมากขึ้น

person.name.like(n)
  .and(person.birthdate.goe(from)
  .and(person.birthdate.lt(to))

หรือมีวิธีแก้ไขปัญหาที่สะอาดซึ่งทำสิ่งที่ฉันต้องการ?


person MrMeszaros    schedule 03.08.2015    source แหล่งที่มา
comment
ถ้านี่เป็น SQL ธรรมดา ฉันจะใช้ between "from" and "to" - 1? (สมมติว่า to_ เป็นค่า DATE   -  person a_horse_with_no_name    schedule 03.08.2015
comment
ใช้งานได้เฉพาะในกรณีที่วันที่ถูกตัดทอนทั้งหมด @a_horse; คำขอจริงของ OP จะเป็น between "from" and "to" - interval '1' second   -  person Ben    schedule 03.08.2015


คำตอบ (2)


เอกสารได้รับการแก้ไขแล้วเมื่อไม่นานมานี้ http://www.querydsl.com/static/querydsl/2.2.0/apidocs/com/mysema/query/types/expr/ComparableExpression.html#between(T,%20T)

2.2.0 เปิดตัวเมื่อวันที่ 18.7.2011 ฉันขอแนะนำอย่างยิ่งให้คุณใช้ Querydsl เวอร์ชันใหม่กว่าจาก 4.* หรือ 3.*

สำหรับการเริ่มต้นแบบรวม ปลายแบบพิเศษ คุณสามารถเขียนวิธีการอรรถประโยชน์ของคุณเองได้:

public static <T> Predicate range(ComparableExpression<T> expr, T from, T to) {
    return expr.goe(expr).and(expr.lt(to));
}
person Timo Westkämper    schedule 03.08.2015

สิ่งนี้ดูเหมือนจะเป็นเพียงเอกสารที่ไม่ดี แต่ฉันไม่คิดว่ามันจะสร้างความแตกต่างได้มากนัก หากเอกสารประกอบเป็นไปตามที่แนะนำ แสดงว่าจะไม่เหมาะสมสำหรับคุณ สิ่งที่เกิดขึ้นในปัจจุบันดีขึ้นเล็กน้อย

ไม่มีนิพจน์เดียวในภาษา SQL ของ Oracle ที่จะแสดงการดำเนินการ first <= this < second ดังนั้น คุณยังคงต้องดำเนินการดังนี้:

person.name.like(n)
  .and(person.birthdate.between(from, to)
  .and(person.birthdate.lt(to))

ซึ่งจะแสดงใน SQL เป็น:

select *
  from person
 where name like n
   and birthdate between from and to
   and birthdate < to

เมื่อถึงจุดนั้น มันง่ายพอๆ กันที่จะระบุความตั้งใจของคุณอย่างชัดเจนล่วงหน้าและทำในสิ่งที่คุณตั้งใจ:

person.name.like(n)
  .and(person.birthdate.goe(from)
  .and(person.birthdate.lt(to))

ป.ล. ฉันแปลกใจเล็กน้อยที่ column.like(String) กลายเป็น column like string ใน SQL นี่เทียบเท่ากับ column = string ฉันคาดว่า .like() จะกลายเป็น column like string || '%' ซึ่งจะค้นหาสตริงที่คุณต้องการที่ตอนต้นของคอลัมน์

person Ben    schedule 03.08.2015