1. 程式人生 > >MyBatis框架基本操作及進階部分

MyBatis框架基本操作及進階部分

1、基本操作

  1. 1 pom.xml

    java    7行

<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.4.5</version>
</dependency>
GAV座標
  1. 2配置檔案 mybatis-config.xml 連線資料庫 url, driver, username, password

    java    2行

<mapper resource="包名/XXMapper.xml" />
  1. 3 對映檔案 XXMapper.xml

    java    8行

<mapper namespace="包名.XXMapper"> // 防止命名衝突
    <insert id="insert" parameterType="實體型別"> 插入sql, #{實體屬性值} </insert>
    <update id="update" parameterType="實體型別"> 更新sql, #{實體屬性值} </update>
    <delete id="delete" parameterType="基本型別"> 刪除sql, #{任意字串} </delete>
    <select id="查詢單個" parameterType="查詢條件型別" resultType="實體型別"> 查詢sql </select>
    <select id="查詢多個" parameterType="查詢條件型別" resultType="實體型別"> 查詢sql </select>
</mapper>
  1. 4 java 程式碼

    java    10行

SqlSessionFactory factory = new SqlSessionFactoryBuilder(配置檔案的輸入流);
SqlSession sqlSession = factory.openSession();
sqlSession.insert("namespace.id", 引數物件);
sqlSession.update("namespace.id", 引數物件);
sqlSession.delete("namespace.id", 引數物件);
實體型別 obj = sqlSession.selectOne("namespace.id", 引數物件); // 查詢單個結果
List<實體型別> obj = sqlSession.selectList("namespace.id", 引數物件); // 查詢單個結果
sqlSession.commit(); // 提交事務
sqlSession.close(); // 關閉資源

===============================================================

2、mybatis 進階內容

2.1 新增操作

    sql    6行

create table student(
  id int primary key auto_increment,
  name varchar(20),
  age int
);

怎麼獲取自增長的值

    xml    11行

<!-- 
將資料庫插入後生成的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.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    15行

<!-- 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>

2.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    12行

<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    13行

<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>

2.4 分頁查詢

limit 下標, 數量 方法1:物理分頁(使用sql語句實現分頁) 缺點:不通用,資料庫不同sql語法有差異: mysql, limit sqlserver, top, row_number() oracle, rownum

    xml    8行

<!-- 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    5行

<!-- 邏輯分頁 -->
<select id="selectLogical" resultType="com.westos.entity.Student">
    select * from student
</select>

    java    7行

// rowBounds一定要作為第三個引數
List<Student> list = sqlSession.selectList("com.westos.mapper.StudentMapper.selectLogical", null,
        new RowBounds(5, 5));
for (Student student : list) {
    System.out.println(student);
}

2.5 表和實體類不匹配

create table teacher ( id int primary key auto_increment, first_name varchar(20), last_name varchar(20) );

    xml    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>

    xml    16行

<!-- 方法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>

2.6 連線查詢的對映

商品和類別 select * from product p inner join category c on p.category_id = c.idwhere p.id=1;

    xml    18行

<!-- 把連線查詢對映到兩個有關係的實體類上 -->
<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>

2.7 mybatis中的快取

  1. 一級快取 每個sqlsession都有一個一級快取,只要sql語句和引數相同,只有第一次查詢資料庫,並且會把查詢結果放入一級快取 之後的查詢,就直接從一級快取中獲取結果

    一級快取的作用範圍,只限於一個sqlsession

  2. 二級快取 所有sqlSession共享的快取

    一級快取無需配置,而二級快取需要配置

二級快取的意義是減少與資料庫的互動,從而提升程式的效能

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

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

2.8 #{} 與 ${} 的區別

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

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

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