mybatis入門(三):mybatis的基礎特性


mybatis的知識點:

  1.mybatis和hibernate本質區別和應用場景
    hibernate:是一個標准的ORM框架(Ojbect relation mapper對象關系映射).入門門檻較高的,不需要程序員寫sql,
    sql語句自動生成了。對sql語句進行優化,修改比較困難。
    應用場景:
      適用於需求變化不多的中小型項目.比如后台管理,erp,orm,oa..

    mybatis:專注於sql本身,需要程序員自己編寫sql語句,sql修改,優化比較方便,mybatis是一個不完全的ORM框架,
    雖然程序員自己寫sql,mybatis也可以實現映射(輸入映射,輸出映射)
    應用場景:
    適用於需求變化較多的項目,比如:互聯網項目

  2.sqlSession:是一個面向用戶(程序員)的接口
    sqlSession中提供了很多操作數據的方法.如:selectOne(返回單個對象),selectList(返回單個或多個對象)
    sqlSession是線程不安全的,在sqlSession實現了除了接口有的方法(操作數據庫的方法)還有數據域屬性
    sqlSession最佳應用場合在方法體內,定義成局部變量使用。

  3.總結原始dao開發的問題(User.xml)
    1.dao接口實現類方法中存在大量模板方法,設想能否將這些代碼提取出來,大大減輕程序員的工作量
    2.調用sqlsession方法是將statement的id硬編碼了 3.調用sqlsession方法是傳入的變量,由於sqlsession方法使用泛型,即使變量傳入錯誤,在編譯階段也不報錯。

    不利於程序員開發

  4.mapper代理方法(程序員只需要mapper接口(相當於dao接口))
    1.還需要編寫mapper.xml映射文件(同時切記要在sqlMapConfig.xml里面加上這個)

    2.程序員只需要開發mapper接口需要遵循一些開發規范,mybatis可以自動生成mapper接口實現類的代理對象
      開發規范:
        1.在mapper.xml中namespace等於mapper接口地址
          <!-- namespace命名空間,作用就是對sql進行分類化管理,理解sql隔離-->
          <!--注意:使用mapper代理方法開發,namespace有特殊重要的作用-->
          <mapper namespace="cn.wj.test.mybatis.mapper.UserMapper">
        2.mapper.java接口中的方法名和mapper.xml中statement的id一致 3.mapper.java接口中的方法輸入參數類型和mapper.xml中parameterType指定的類型一致         4.mapper.java接口中方法的返回值的類型和mapper.xml中statement中resultType的類型一致
        例如:
        mapper.java接口方法:
        //根據id查詢查詢用戶(此時這個方法名要和statement的id保持一致)

          public User findUserById(int id) throws Exception;

        UserMapper.xml:

1 <select id="findUserById" parameterType="int" resultType="cn.wj.test.mybatis.pojo.User">
2   select * from user where id = #{id}
3 </select>

 

      在sqlMapper.xml添加UserMapper.xml映射
      總結:以上的開發規范主要是對下邊代碼進行統一的生成

    

    3.代理對象內部調用selectOne或selectList
      如果mapper方法返回單個pojo對象(非集合對象),代理對象內部通過selectOne查詢數據庫
      如果mapper方法返回集合對象,代理對象內部通過selectList查詢數據庫

    

    4.mapper接口方法參數只能有一個是否影響系統開發
      mapper接口方法參數只有一個,系統是否不利於擴展維護?
      答:系統框架中,dao層的代碼是被業務員公用的
      即使mapper接口中只有一個參數,也可以使用包裝類型的pojo滿足不同的業務方法的需求 注意:持久層方法的參數可以是包裝類型,

      map...,service方法中建議不要使用包裝類型(不利於業務層的可擴展)

    

    5.sqlMapConfig.xml中配置文件的內容和順序如下:
      properties(屬性)
      settings(全局配置參數)
      typeAliases(類型別名)
      typeHandlers(類型處理器)
      objectFactory(對象工廠)
      plugins(插件)

      1.properties(屬性)
      需求: 將數據庫連接參數單獨配置在db.properties中,只需要在sqlMapConfig.xml中加載dp.properties的屬性值,

      在sqlMapperConfig.xml就不需要對數據庫的連接參數進行編碼了
      properties特性:
      注意:mybatis將按照下面的順序加載屬性
        1.在properties元素體內定義的屬性首先揮別讀取
        2.然后會讀取properties元素中resource或url加載的屬性,他會覆蓋已讀取的同名屬性
        3.最后讀取parameterType傳遞的屬性,他會覆蓋已讀取的同名屬性
        建議:
        不要在properties元素體內添加任何屬性值,只將屬性值定義在prperties中,在properties文件中屬性名一定有一定的特性:如xxxx.xxx.xx

      例子:

      1.db.properties(這個里面就是屬性名就是比較特殊,例如jdbc.driver,jdbc。url)

