有沒有辦法用 Hibernate 實作 DSL 查詢?我的意思主要是更容易和更安全的 HQL 陳述句構建。例如,像這樣的 HQL 查詢:select u.id from Users u where u.person.identityCard.lastName like :lastNameVar會寫成這樣:
Select.from(User.class, “u”).where(eq(“u”, User.person().identityCard().lastName(), lastNameVar))
作為實驗,我已經撰寫了構建器本身,但我似乎無法弄清楚如何制作那些多步 DSL 路徑 ( User.person().identityCard().lastName())。我顯然必須向我的物體類添加一些內容,例如:
@Entity
public class User {
public static DSLProperty<Person> person() = new DSLProperty<>(“person”); // how do I write DSLProperty class to achieve this?
@OneToOne
@JoinColumn(name=“person_id”)
private Person person;
//getters, setters etc.
}
但是我似乎缺乏關于如何呼叫抽象類的命名方法的知識,比如DSLProperty在鏈接屬性路徑時。
Ps 這更多的是我想自己弄清楚的實驗性功能。我知道像 QueryDSL 和 jOOQ 這樣的庫,但我不確定它們是否支持屬性鏈接,而且我對從頭開始實作這個功能更感興趣。
uj5u.com熱心網友回復:
陳舊而冗長的解決方案——CriteriaBuilder
調制解調器一——QueryDSL
uj5u.com熱心網友回復:
所以,花了一些時間解決這個問題(正如我所說,這更像是一個實驗性的事情)我得出了這樣的解決方案:
首先,我創建了一個基礎DSLProperty.class:
public class DSLProperty {
protected String previousPath; // this will hold the path till the current step of the path chain
public DSLProperty( String previousPath ) {
this.previousPath = previousPath;
}
public String getPath() { return previousPath; }
}
然后,在我的抽象基物體類中,我創建了這樣的靜態內部類:
public static class DSL extends DSLProperty {
protected DSL( String input ) {
super( input );
}
public DSLProperty id() {
return property( "id" );
}
protected DSLProperty property( String property ) {
return new DSLProperty( ( previousPath != null ? previousPath "." : "" ) property );
}
}
并且基本上DSL在所有子物體中擴展(可能使用您的IDE或Maven來生成)這個基類,例如DSLTestUser.class:
@Entity
@Table
public class DSLTestUser extends DSLTestBaseEntity {
public static DSL alias( String alias ) { return new DSL( alias ); }
public static class DSL extends DSLTestBaseEntity.DSL {
public DSL( String input ) {
super( input );
}
public DSLProperty username() { return property( "username" ); }
public DSLTestPerson.DSL person() { return DSLTestPerson.alias( previousPath ".person" ); }
}
// all the columns, getters & setters etc.
}
和DSLTestPerson.class:
@Entity
@Table
public class DSLTestPerson extends DSLTestBaseEntity {
public static DSL alias( String alias ) { return new DSL( alias ); }
public static class DSL extends DSLTestBaseEntity.DSL {
public DSL( String input ) {
super( input );
}
public DSLProperty name() { return property( "name" ); }
public DSLTestUser.DSL user() { return DSLTestUser.alias( previousPath ".user" ); }
}
// all the columns, getters & setters etc.
}
這樣,這段代碼:
System.out.println( DSLTestUser.alias( "tu" ).person().id().getPath() );
System.out.println( DSLTestUser.alias( "tu" ).username().getPath() );
System.out.println( DSLTestPerson.alias( "tp" ).user().username().getPath() );
System.out.println( DSLTestPerson.alias( "tp" ).getPath() );
將產生以下輸出:
tu.person.id
tu.username
tp.user.username
tp
您的路徑鏈的長度沒有限制,您可以使用它以任何您希望使用此域特定屬性路徑生成的方式生成 HQL 查詢。
該錯誤我一個位的代碼,你需要寫(再次,您可以生成它),有多少個物件的每個路徑將創建大量的唯一的事情(取決于步驟的數量),但親本解決方案是,如果您更改屬性的名稱,您將不必擔心在 HQL 查詢中找到它使用的所有位置 - 只需DSL使用 IDE 的重構功能更改相應內部類中的屬性即可。
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/376475.html
上一篇:@Embeddable或@Entity我們應該選擇哪一個
下一篇:一對多關系不回傳資料庫中的所有值
