今天一個新同事問我,我知道如何利用XML的方式來構建動態SQL,但是Mybatis是否可以利用註解完成動態SQL的構建呢?!!答案是確定的,MyBatis 提供了註解,@InsertProvider,@UpdateProvider,@DeleteProvider 和@SelectProvider,來幫助構建動態 SQL 語句,而後讓MyBatis 執行這些 SQL 語句。
java
建立一個 TutorDynaSqlProvider.java 類,以及 findTutorByIdSql()方法apache
package com.test.myBatisTest;app
import org.apache.ibatis.jdbc.SQL;ide
public class TutorDynaSqlProvider {
public String findTutorByIdSql(int tutorId) {
return "SELECT TUTOR_ID AS tutorId, NAME, EMAIL FROM TUTORS WHERE TUTOR_ID=" + tutorId;
}
}工具
在 TutorMapper.java 接口中建立一個映射語句spa
@SelectProvider(type=TutorDynaSqlProvider.class, method="findTutorByIdSql") Tutor findTutorById(int tutorId);
使用SQL類來構建動態SQL以下所示blog
import org.apache.ibatis.jdbc.SQL; public class TutorDynaSqlProvider { public String findTutorByIdSql(final int tutorId) { return new SQL() { { SELECT("tutor_id as tutorId, name, email"); FROM("tutors"); WHERE("tutor_id=" + tutorId); } }.toString(); } }
SQL 工具類會處理以合適的空格前綴和後綴來構造 SQL 語句。能夠接受的參數類型無參數和映射器 Mapper 接口的方法以及同類型的參數 java.util.Map。 若是映射器 Mapper 接口有多個輸入參數,咱們可使用參數類型爲 java.util.Map 的方法做爲 SQL provider 方法。而後映射器 Mapper 接口方法全部的輸入參數將會被放到 map 中,以 param1,param2 等等做爲 key,將輸入參數按接口
序做爲 value。 你也可使用 0,1,2 等做爲 key 值來取的輸入參數。以下所示ip
@SelectProvider(type = TutorDynaSqlProvider.class, method = "findTutorByNameAndEmailSql") Tutor findTutorByNameAndEmail(String name, String email); public String findTutorByNameAndEmailSql(Map<String, Object> map) { String name = (String) map.get("param1"); String email = (String) map.get("param2"); // you can also get those values using 0,1 keys // String name = (String) map.get("0"); // String email = (String) map.get("1"); return new SQL() { { SELECT("tutor_id as tutorId, name, email"); FROM("tutors"); WHERE("name=#{name} AND email=#{email}"); } }.toString(); }
package com.test.myBatisTest; import org.apache.ibatis.jdbc.SQL; public class TutorDynaSqlProvider { public String selectTutorById() { return new SQL() { { SELECT("t.tutor_id, t.name as tutor_name, email"); SELECT("a.addr_id, street, city, state, zip, country"); SELECT("course_id, c.name as course_name, description,start_date, end_date"); FROM("TUTORS t"); LEFT_OUTER_JOIN("addresses a on t.addr_id=a.addr_id"); LEFT_OUTER_JOIN("courses c on t.tutor_id=c.tutor_id"); WHERE("t.TUTOR_ID = #{id}"); } }.toString(); } }
package com.test.myBatisTest; import org.apache.ibatis.jdbc.SQL; public class TutorDynaSqlProvider { public String insertTutor(final Tutor tutor) { return new SQL() { { INSERT_INTO("TUTORS"); if (tutor.getName() != null) { VALUES("NAME", "#{name}"); } if (tutor.getEmail() != null) { VALUES("EMAIL", "#{email}"); } } }.toString(); } } public interface TutorMapper { @InsertProvider(type = TutorDynaSqlProvider.class, method = "insertTutor") @Options(useGeneratedKeys = true, keyProperty = "tutorId") int insertTutor(Tutor tutor); }
package com.test.myBatisTest; import org.apache.ibatis.jdbc.SQL; public class TutorDynaSqlProvider { public String updateTutor(final Tutor tutor) { return new SQL() { { UPDATE("TUTORS"); if (tutor.getName() != null) { SET("NAME = #{name}"); } if (tutor.getEmail() != null) { SET("EMAIL = #{email}"); } WHERE("TUTOR_ID = #{tutorId}"); } }.toString(); } } public interface TutorMapper { @UpdateProvider(type = TutorDynaSqlProvider.class, method = "updateTutor") int updateTutor(Tutor tutor); }
package com.test.myBatisTest; import org.apache.ibatis.annotations.DeleteProvider; import org.apache.ibatis.jdbc.SQL; public class TutorDynaSqlProvider { public String deleteTutor(int tutorId) { return new SQL() { { DELETE_FROM("TUTORS"); WHERE("TUTOR_ID = #{tutorId}"); } }.toString(); } } public interface TutorMapper { @DeleteProvider(type = TutorDynaSqlProvider.class, method = "deleteTutor") int deleteTutor(int tutorId); }
以上就是使用註解的方式來動態的構建SQL,能夠說和XML方式有很大的不一樣,可是功能上面彷佛沒有XML方式的強大,我我的更喜歡使用XML的方式來構建,同時對參數進行各類操做。ci