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語句的任意部分