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

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