1. 程式人生 > >mybatis進階內容

mybatis進階內容

怎麼獲取自增長的值 ```xml <!-- 將資料庫插入後生成的id值,同步到java物件上     useGeneratedKeys="是否使用由資料庫生成的主鍵"      keyColumn="主鍵列的名稱"      keyProperty="主鍵要存入哪個屬性" --> <insert id="insert" parameterType="com.westos.entity.Student"     useGeneratedKeys="true" keyColumn="id" keyProperty="id">     insert into student (id, name) values (null, #{name}) </insert> ```

## 1.2 動態sql1 foreach 刪除操作:一次刪除多條記錄 delete from student where id in(1); delete from student where id in(1, 2); delete from student where id in(1, 2, 3); // java.util.List -> 簡寫為  list ```xml <!-- list (1,2,3)     collection="要遍歷的集合"     item="臨時變數名稱"     open="迴圈之前的符號"     close="迴圈之後的符號"     separator="每個元素的分隔符"     delete from student where id in (1, 2, 3) --> <delete id="delete" parameterType="list">   delete from student where id in   <foreach collection="list" item="i" open="(" close=")" separator=",">       #{i}   </foreach> </delete> ```

## 1.3 動態sql2 if 按照姓名模糊查詢,年齡範圍查詢 Map map = ... map.put("name", "張%"); map.put("minAge", 10); map.put("maxAge", 20); select * from student where name=#{name} select * from student where age between #{minAge} and #{maxAge} select * from student where name=#{name} and age between #{minAge} and #{maxAge} select * from student // java.util.Map 簡寫為 map ```xml <select id="selectByCondition" parameterType="map" resultType="com.westos.entity.Student">         select * from student     <where>         <if test="name != null">          and name=#{name}         </if>         <if test="minAge != null && maxAge != null">          and age between #{minAge} and #{maxAge}         </if>     </where> </select> ```

動態更新 update student set name=#{}, age=#{} where id=#{} 希望實現修改哪列就在update中出現響應的set語句,而不是出現所有的列 update student set name=#{} wehre id=#{} update student set age=#{} wehre id=#{} ```xml <update id="update" parameterType="com.westos.entity.Student">     update student     <set>         <if test="name != null">             name = #{name},         </if>         <if test="age != 0">             age = #{age},         </if>     </set>     where id = #{id} </update> ```

## 1.4 分頁查詢 limit 下標, 數量 方法1:物理分頁(使用sql語句實現分頁) 缺點:不通用,資料庫不同sql語法有差異:     mysql, limit     sqlserver,  top, row_number()     oracle, rownum ```xml <!-- map     .put("m", 下標);     .put("n", 數量); --> <select id="selectByPage" parameterType="map" resultType="com.westos.entity.Student">     select * from student limit #{m}, #{n} </select> ```

方法2:邏輯分頁(把所有記錄都查出來,用jdbc程式碼實現分頁) 優點:通用,sql程式碼都是查詢所有      效率低,適合資料很少的情況 ```xml <!-- 邏輯分頁 --> <select id="selectLogical" resultType="com.westos.entity.Student">     select * from student </select> ``` ```java // rowBounds一定要作為第三個引數 List<Student> list = sqlSession.selectList("com.westos.mapper.StudentMapper.selectLogical", null,         new RowBounds(5, 5)); for (Student student : list) {     System.out.println(student); } ```

## 1.5 表和實體類不匹配 create table teacher (    id int primary key auto_increment,    first_name varchar(20),    last_name varchar(20) ); ```xml <!-- 方法1: 可以使用列別名來解決不一致問題 --> <select id="selectOne" parameterType="int" resultType="com.westos.entity.Teacher">     select id,first_name firstName,last_name lastName from teacher where id = #{id} </select> ```

```xml <!-- 方法2: 使用 resultMap 代替 resultType完成對映 --> <select id="selectOne" parameterType="int" resultMap="aaa">     select id, first_name, last_name from teacher where id = #{id} </select>

<!-- type="實體物件的型別"      id 標籤用來對映主鍵      result 標籤用來對映其它列 --> <resultMap id="aaa" type="com.westos.entity.Teacher">     <!-- column="列名" property="屬性名" -->     <id column="id" property="id"></id>     <result column="first_name" property="firstName"></result>     <result column="last_name" property="lastName"></result> </resultMap> ```

## 1.6 連線查詢的對映 商品和類別 select * from product p inner join category c on p.category_id = c.id where p.id=1; ```xml <!-- 把連線查詢對映到兩個有關係的實體類上 --> <select id="selectById" parameterType="int" resultMap="bbb">     select p.id, p.name, p.price, c.id cid, c.name cname      from product p inner join category c on p.category_id = c.id where p.id=#{id} </select>

<!-- association 關聯 --> <resultMap id="bbb" type="com.westos.entity.Product">     <id column="id" property="id"></id>     <result column="name" property="name"></result>     <result column="price" property="price"></result>     <!-- property="關係屬性名" -->     <association property="category" javaType="com.westos.entity.Category">         <id column="cid" property="id"></id>         <result column="cname" property="name"></result>     </association> </resultMap> ```

## 1.7 mybatis中的快取 1) 一級快取    每個sqlsession都有一個一級快取,只要sql語句和引數相同,只有第一次查詢資料庫,並且會把查詢結果放入一級快取    之後的查詢,就直接從一級快取中獲取結果        一級快取的作用範圍,只限於一個sqlsession     2) 二級快取    所有sqlSession共享的快取

    一級快取無需配置,而二級快取需要配置     <!-- 開啟 ProductMapper的二級快取, 會讓本mapper內的所有select利用二級快取-->     <cache/>      二級快取的意義是減少與資料庫的互動,從而提升程式的效能

3) 快取失效 只要是執行了增,刪,改的操作,快取就應該失效,仍然從資料庫查詢得到最新結果

4) 二級快取適用場景 當資料的查詢遠遠多於修改時, 才有啟用二級快取的必要

## 1.8 `#{}` 與 `${}` 的區別 區別1: `#{}` 生成的sql語句是用?佔位符的方式, 可以防止sql注入攻擊 `${}` 生成的sql語句是直接把值進行了字串的拼接, 有注入攻擊漏洞

區別2: `${}` 可以進行運算 `#{}` 不能運算

區別3: `#{}` 在sql語句中只能替換值, 不能是表名,列名,關鍵字 `${}` 可以替換sql語句的任意部分