我正在使用JDBI和Dropwizard,並且遇到流暢查詢的問題。我有一個API端點,看起來像這樣:JDBI Fluent查詢問題
public Response getAccount(@QueryParam("nickname") String nickname, @QueryParam("email") String email);
我試圖要避免編寫以下3個疑問:
@SqlQuery( " SELECT * FROM ACCOUNT WHERE EMAIL = :email " )
public Account getAccountByEmail(@Bind("email") String email);
@SqlQuery(" SELECT * FROM ACCOUNT WHERE NICKNAME = :nickname ")
public Account getAccountByNickname(@Bind("nickname") String nickname);
@SqlQuery(" SELECT * FROM ACCOUNT WHERE NICKNAME = :nickname AND EMAIL = :email " )
public Account getAccount(@Bind("nickname") String nickname, @Bind("email") String email);
這也意味着,我的實施方法getAccount有3個如果檢查...暱稱,沒有電子郵件,電子郵件和暱稱,電子郵件和暱稱,以確定運行3個查詢中的哪一個。如果我要添加另一個查找參數(例如accountId),這意味着我現在需要有6個查詢(每個可能性1個)和6個if語句來確定要運行哪個查詢。
有沒有簡單的方法來解決這個與JDBI?我已經研究過@Define的可能性,但這會帶來SQL注入的風險。電子郵件和暱稱都是字符串。
我理想只需要一個查詢:
@SqlQuery(" SELECT * FROM ACCOUNT WHERE NICKNAME = :nickname AND EMAIL = :email " )
public Account getAccount(@Bind("nickname") String nickname, @Bind("email") String email);
如果暱稱爲null,將忽略暱稱要求,只是詢問過的電子郵件。是這樣的可能嗎?
編輯/ UPDATE:
@SqlQuery(" SELECT * FROM ACCOUNT WHERE <query> ")
public Account getAccount(@Bind("id") Long id, @Bind("nickname") String nickname, @Bind("email") String email, @Define("query") String query);
我已經更新了我JDBI DAO使用@define:
我現在爲了清理我的代碼有點做到了這一點。通過這樣做,我可以削減我的6個查詢(每個案例1個查詢,因爲有3個查詢字段),以及6個查詢語句減少到1個查詢和3個if語句。
Account account = null;
StringBuilder query = new StringBuilder();
if(accountId != null) {
query.append(" ID = :id ");
}
if(!Strings.isNullOrEmpty(nickname)) {
if(query.length() > 0) query.append(" AND ");
query.append(" NICKNAME = :nickname ");
}
else if(!Strings.isNullOrEmpty(email)) {
if(query.length() > 0) query.append(" AND ");
query.append(" EMAIL = :email ");
}
account = accountDAO.getAccount(accountId, nickname, email, query.toString());
我寧願沒有用,雖然定義爲我想繼續我的查詢邏輯在DAO。這將是很好,如果這樣的事情是在所有可能的:
SELECT * FROM ACCOUNT WHERE @IfNotNull(id = :id)
AND @IfNotNull(email = :email) AND @IfNotNull(nickname = :nickname)
好主意,但在技術上你應該使用(合併(:電子郵件, '')= '' OR =電子郵件:電子郵件)來匹配bcam909的if(Strings.isNullOrEmpty(電子郵件)!)。與暱稱相同。 – alecswan 2015-02-06 18:50:24
如果電子郵件地址和暱稱都不爲空,這將會起作用。如果暱稱和電子郵件都爲空,它將返回所有帳戶。在調用此查詢之前,我必須添加一個支票,以確保暱稱和電子郵件都不爲空或空。 – bcam909 2015-02-06 22:28:20