mybatis 進階內容
mybatis 進階內容
1.1 新增操作
怎麼獲取自增長的值
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>
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
<!-- 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
<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=#{}
<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
<!-- 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程式碼都是查詢所有
效率低,適合資料很少的情況
<!-- 邏輯分頁 -->
<select id="selectLogical" resultType="com.westos.entity.Student">
select * from student
</select>
// 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 表和實體類不匹配
<!-- 方法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>
<!-- 方法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>
商品和類別
select * from product p inner join category c on p.category_id = c.id where p.id=1;
<!-- 把連線查詢對映到兩個有關係的實體類上 -->
<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語句的任意部分