一、MyBatis的註解開發
- 開發中推薦是使用xml檔案配置
1、配置對映關係【使用註解的方式】:
<!-- 全域性的配置檔案 -->
<configuration>
<!-- 2、關聯對映檔案/ 關聯Mapper介面 -->
<mappers>
<!-- <mapper resource="com/shan/hello/mapper/UserMapper.xml"/>-->
<mapper class="com.shan.hello.mapper.UserMapper"/>
</mappers>
</configuration>
2、通過註解,把sql和對映寫到Mapper介面:
public interface UserMapper {
@Insert("insert into t_user (name, salary) values (#{name}, #{salary});")
@Options(useGeneratedKeys = true,keyProperty = "id")
void save(User user);
@Delete("delete from t_user where id = #{id};")
void delete(Long id);
@Update("update t_user set name = #{name}, salary = #{salary} where id = #{id};")
void update(User user);
// void update(User user, Long id);//錯誤:myBatis預設只能傳遞一個引數
@Select("select id u_id, name as u_name, salary u_salary from t_user where id = #{id}")
@Results(id="BaseResultMap", value= {
@Result(column = "u_id",property = "id"),
@Result(column = "u_name",property = "name"),
@Result(column = "u_salary",property = "salary")
})
User get(Long id);
@Select("select id u_id, name as u_name, salary u_salary from t_user")
@ResultMap("BaseResultMap")
List<User> getListAll();
}
3、測試(這裡以測試查詢為例):
/* 測試查詢 */
@Test
public void testGet() throws IOException {
SqlSession session = MyBatisUtil.getSession();
UserMapper userMapper = session.getMapper(UserMapper.class);
User user = userMapper.get(2L);
System.out.println(user);
//5、關閉資源
session.close();
}
二、動態SQL 【類似JSTL(java標準標籤庫)語法】
-
if
-
choose (when, otherwise)
-
trim (where, set)
-
foreach
-
其他(bind,sql,include)
1、if 舉例:
<!-- 對映檔案 -->
<select id="select" resultType="Employee">
select * from employee
<if test="minSalary != null">
where salary >= #{minSalary}
</if>
</select>
-
細節:在xml中 小於符合不能直接輸入 < , 會被當做標籤的開始標誌,需要使用轉義符號 <;
-
防止第一個查詢條件是null,加上 where 1=1,然後其他查詢條件接著and 寫。
2、choose (when, otherwise) 舉例:
<!-- 對映檔案 -->
<select id="select" resultType="Employee">
select * from employee where 1=1
<if test="minSalary != null">
and salary >= #{minSalary}
</if>
<choose>
<when test="deptId > 0">and deptId = #{deptId}</when>
<otherwise>and deptId is not null</otherwise>
</choose>
</select>
3-1、trim (where, set)- where 舉例:
-
解決sql拼接查詢條件時第一個條件為null,而加上 where 1=1,導致不能進行索引查詢,影響效能。
-
where 元素:判斷查詢條件是否有where關鍵字,若沒有,則第一個查詢條件之前要插入 where
若發現查詢條件是以and/or開頭,則會把第一個查詢條件前的and/or 替換成 where
<!-- 對映檔案 -->
<select id="select" resultType="Employee">
select * from employee
<where>
<if test="minSalary != null">
and salary >= #{minSalary}
</if>
<if test="maxSalary != null">
and salary <= #{maxSalary}
</if>
<choose>
<when test="deptId > 0">and deptId = #{deptId}</when>
<otherwise>and deptId is not null</otherwise>
</choose>
</where>
</select>
3-2、trim (where, set)-set 舉例:
- 和where 類似,動態去掉最後一個逗號
<update id="updateAuthorIfNecessary">
update Author
<set>
<if test="username != null">username=#{username},</if>
<if test="password != null">password=#{password},</if>
<if test="email != null">email=#{email},</if>
<if test="bio != null">bio=#{bio}</if>
</set>
where id=#{id}
</update>
3-3、trim (where, set)-trim :
<trim prefix="" prefixOverrides="" suffix="" suffixOverrides="">
<!--trim 包含的動態 SQL-->
</trim>
□ prefix – 在這個字串之前插入 prefix 屬性值。
□ prefixOverrides – 並且字串的內容以 prefixOverrides 中的內容開頭(可以包含管道符號),那麼使用 prefix 屬性值替換內容的開頭。
□ suffix – 在這個字串之後插入 suffix 屬性值。
□ suffixOverrides –並且字串的內容以 suffixOverrides 中的內容結尾(可以包含管道符號),那麼使用 suffix 屬性值替換內容的結尾。
-
使用 where 等價於:
注意:此時 AND 後面有一個空格。 -
使用 set 等價於:
4、foreach 舉例1:
/* Mapper介面 */
void batchDelete(@Param("ids")List<Long> ids);
<!-- 對映檔案 -->
<!--
foreach 元素: collection屬性:表示要迭代的集合或陣列【的型別,若是通過Parm註解,可以直接寫上Map中的key,而不用填寫型別】
open屬性:在集合迭代之前,要拼接的符號 close 屬性:在集合迭代之後要拼接的符號
separator屬性:迭代的元素之間的分割符號
item屬性:每個被迭代的元素
index屬性:迭代的索引
-->
<delete id="batchDelete">
delete from employee where id in
<foreach collection="ids" open="(" close=")" separator="," item="id">
#{id}
</foreach>
</delete>
■ foreach 舉例2:
/* Mapper介面 */
void batchSave(@Param("emps")List<Employee>emps);
<!-- 對映檔案 -->
<insert id="batchSave">
insert into employee (name, sn, salary) values
<foreach collection="emps" separator="," item="e">
(#{e.name}, #{e.sn}, #{e.salary})
</foreach>
</insert>
5、其他(bind,sql,include) 舉例-高階分頁查詢:
■ sql,include 的例子:
<!-- 對映檔案 -->
<mapper namespace="com.shan.hello.mapper.EmployeeMapper">
<sql id="base_where">
<where>
<if test="keyword != null">
<!--and name like #{%name%}; 要使用字串函式concat進行拼接呀 -->
<!-- and name like concat('%', #{name}, '%') or sn like concat('%', #{sn},'%'); qo查詢物件,也沒有屬性name,sn呀 -->
and (name like concat('%', #{keyword}, '%') or sn like concat('%', #{keyword}, '%'))
</if>
<if test="minSalary != null">
and salary >= #{minSalary}
</if>
<if test="maxSalary != null">
and salary <= #{maxSalary}
</if>
<if test="deptId > 0">
and deptId = #{deptId}
</if>
</where>
</sql>
<select id="queryForList" resultType="Employee">
select id, name, sn, salary from employee
<include refid="base_where"/>
</select>
<select id="queryForCount" resultType="int">
select count(id) from employee
<include refid="base_where"/>
</select>
</mapper>
■ bind(跟concat一樣是用於拼接字串) 的例子:
<if test="keyword != null">
<!--and name like #{%name%}; 要使用字串函式concat進行拼接呀 -->
<!-- and name like concat('%', #{name}, '%') or sn like concat('%', #{sn},'%'); qo查詢物件,也沒有屬性name,sn呀 -->
<!-- and (name like concat('%', #{keyword}, '%') or sn like concat('%', #{keyword}, '%')) -->
<bind name="keywordLike" value="'%' + keyword + '%'"/>
and (name like #{keywordLike} or sn like #{keywordLike})
</if>