1       jdbc.driver=com.mysql.jdbc.Driver
2           jdbc.url=jdbc:mysql://localhost:3306/mybatisData?characterEncoding=utf-8
3           jdbc.username=root
4           jdbc.password=root

      sqlMapConfig文件中: 

 1         <!-- 加載屬性文件 -->
 2                 <properties resource="db.properties">
 3                     <!--properties中可以配置一些屬性名和屬性值-->
 4                     <!--<property name="" value=""/>-->
 5                 </properties>
 6                 <dataSource type="POOLED">
 7                     <property name="driver" value="${jdbc.driver}"/>
 8                     <property name="url" value="${jdbc.url}"/>
 9                     <property name="username" value="${jdbc.username}"/>
10                     <property name="password" value="${jdbc.password}"/>
11                 </dataSource>
12                 (其中加載這個文件properties,則底下dataSource里面的參數則是property)

    2.settings(配置)

    mybatis全局配置參數,全局參數將會影響mybatis運行行為

    3.typeAliases(別名)

      需求:
      在mapper.xml中定義了很多的statement,statement需要指定參數的類型,需要resultMap指定輸出結果的映射類型
      如果在指定類型時輸入類型全路徑,不方便進行開發,可以針對parameterType或resultType指定的類型定義的一些別名,在mapper.xml通過別名定義,方便開發。

 1                <typeAliases>
 2                             <!--
 3                                 針對單個別名的定義
 4                                 type:類型的路徑
 5                                 alias:別名
 6                             -->
 7                             <typeAlias type="cn.wj.test.mybatis.pojo.User" alias="user"/>
 8                           <!--
 9                             批量定義別名(較為常用)
10                             指定包名,mybatis自動掃描包中的po類,自動定義別名,別名就是類名(首字母大小寫都可)
11                             -->
12                             <package name="cn.wj.test.mybatis.pojo"/>
13                         </typeAliases>
14                         引用別名:
15                         <select id="findUserById" parameterType="int"        resultType="user">
16                             select * from user where id = #{id}
17                         </select>

    4.typeHandlers(類型處理器)

      mybatis中通過typeHandlers完成jdbc類型和java類型的轉換。
      通常情況下,mybatis提供的類型處理器滿足日常的需要,不需要我們自定義轉換

    5.mappers(mapper的映射配置)

      1.通過resource來加載單個的映射文件
        <!--通過resource方法一次加載一個映射文件-->
        <mapper resource="mapper/UserMapper.xml"/>

      

      2.通過mapper接口加載映射文件
        <!--
          通過mapper接口加載映射文件
          遵循一些規范:需要將mapper接口類名和mapper.xml映射文件保持一致,且在一個目錄中
          上邊的規范是mapper接口加載映射文件
        -->
        <mapper class="cn.wj.test.mybatis.mapper.UserMapper"/>

      3.批量添加mapper(包名,推薦使用)

        <!--
          批量加載mapper
          指定mapper接口的包名,mybatis自動掃描包下面所有的mapper接口進行加載
          上邊的規范是mapper接口加載映射文件
        -->
        <package name="cn.wj.test.mybatis.mapper"/>

    6.輸入映射

      通過parameterType指定輸入參數的類型,類型可以是簡單類型,hashmap,poji的包裝對象

      需求:
        完成用戶信息的綜合查詢,需要傳入的查詢條件很復雜(可能包括用戶信息,其他信息,比如商品,訂單)
        針對

        UserMapper.xml

