【MyBatis】MyBatis 動態 SQL
阿新 • • 發佈:2020-12-19
MyBatis 動態SQL
if
可以根據實體類的不同取值,使用不同的 SQL 語句來進行查詢。
使用動態 SQL 最常見情景是根據條件包含 where 子句的一部分。
持久層 DAO 介面:
public interface UserDAO {
/**
* 根據使用者資訊,查詢使用者列表
* @param user
* @return
*/
List<User> findByUser(User user);
}
DAO 對映配置:
<mapper namespace="cn.parzulpan.dao.UserDAO"> <select id="findByUser" resultType="User" parameterType="User"> select * from user where 1 = 1 <if test="username != null and username != ''"> and username like #{username} </if> <if test="address != null"> and address like #{address} </if> </select> </mapper>
測試:
@Test
public void findByUserTest() {
User user = new User();
user.setUsername("%Tim%");
// user.setAddress("%北京%");
List<User> users = userDAO.findByUser(user);
for (User u : users) {
System.out.println(u);
}
}
choose、when、otherwise
有時候,如果不想使用所有的條件,而只是想從多個條件中選擇一個使用。針對這種情況,MyBatis 提供了 choose
switch
語句。
持久層 DAO 介面:
public interface UserDAO {
/***
* 根據使用者資訊,查詢使用者列表,提供預設情況
* @param user
* @return
*/
List<User> findByUserDefault(User user);
}
DAO 對映配置:
<mapper namespace="cn.parzulpan.dao.UserDAO"> <select id="findByUserDefault" resultType="User" parameterType="User"> select * from user where 1 = 1 <choose> <when test="username !=null and username != ''"> and username like #{username} </when> <when test="address != null"> and address like #{address} </when> <otherwise> and id > 50 </otherwise> </choose> </select> </mapper>
測試:
@Test
public void findByUserDefaultTest() {
User user = new User();
// user.setUsername("%Tim%");
List<User> users = userDAO.findByUserDefault(user);
for (User u : users) {
System.out.println(u);
}
}
trim、where、set
為了去掉上面的 where 1 = 1
恆成立語句,可以使用 where 元素
,where 元素只會在子元素返回任何內容的情況下才插入 “WHERE” 子句。而且,若子句的開頭為 “AND” 或 “OR”,where 元素也會將它們去除。
持久層 DAO 介面:
public interface UserDAO {
/**
* 根據使用者資訊,查詢使用者列表,使用 Where
* @param user
* @return
*/
List<User> findByUserWhere(User user);
}
DAO 對映配置:
<mapper namespace="cn.parzulpan.dao.UserDAO">
select * from user
<where>
<if test="username != null and username != ''">
and username like #{username}
</if>
<if test="address != null">
and address like #{address}
</if>
</where>
</mapper>
測試:
@Test
public void findByUserWhereTest() {
User user = new User();
// user.setUsername("%Tim%");
List<User> users = userDAO.findByUserWhere(user);
for (User u : users) {
System.out.println(u);
}
}
也可以通過自定義 trim
元素來定製 where 元素的功能。比如,和 where 元素等價的自定義 trim 元素為:
<trim prefix="WHERE" prefixOverrides="AND |OR ">
...
</trim>
prefixOverrides
屬性會忽略通過管道符分隔的文字序列,上述例子會移除所有 prefixOverrides 屬性中指定的內容,並且插入 prefix
屬性中指定的內容。
set
元素可以用於動態包含需要更新的列,忽略其它不更新的列,通常用於動態更新語句。
<mapper namespace="cn.parzulpan.dao.UserDAO">
update user
<set>
<if test="username != null and username != ''">
username = #{username},
</if>
<if test="address != null">
address = #{address},
</if>
</set>
where id = #{id}
</mapper>
和 set 元素等價的自定義 trim 元素為:
<trim prefix="SET" suffixOverrides=",">
...
</trim>
foreach
動態 SQL 的另一個常見使用場景是對集合進行遍歷,尤其是在構建 IN 條件語句的時候。
持久層 DAO 介面:
public interface UserDAO {
/**
* 根據 id 集合查詢使用者
* @param v
* @return
*/
List<User> findByIds(QueryV v);
}
DAO 對映配置:
<mapper namespace="cn.parzulpan.dao.UserDAO">
<select id="findByIds" resultType="User" parameterType="QueryV">
select * from user
<where>
<if test="ids != null and ids.size() > 0">
<foreach collection="ids" open="id in (" close=")" item="uid" separator=",">
#{uid}
</foreach>
</if>
</where>
</select>
</mapper>
測試:
@Test
public void findByIdsTest() {
List<Integer> ids = new ArrayList<>();
ids.add(41);
ids.add(42);
ids.add(43);
ids.add(50);
ids.add(51);
ids.add(60);
QueryV queryV = new QueryV();
queryV.setIds(ids);
List<User> users = userDAO.findByIds(queryV);
for (User u : users) {
System.out.println(u);
}
}
簡化編寫的 SQL 片段
Sql 中可將重複的 sql 提取出來,使用時用 include 引用即可,最終達到 sql 重用的目的。
定義程式碼片段:
<!-- 抽取重複的語句程式碼片段 -->
<sql id="defaultSql">
select * from user
</sql>
引用程式碼片段:
<!-- 配置查詢所有操作 -->
<select id="findAll" resultType="user">
<include refid="defaultSql"></include>
</select>
<!-- 根據 id 查詢 -->
<select id="findById" resultType="User" parameterType="int">
<include refid="defaultSql"></include>
where id = #{uid}
</select>