<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      【精選必看】MyBatis映射文件及動態SQL,一級,二級緩存介紹

      MyBatis映射文件

      在這里插入圖片描述

      < r e s u l t M a p > <resultMap> <resultMap>

      MyBatis映射文件中除了<insert><delete><update><select>外,還有一些標簽可以使用:

      resultMap

      標簽的作用的自定義映射關系。

      MyBatis可以將數據庫結果集封裝到對象中,是因為結果集的列名和對象屬性名相同:

      當POJO屬性名和數據庫列名不一致時,MyBatis無法自動完成映射關系。

      此時有兩種解決方案:

      1. Sql語句的查詢字段起與POJO屬性相同的別名。

        <select id="findAll" resultType="com.mybatis.pojo.Teacher">
           select tid as id,tname as teacherName from teacher;
        </select>
        
      2. 自定義映射關系

        • 在映射文件中,使用<resultMap>自定義映射關系:
        <!-- id:自定義映射名 type:自定義映射的對象類型  -->
        <resultMap id="teacherMapper" type="com.mybatis.pojo.Teacher">
          <!-- id定義主鍵列  property:POJO屬性名 column:數據庫列名  -->
          <id property="id" column="tid"></id>
          <!-- result定義普通列  property:POJO屬性名 column:數據庫列名  -->
          <result property="teacherName" column="tname"></result>
        </resultMap>
        
        • <select>標簽中,使用resultMap屬性代替resultType屬性,使用自定義映射關系。
        <select id="findAll" resultMap="teacherMapper">
           select * from teacher
        </select>
        

      < sql>&< include>

      <sql>用來定義可重用的Sql片段,通過<include>引入該片段。如:Sql語句的查詢字段起與POJO屬性相同的別名,該Sql片段就可以重用。

      <sql id="selectAllField">
         select tid as id,tname as teacherName
      </sql>
      
      
      <select id="findAll" resultType="com.mybatis.pojo.Teacher">
        <include refid="selectAllField"></include>
         from teacher;
      </select>
      
      
      <select id="findById" resultType="com.mybatis.pojo.Teacher">
        <include refid="selectAllField"></include>
         from teacher where tid = #{id}
      </select>
      
      

      特殊字符處理

      在Mybatis映射文件中盡量不要使用一些特殊字符,如:<>等。

      我們可以使用符號的實體來表示:(帶后面的分號)

      符號實體
      <& lt;
      >& gt;
      && amp;
      & apos;
      & quot;

      如:

      <select id="findById2" resultType="com.mybatis.pojo.Teacher">
        <include refid="selectAllField"></include>
         from teacher where tid &gt; #{id}
      </select>
      

      動態SQL

      在這里插入圖片描述

      一個查詢的方法的Sql語句不一定是固定的。比如電商網站的查詢商品,用戶使用不同條件查詢,Sql語句就會添加不同的查詢條件。此時就需要在方法中使用動態Sql語句。

      < i f > < if> <if>

      <if>標簽內的Sql片段在滿足條件后才會添加,用法為:<if test="條件">。例如:根據不同條件查詢用戶:

      1. 持久層接口添加方法

        // 用戶通用查詢
        List<User> findByCondition(User user);
        
      2. 映射文件添加標簽

        <select id="findByCondition" parameterType="com.mybatis.pojo.User" resultType="com.mybatis.pojo.User">
           select * from user where 1 = 1
          <if test="username != null and username.length() != 0">
             and username like #{username}
          </if>
          <if test="sex != null and sex.length() != 0">
             and sex = #{sex}
          </if>
          <if test="address != null and address.length() != 0">
             and address = #{address}
          </if>
        </select>
        
      3. 編寫測試方法

        @Test
        public void testFindByCondition(){
          User user = new User();
          List<User> users1 = userMapper2.findByCondition(user);
          //users1.forEach(System.out::println);
        
        
          user.setUsername("%張三%");
          List<User> users2 = userMapper2.findByCondition(user);
          users2.forEach(System.out::println);
        
        
          user.setAddress("北京");
          List<User> users3 = userMapper2.findByCondition(user);
          users3.forEach(System.out::println);
        }
        
      1. if中的條件不能使用&&/||,而應該使用and/or

      2. if中的條件可以直接通過屬性名獲取參數POJO的屬性值,并且該值可以調用方法。

      3. where后為什么要加1=1?

        任意條件都可能拼接到Sql中。如果有多個條件,從第二個條件開始前都需要加And關鍵字。加上1=1這個永久成立的條件,就不需要考慮后面的條件哪個是第一個條件,后面的條件前都加And關鍵字即可。

      < w h e r e > <where> <where>

      <where>可以代替sql中的where 1=1 和第一個and,更符合程序員的開發習慣,使用<where>后的映射文件如下:

      <select id="findByCondition" resultType="com.mybatis.user.User" parameterType="com.mybatis.user.User">
         select * from user
        <where>
          <if test="username != null and username.length() != 0">
             username like #{username}
          </if>
          <if test="sex != null and sex.length() != 0">
             and sex = #{sex}
          </if>
        </where>
      </select>
      
      

      < s e t > <set> <set>

      <set>標簽用在update語句中。借助<if>,可以只對有具體值的字段進行更新。<set>會自動添加set關鍵字,并去掉最后一個if語句中多余的逗號。

      <update id="update" parameterType="com.mybatis.user.User">
         update user
        <set>
          <if test="username != null and username.length() > 0">
             username = #{username},
          </if>
          <if test="sex != null and sex.length() > 0">
             sex = #{sex},
          </if>
        </set>
        <where>
           id = #{id}
        </where>
      </update>
      
      

      < c h o o s e > < choose> <choose> < w h e n > < when> <when> < o t h e r w i s e > < otherwise> <otherwise>

      這些標簽表示多條件分支,類似JAVA中的switch...case<choose>類似switch<when>類似case<otherwise>類似default,用法如下:

      <select id="findByCondition" resultType="com.mybatis.user.User" parameterType="com.mybatis.user.User">
         select * from user
        <where>
          <choose>
            <when test="username.length() &lt; 5">
               username like #{username}
            </when>
            <when test="username.length() &lt; 10">
               username = #{username}
            </when>
            <otherwise>
               id = 1
            </otherwise>
          </choose>
        </where>
      </select>
      
      

      這段代碼的含義為:用戶名<5時使用模糊查詢,用戶名>=5并且<10時使用精確查詢,否則查詢id為1的用戶

      < f o r e a c h > <foreach> <foreach>

      <foreach>類似JAVA中的for循環,可以遍歷集合或數組。<foreach>有如下屬性:

      • collection:遍歷的對象類型
      • open:開始的sql語句
      • close:結束的sql語句
      • separator:遍歷每項間的分隔符
      • item:表示本次遍歷獲取的元素,遍歷List、Set、數組時表示每項元素,遍歷map時表示鍵值對的值。
      • index:遍歷List、數組時表示遍歷的索引,遍歷map時表示鍵值對的鍵。
      遍歷數組

      我們使用<foreach>遍歷數組進行批量刪除。

      1. 持久層接口添加方法

        void deleteBatch(int[] ids);
        
      2. 映射文件添加標簽

        <delete id="deleteBatch" parameterType="int">
           delete from user
          <where>
            <foreach open="id in(" close=")" separator="," collection="array" item="id" >
               #{id}
            </foreach>
          </where>
        </delete>
        
      3. 編寫測試方法

        @Test
        public void testDeleteBatch(){
          int[] ids = {9,11};
          userMapper.deleteBatch(ids);
          session.commit();
        }
        
      遍歷Collection

      <foreach>遍歷List和Set的方法是一樣的,我們使用<foreach>遍歷List進行批量添加。

      1. 持久層接口添加方法

        void insertBatch(List<User> users);
        
      2. 映射文件添加標簽

        <insert id="insertBatch" parameterType="com.mybatis.user.User">
           insert into user values
          <foreach collection="list" item="user" separator=",">
             (null ,#{user.username},#{user.sex},#{user.address})
          </foreach>
        </insert>
        
      3. 編寫測試方法

        @Test
        public void testInsertBatch(){
          User user1 = new User("程序員1", "男", "北京");
          User user2 = new User("程序員2", "女", "上海");
          List<User> users = new ArrayList();
          users.add(user1);
          users.add(user2);
        
        
          userMapper2.insertBatch(users);
          session.commit();
        }
        
      遍歷Map

      我們使用<foreach>遍歷Map進行多條件查詢。

      1. 持久層接口添加方法

        /**
           * 多條件查詢
           * @param map 查詢的條件鍵值對 鍵:屬性名 值:屬性值
           * @return
           */
        List<User> findUser(@Param("queryMap") Map<String,Object> map);
        
      2. 映射文件添加標簽

        <select id="findUser" parameterType="map" resultType="com.mybatis.pojo.User">
           select * from user
          <where>
            <foreach collection="queryMap" separator="and" index="key" item="value">
               ${key} = #{value}
            </foreach>
          </where>
        </select>
        
      3. 編寫測試方法

        @Test
        public void testFindUser(){
          Map<String,Object> queryMap = new HashMap();
          queryMap.put("sex","男");
          queryMap.put("address","北京");
          List<User> users = userMapper2.findUser(queryMap);
          users.forEach(System.out::println);
        }
        

      MyBatis緩存

      在這里插入圖片描述

      緩存介紹

      緩存是內存當中一塊存儲數據的區域,目的是提高查詢效率。MyBatis會將查詢結果存儲在緩存當中,當下次執行相同的SQL時不訪問數據庫,而是直接從緩存中獲取結果,從而減少服務器的壓力。

      • 什么是緩存?

        存在于內存中的一塊數據。

      • 緩存有什么作用?

        減少程序和數據庫的交互,提高查詢效率,降低服務器和數據庫的壓力。

      • 什么樣的數據使用緩存?

        經常查詢但不常改變的,改變后對結果影響不大的數據。

      • MyBatis緩存分為哪幾類?

        一級緩存和二級緩存

      • 如何判斷兩次Sql是相同的?

        1. 查詢的Sql語句相同
        2. 傳遞的參數值相同
        3. 對結果集的要求相同
        4. 預編譯的模板Id相同

      MyBatis一級緩存

      • MyBatis一級緩存也叫本地緩存。SqlSession對象中包含一個Executor對象,Executor對象中包含一個PerpetualCache對象,在該對象存放一級緩存數據。
      • 由于一級緩存是在SqlSession對象中,所以只有使用同一個SqlSession對象操作數據庫時才能共享一級緩存
      • MyBatis的一級緩存是默認開啟的,不需要任何的配置。
      測試一級緩存
      @Test
      public void testCache1() throws IOException {
        InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(is);
        SqlSession session = factory.openSession();
      
      
        // 使用同一個SqlSession查詢
        UserMapper mapper1 = session.getMapper(UserMapper.class);
        UserMapper mapper2 = session.getMapper(UserMapper.class);
      
      
        User user1 = mapper1.findById(1);
        System.out.println(user1.hashCode());
        System.out.println("-------------------------------------------");
        User user2 = mapper2.findById(1);
        System.out.println(user2.hashCode());
      }
      
      
      @Test
      public void testCache2() throws IOException {
        InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(is);
        SqlSession session1 = factory.openSession();
        SqlSession session2 = factory.openSession();
      
      
        // 使用不同的SqlSession查詢
        UserMapper mapper1 = session1.getMapper(UserMapper.class);
        UserMapper mapper2 = session2.getMapper(UserMapper.class);
      
      
        User user1 = mapper1.findById(1);
        System.out.println(user1.hashCode());
        System.out.println("-------------------------------------------");
        User user2 = mapper2.findById(1);
        System.out.println(user2.hashCode());
      }
      
      

      MyBatis清空一級緩存

      進行以下操作可以清空MyBatis一級緩存:

      1. SqlSession調用close():操作后SqlSession對象不可用,該對象的緩存數據也不可用。
      2. SqlSession調用clearCache()/commit():操作會清空一級緩存數據。
      3. SqlSession調用增刪改方法:操作會清空一級緩存數據,因為增刪改后數據庫發生改變,緩存數據將不準確。
      @Test
      public void testCache3() throws IOException {
        InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(is);
        SqlSession session = factory.openSession();
      
      
        UserMapper mapper1 = session.getMapper(UserMapper.class);
        UserMapper mapper2 = session.getMapper(UserMapper.class);
      
      
        User user1 = mapper1.findById(1);
        System.out.println(user1.hashCode());
        //     session.close();
        //     session.clearCache();
        //     session.commit();
        mapper1.delete(2);
        System.out.println("-------------------------------------------");
        User user2 = mapper2.findById(1);
        System.out.println(user2.hashCode());
      }
      
      

      MyBatis二級緩存

      • MyBatis二級緩存也叫全局緩存。數據存放在SqlSessionFactory中,只要是同一個工廠對象創建的SqlSession,在進行查詢時都能共享數據。一般在項目中只有一個SqlSessionFactory對象,所以二級緩存的數據是全項目共享的。

      • MyBatis一級緩存存放的是對象,二級緩存存放的是對象的數據。所以要求二級緩存存放的POJO必須是可序列化的,也就是要實現Serializable接口。

      • MyBatis二級緩存默認不開啟,手動開啟后數據先存放在一級緩存中,只有一級緩存數據清空后,數據才會存到二級緩存中。

        SqlSession調用clearCache()無法將數據存到二級緩存中。

      開啟二級緩存
      1. POJO類實現Serializable接口。

        public class User implements Serializable {
          private int id;
          private String username;
          private String sex;
          private String address;
        }
        
        
      2. 在MyBatis配置文件添加如下設置:

        <settings>
          <setting name="cacheEnabled" value="true"/>
        </settings>
        
        

        由于cacheEnabled默認值是true,所以該設置可以省略。

      3. 在映射文件添加<cache />標簽,該映射文件下的所有方法都支持二級緩存。

        如果查詢到的集合中對象過多,二級緩存只能緩存1024個對象引用。可以通過<cache />標簽的size屬性修改該數量。

        <cache size="2048"/>
        
      4. 測試二級緩存

        @Test
        public void testCache4() throws IOException {
          InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
          SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
          SqlSessionFactory factory = builder.build(is);
          SqlSession session1 = factory.openSession();
          SqlSession session2 = factory.openSession();
        
        
          UserMapper mapper1 = session1.getMapper(UserMapper.class);
          UserMapper mapper2 = session2.getMapper(UserMapper.class);
        
        
          User user1 = mapper1.findById(1);
          System.out.println(user1);
          System.out.println(user1.hashCode());
          // 讓一級緩存失效
          session1.commit();
          System.out.println("-------------------------------------------");
        
        
          User user2 = mapper2.findById(1);
          System.out.println(user2);
          System.out.println(user2.hashCode());
        }
        
        
      posted @ 2023-11-26 12:42  Gjq-  閱讀(57)  評論(0)    收藏  舉報  來源
      主站蜘蛛池模板: 成人3D动漫一区二区三区| 无码伊人久久大杳蕉中文无码| 99热国产这里只有精品9| 18禁无遮挡啪啪无码网站| 久久久久亚洲AV成人片一区| 亚洲av第三区国产精品| 亚洲国产精品一区二区久久| 中文字幕人妻丝袜美腿乱| 亚洲人成色77777| 亚洲国产精品一区第二页| 中文日产幕无线码一区中文| 国产好大好硬好爽免费不卡| 亚洲精品成人区在线观看| 欧美人与动牲交A免费观看| 国产一区二区亚洲一区二区三区| 五月婷婷激情第四季| 欧洲熟妇色自偷自拍另类| 亚洲欧美自偷自拍视频图片| 免费国产午夜理论片不卡| 精品偷拍一区二区三区| 麻豆国产成人AV在线播放| 亚洲无人区码二码三码区| 涡阳县| 免费日韩av网在线观看| 天堂亚洲免费视频| 欧美s码亚洲码精品m码| 国产在线拍揄自揄拍无码| 国产欧美精品一区二区三区| 久久精品夜夜夜夜夜久久| av中文字幕在线二区| 国产精品三级爽片免费看| 国产精品一码二码三码| 精品999日本久久久影院| 亚洲日韩国产一区二区三区在线| 黑巨人与欧美精品一区| 国产黄色带三级在线观看| 男人又大又硬又粗视频| 69精品丰满人妻无码视频a片| 护士张开腿被奷日出白浆| 亚洲一区二区三区黄色片| 人人澡人人透人人爽|