1               <!--
2                             用戶的綜合查詢
3                             #{userCustom.sex}:取出包裝類型的值
4                             ${userCustom.username}:取出pojo包裝類型對象的名稱
5                         -->
6                             <select id="findUserList"                    parameterType="cn.wj.test.mybatis.pojo.UserQueryVo" resultType="cn.wj.test.mybatis.pojo.UserCustom">
7                                 select * from user where user.sex = #{userCustom.sex} and username like '%${userCustom.username}%'
8                             </select>

        UserMapper.java

  

 1             //用戶信息的綜合查詢
 2                     public List<UserCustom> findUserList(UserQueryVo userQueryVo) throws Exception;
 3                     
 4                       測試代碼:
 5                         @Test
 6                         public void testfindUserList()throws Exception{
 7                             SqlSession sqlSession = sqlSessionFactory.openSession();
 8                             //創建UserMapper對象,mybatis自動生成mapper對象
 9                             UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
10                             //調用userMapper的方法
11                             UserCustom userCustom = new UserCustom();
12                             userCustom.setSex("m");
13                             userCustom.setUsername("123");
14                             UserQueryVo userQueryVo = new UserQueryVo();
15                             userQueryVo.setUserCustom(userCustom);
16                             List<UserCustom> userList = userMapper.findUserList(userQueryVo);
17                             System.out.println(userList);
18                         }

    7.輸出映射

      1.resultType:
        使用resultType進行輸出映射,只有查詢出來的列名和pojo中的屬性名保持一致,該列才可以映射成功。
        如果查詢出來的列名和pojo中的屬性名全部不一致,沒有創建pojo對象
        只要查詢出來的列名和pojo中的屬性有一個一致,就會創建pojo對象。
          輸出簡單類型:切記:輸出簡單類型只有一行一列的數據

      2.resultMap:
        mybatis中使用resultMap完成高級輸出結果映射
        resultMap使用方法:
        如果查詢出來的列名和pojo的屬性名不一致,通過定義一個resultMap列名和pojo屬性名做一個映射關系

        1.定義resultMap

        UserMapper.xml

 1                <!--
 2                             定義resultMap
 3                             將select id id_,username username_和User中的屬性作為一個映射關系
 4                             type:resultMap最終映射的java對象類型,可以使用別名
 5                             id:對resultMap的唯一標識
 6                         -->
 7                         <resultMap id="userResultMap" type="cn.wj.test.mybatis.pojo.User">
 8                             <!--
 9                                 id表示查詢結果集中唯一標識
10                                 column:查詢出來的列名
11                                 property:type指定的pojo類型中的屬性名
12                                 最終resultMap對column和property做一個映射關系(對應關系)
13                             -->
14                             <id column="id_" property="id"/>
15                             <!--
16                                 result:標識對於普通名的映射
17                                 column:查詢出來的列名
18                                 property:type指定的pojo類型中的屬性名
19                                 最終resultMap對column和property做一個映射關系(對應關系)
20                             -->
21                             <result column="username_" property="username"></result>
22                         </resultMap>

         2.使用resultMap作為statement的輸出映射類型(返回參數使用resultMap)

1                   <!--
2                                 使用resultMap來進行輸出的映射
3                                 resultMap:指定定義的resultMap的id,如果這個resultMap在其他mapper文件中,前邊需要加namespace
4                             -->
5                             <select id="findUserByIdResultMap" parameterType="int" resultMap="userResultMap">
6                                 select id id_,username username_ from user where id = #{id}
7                             </select>        

          userMapper.java中的接口調用
          //根據用戶信息查詢用戶列表,根據resultMap輸出
          public User findUserByIdResultMap(int id) throws Exception;

    小節:
      使用resultType進行輸出映射,只有查詢出來的列名和pojo中的屬性名一致,該列才可以映射成功。
      如果查詢出來的列名和pojo屬性名不一致,通過定義一個resultMap隊列名和pojo屬性名之間做一個映射關系。

    8.動態sql

      1.什么是動態sql:
        mybatis核心:對sql語句進行靈活的操作,通過表達式進行判斷,對sql進行靈活的拼接,組裝。
        原來的查詢語句:

