1 問題
Java 程序員面對的最痛苦的事情之一就是在 Java 代碼中嵌入 SQL 語句。
如你所見,MyBatis 在 XML 映射中具備強大的 SQL 動態生成能力。
但有時,我們還是需要在 Java 代碼里構建 SQL 語句。
在 Java 代碼中動態生成 SQL 代碼真的就是一場噩夢。例如:
String sql = "SELECT P.ID, P.USERNAME, P.PASSWORD, P.FULL_NAME, "
"P.LAST_NAME,P.CREATED_ON, P.UPDATED_ON " +
"FROM PERSON P, ACCOUNT A " +
"INNER JOIN DEPARTMENT D on D.ID = P.DEPARTMENT_ID " +
"INNER JOIN COMPANY C on D.COMPANY_ID = C.ID " +
"WHERE (P.ID = A.ID AND P.FIRST_NAME like ?) " +
"OR (P.LAST_NAME like ?) " +
"GROUP BY P.ID " +
"HAVING (P.LAST_NAME like ?) " +
"OR (P.FIRST_NAME like ?) " +
"ORDER BY P.ID, P.FULL_NAME";
2?解決方案
MyBatis 3 提供了方便的工具類來幫助解決此問題。
借助 SQL 類,我們只需要簡單地創建一個實例,并調用它的方法即可生成 SQL 語句。
讓我們來用 SQL 類重寫上面的例子:
private String selectPersonSql() {
? return new SQL() {{
? ? SELECT("P.ID, P.USERNAME, P.PASSWORD, P.FULL_NAME");
? ? SELECT("P.LAST_NAME, P.CREATED_ON, P.UPDATED_ON");
? ? FROM("PERSON P");
? ? FROM("ACCOUNT A");
? ? INNER_JOIN("DEPARTMENT D on D.ID = P.DEPARTMENT_ID");
? ? INNER_JOIN("COMPANY C on D.COMPANY_ID = C.ID");
? ? WHERE("P.ID = A.ID");
? ? WHERE("P.FIRST_NAME like ?");
? ? OR();
? ? WHERE("P.LAST_NAME like ?");
? ? GROUP_BY("P.ID");
? ? HAVING("P.LAST_NAME like ?");
? ? OR();
? ? HAVING("P.FIRST_NAME like ?");
? ? ORDER_BY("P.ID");
? ? ORDER_BY("P.FULL_NAME");
? }}.toString();
}
這個例子有什么特別之處嗎? 仔細看一下你會發現,你不用擔心可能會重復出現的 "AND" 關鍵字,或者要做出用 "WHERE" 拼接還是 "AND" 拼接還是不用拼接的選擇。 SQL 類已經為你處理了哪里應該插入 "WHERE"、哪里應該使用 "AND" 的問題,并幫你完成所有的字符串拼接工作。
3?SQL 類
這里有一些示例:
// 匿名內部類風格
public String deletePersonSql() {
? return new SQL() {{
? ? DELETE_FROM("PERSON");
? ? WHERE("ID = #{id}");
? }}.toString();
}
// Builder / Fluent 風格
public String insertPersonSql() {
? String sql = new SQL()
? ? .INSERT_INTO("PERSON")
? ? .VALUES("ID, FIRST_NAME", "#{id}, #{firstName}")
? ? .VALUES("LAST_NAME", "#{lastName}")
? ? .toString();
? return sql;
}
// 動態條件(注意參數需要使用 final 修飾,以便匿名內部類對它們進行訪問)
public String selectPersonLike(final String id, final String firstName, final String lastName) {
? return new SQL() {{
? ? SELECT("P.ID, P.USERNAME, P.PASSWORD, P.FIRST_NAME, P.LAST_NAME");
? ? FROM("PERSON P");
? ? if (id != null) {
? ? ? WHERE("P.ID like #{id}");
? ? }
? ? if (firstName != null) {
? ? ? WHERE("P.FIRST_NAME like #{firstName}");
? ? }
? ? if (lastName != null) {
? ? ? WHERE("P.LAST_NAME like #{lastName}");
? ? }
? ? ORDER_BY("P.LAST_NAME");
? }}.toString();
}
public String deletePersonSql() {
? return new SQL() {{
? ? DELETE_FROM("PERSON");
? ? WHERE("ID = #{id}");
? }}.toString();
}
public String insertPersonSql() {
? return new SQL() {{
? ? INSERT_INTO("PERSON");
? ? VALUES("ID, FIRST_NAME", "#{id}, #{firstName}");
? ? VALUES("LAST_NAME", "#{lastName}");
? }}.toString();
}
public String updatePersonSql() {
? return new SQL() {{
? ? UPDATE("PERSON");
? ? SET("FIRST_NAME = #{firstName}");
? ? WHERE("ID = #{id}");
? }}.toString();
}