1. 程式人生 > >MyBatis相關記錄

MyBatis相關記錄

mybatis 專案初始化

  1. maven依賴

    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.4.6</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.13</version>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.2.3</version>
    </dependency>
  2. Mybatis 全域性配置檔案

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configuration
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
    
        <environments default="development">
            <environment id="development">
                <transactionManager type="JDBC"/>
                <dataSource type="POOLED">
                    <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                    <property name="url" value="jdbc:mysql://192.168.31.136:3306/mybatis"/>
                    <property name="username" value="root"/>
                    <property name="password" value="123456"/>
                </dataSource>
            </environment>
        </environments>
        <mappers>
            <mapper resource="UserMapper.xml"/>
        </mappers>
    </configuration>
  3. 建立實體類和Mapper配置檔案

    public class User {
        private Long id;
        private String name;
        private Integer age;
    }
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.godfunc.UserMapper">
        <select id="selectUser" resultType="com.godfunc.User">
        select * from user where id = #{id}
      </select>
    </mapper>
  4. 測試

    @Test
        public void func1() throws IOException {
            String resource = "mybatis-config.xml";
            InputStream resourceAsStream = Resources.getResourceAsStream(resource);
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
            SqlSession sqlSession = sqlSessionFactory.openSession();
            User user = sqlSession.selectOne("com.godfunc.UserMapper.selectUser", 1L);
            log.error("result: {}", user);
        }
    sqlSession.close();

介面式程式設計

  1. 建立 UserMapper.java

    public interface UserMapper {
        User selectUser(Long id);
    }
  2. UserMapper.xmlnamespace 改為 UserMapper.java 的全類名。

  3. 測試

    @Test
        public void func2() throws IOException {
            String resource = "mybatis-config.xml";
            InputStream resourceAsStream = Resources.getResourceAsStream(resource);
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
            SqlSession sqlSession = sqlSessionFactory.openSession();
            UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
            User user = userMapper.selectUser(1L);
            log.error("type {}", userMapper.getClass());
            log.error("result: {}", user);
            sqlSession.close();
        }

    此時我們看到控制檯將 userMapper 的 type 打印出來了:

    [main] ERROR com.godfunc.Demo1 - type class com.sun.proxy.$Proxy5

    在這裡我們可以看到,myBatisuserMapper 建立了一個代理物件(也就是 UserMapper 的實現類 ),此時我們就知道了,Mybatis 的介面式程式設計,其實最終還是為介面建立了實現類,然後呼叫實現方法,對資料庫進行操作。

  4. INSERT 返回主鍵

    • UserMapper.java 中加上 insert

      void insert(User user);
    • UserMapper.xml 中配置 sql

      <insert id="insert" parameterType="com.godfunc.User" useGeneratedKeys="true" keyProperty="id">
              INSERT INTO user(name, age) values(#{name}, #{age})
      </insert>

      note: 如果引數是一個物件,我們是可以直接通過屬性名就行取值的。

Mybatis 多引數

多個引數,Mybatis 會做特殊處理,會將多個引數封裝到一個 map 中。map 的 key 是從 param1...paramn

  1. 介面方法和 sql 配置

    <update id="update">
            update user set name = #{param1}, age = #{param2} where id = #{param3}
    </update>
    void update(String name, Integer age, Long id);

    這樣,我們可以通過取出 map 中的多個引數,進行資料的更新。

    note: 如果引數是 List 獲取 Array , 裝到 map 中 key 的名字是 listarray

Mybatis 引數封裝

  1. update 為例(這裡用的是@Param註解)

    void update(@Param("name") String name, @Param("age") Integer age, @Param("id") Long id);
  2. 在執行update 方法時,會進入 org.apache.ibatis.binding.MapperProxy類中,執行 invoke 方法,從類的命名上我們可以清楚的知道, MapperProxy 是Mapper的動態代理類

查詢返回 Map

  1. 介面和配置檔案如下

    @MapKey("id")
    Map<Long, User> selectResultMap();
    <select id="selectResultMap" resultType="com.godfunc.User">
        select * from user
    </select>

    11:23:24.543 [main] ERROR com.godfunc.Demo1 - result {1=User{id=1, name='里斯', age=2}, 3=User{id=3, name='天全', age=3}, 8=User{id=8, name='王大山', age=34}, 9=User{id=9, name='天全11', age=3}}

    Mapper 配置檔案中返回值型別依舊是 User,在介面方法宣告上使用 @MapKey("id") 將 返回結果中的 id 作為 Mapkey.

級聯查詢

  1. 介面和配置檔案如下

    public class User {
        private Long id;
        private String name;
        private Integer age;
        private Job job;
    }
   User selectUserWithJob(Long id);
   <resultMap id="userMap" type="com.godfunc.User">
       <result column="id" property="id"/>
       <result column="name" property="name"/>
       <result column="age" property="age"/>
       <result column="job_id" property="job.id"/>
       <result column="job_name" property="job.name"/>
       <result column="u_id" property="job.uid"/>
   </resultMap>
   <select id="selectUserWithJob" resultMap="userMap">
       select u.*, b.id job_id, b.name job_name, b.u_id  from user u left join job b on b.u_id = u.id where u.id = #{id}
   </select>

這裡是一個對一關聯,也可以使用 association 標籤做,但是這裡直接使用了 . 的方式。

子查詢

  1. 當我們進行子查詢,想要傳遞多個引數時,可以這樣做 column="{key1=column1,key2=column2}"*

  2. fetchType="eager|lazy" 設定子查詢立即載入|懶載入

  3. bind 將一個表示式的值繫結到一個變數中(可以用來做模糊查詢的% 拼接)

    <select id="selectByUserName" resultType="com.godfunc.User">
        <bind name="_name" value="'%'+name+'%'"/>
        select * from user where name like #{_name}
    </select>

    Note: 如果只有一個引數,也要加 @Param 註解,不然會報錯

快取

  1. 一級快取 預設是開啟的
  2. 二級快取
    1. 快取的回收策略(eviction):
      • LRU - 最近最少使用的 :移除最長時間不被使用的物件。
      • FIFO - 先進先出:按物件進入快取的順序來移除他們。
      • SOFT - 軟引用:移除基於垃圾回收器狀態和軟引用規則的物件。
      • WEAK - 弱引用:更積極地移除基於垃圾收集器狀態和弱引用規則的物件。
    2. 快取重新整理間隔(flushInterval):快取多久時間清空一次,預設不清空,設定一個毫秒值。
    3. 是否只讀(readOnly)