1           <select id="findUserList" parameterType="cn.wj.test.mybatis.pojo.UserQueryVo" resultType="cn.wj.test.mybatis.pojo.UserCustom">
2                      select * from user where user.sex = #{userCustom.sex} and username like '%${userCustom.username}%'
3                  </select>

        現在的查詢語句
        理由:由於原來的查詢語句可能userCustom是null或者里面的參數為‘’,所以我們可以使用動態sql來進行判斷

 1                          <select id="findUserList" parameterType="cn.wj.test.mybatis.pojo.UserQueryVo" resultType="cn.wj.test.mybatis.pojo.UserCustom">
 2                             <!--
 3                                 where可以自動去掉條件中的第一個add
 4                             -->
 5                             <where>
 6                                 <if test="userCustom != null">
 7                                     <if test="userCustom.sex != null and userCustom.sex = ''">
 8                                         and user.sex = #{userCustom.sex}
 9                                     </if>
10                                     <if test="userCustom.username != null and userCustom.username = ''">
11                                         and username like '%${userCustom.username}%'
12                                     </if>
13                                 </if>
14                             </where>
15                         </select>

     9.動態sql代碼段

      將上邊實現的動態sql判斷代碼塊抽取出來,組成一個sql片段,其他的statement就可以引用sql片段

      1.定義sql片段
      <!--
        定義sql片段
        id:sql片段的唯一標識
        經驗:是基於單表來定義sql片段,這樣的話sql片段的可重用性才高
        在slq片段中不要包括where
      -->

      sql片段定義:

 1               <sql id="query_user_where">
 2                                 <if test="userCustom != null">
 3                                     <if test="userCustom.sex != null and userCustom.sex = ''">
 4                                         and user.sex = #{userCustom.sex}
 5                                     </if>
 6                                     <if test="userCustom.username != null and userCustom.username = ''">
 7                                         and username like '%${userCustom.username}%'
 8                                     </if>
 9                                 </if>
10                         </sql>
11                         sql片段引用:
12                        <select id="findUserList" parameterType="cn.wj.test.mybatis.pojo.UserQueryVo" resultType="cn.wj.test.mybatis.pojo.UserCustom">
13                             <!--select * from user where user.sex = #{userCustom.sex} and username like '%${userCustom.username}%'username-->
14                             select * from user
15                             <!--
16                                 where可以自動去掉條件中的第一個add
17                             -->
18                             <where>
19                             <!--引用sql片段的id,如果refid指定的id不在本mapper文件中,需要前邊加namespace-->
20                               <include refid="query_user_where"></include>
21                             </where>
22                         </select>

    foreach標簽

      向sql傳遞數據或List,mybatis使用foreach解析
      兩種方法:
        select * from user where (id = 1 or id =2)
        select * from user where id in (1 , 2)

      foreach的sql片段:

                <sql id="query_user_where">
                                <if test="userCustom != null">
                                    <if test="ids != null">
                                        <!--
                                            使用foreach遍歷ids
                                                collection:指定輸入對象中集合屬性
                                                item:每個遍歷生成的對象中
                                                open:開始遍歷時拼接的串
                                                close:結束遍歷時拼接的串
                                                separator:遍歷中兩個對象需要拼接的串
                                         -->
                                        <!--
                                            方法一:
                                            使用實現下邊的sql拼接:
                                            AND (id = 1 OF id = 10)
                                        -->
                                        <foreach collection="ids" item="item_id" open="and (" close=")" separator="or">
                                          <!--每個遍歷需要拼接的串-->
                                            id = #{item_id}
                                        </foreach>
                                        
                                        或者我們也可以才去這種方法
                                        <!--
                                            方法二:
                                            使用實現下邊的sql拼接:
                                            And id  in (1,10)
                                        -->
                                        <foreach collection="ids" item="item_id" open="and id in (" close=")" separator=",">
                                            <!--每個遍歷需要拼接的串-->
                                            #{item_id}
                                        </foreach>
                                    </if>
                                </if>
                            </sql>
                            UserMapper.xml的sql片段的調用
                             <select id="selectUserByForeach" parameterType="cn.wj.test.mybatis.pojo.UserQueryVo" resultType="cn.wj.test.mybatis.pojo.User">
                                select * from user
                                <where>
                                    <include refid="query_user_foreach"/>
                                </where>
                            </select>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM