MyBatis原理系列(一)-手把手帶你閱讀MyBatis源碼

MyBatis原理系列(一)-手把手帶你閱讀MyBatis源碼
MyBatis原理系列(二)-手把手帶你了解MyBatis的啟動流程
MyBatis原理系列(三)-手把手帶你了解SqlSession,SqlSessionFactory,SqlSessionFactoryBuilder的關(guān)系
MyBatis原理系列(四)-手把手帶你了解MyBatis的Executor執(zhí)行器
MyBatis原理系列(五)-手把手帶你了解Statement、StatementHandler、MappedStatement間的關(guān)系
MyBatis原理系列(六)-手把手帶你了解BoundSql的創(chuàng)建過程
MyBatis原理系列(七)-手把手帶你了解如何自定義插件
MyBatis原理系列(八)-手把手帶你了解一級緩存和二級緩存
MyBatis原理系列(九)-手把手帶你了解MyBatis事務(wù)管理機制

作為Java碼農(nóng),無論在面試中,還是在工作中都會遇到MyBatis的相關(guān)問題。筆者從大學開始就接觸MyBatis,到現(xiàn)在為止都是會用,知道怎么配置,怎么編寫xml,但是不知道Mybatis核心原理,一遇到問題就復(fù)制錯誤信息百度解決。為了改變這種境地,鼓起勇氣開始下定決心閱讀MyBatis源碼,并開始記錄閱讀過程,希望和大家分享。

1. 初識MyBatis

還記得當初接觸MyBatis時,覺得要配置很多,而且sql要單獨寫在xml中,相比Hibernate來說簡直不太友好,直到后來出現(xiàn)了復(fù)雜的業(yè)務(wù)需求,需要編寫相應(yīng)的復(fù)雜的sql,此時用Hibernate反而更加麻煩了,用MyBatis是真香了。因此筆者對MyBatis的第一印象就是將業(yè)務(wù)關(guān)注的sql和java代碼進行了解耦,在業(yè)務(wù)復(fù)雜變化的時候,相應(yīng)的數(shù)據(jù)庫操作需要相應(yīng)進行修改,如果通過java代碼構(gòu)建操作數(shù)據(jù)邏輯,這不斷變動的需求對程序員的耐心是極大的考驗。如果將sql統(tǒng)一的維護在一個文件里,java代碼用接口定義,在需求變動時,只用改相應(yīng)的sql,從而減少了修改量,提高開發(fā)效率。以上也是經(jīng)常在面試中經(jīng)常問到的Hibernate和MyBatis間的區(qū)別一點。

切到正題,Mybatis是什么呢?

Mybatis SQL 映射框架使得一個面向?qū)ο髽?gòu)建的應(yīng)用程序去訪問一個關(guān)系型數(shù)據(jù)庫變得更容易。MyBatis使用XML描述符或注解將對象與存儲過程或SQL語句耦合。與對象關(guān)系映射工具相比,簡單性是MyBatis數(shù)據(jù)映射器的最大優(yōu)勢。

以上是Mybatis的官方解釋,其中“映射”,“面向?qū)ο蟆?,“關(guān)系型”,“xml”等等都是Mybatis的關(guān)鍵詞,也是我們了解了Mybatis原理后,會恍然大悟的地方。筆者現(xiàn)在不詳述這些概念,在最后總結(jié)的時候再進行詳述。我們只要知道Mybatis為我們操作數(shù)據(jù)庫提供了很大的便捷。

2. 源碼下載

我們首先要從github上下載源碼,倉庫地址,然后在IDEA中clone代碼

倉庫

在打開中的IDEA中,選擇vsc -> get from version control -> 復(fù)制剛才的地址


image.png

點擊clone即可


image.png

經(jīng)過漫長的等待后,代碼會全部下載下來,項目結(jié)果如下,框起來的就是我們要關(guān)注的核心代碼了。

image.png

每個包就是MyBatis的一個模塊,每個包的作用如下:

image.png

3. 一個簡單的栗子

不知道現(xiàn)在還有沒有同學知道怎么使用原生的JDBC進行數(shù)據(jù)庫操作,現(xiàn)在框架太方便了,為我們考慮了很多,也隱藏了很多細節(jié),因此會讓我們處于一個云里霧里的境地,為什么這么設(shè)計,這樣設(shè)計解決了什么問題,我們是不得而知的,為了了解其中奧秘,還是需要我們從頭開始了解。

接下來筆者將以兩個栗子來分別講講如何用原生的JDBC操作數(shù)據(jù)庫,以及如何使用MyBatis框架來實現(xiàn)相同的功能,并比較兩者的區(qū)別。

3.1 創(chuàng)建表

在此我們建了兩張表,一張是t_test_user用戶信息主表,一張是t_test_user_info用戶信息副表,兩張表通過member_id進行關(guān)聯(lián)。

DROP TABLE IF EXISTS `t_test_user`;
CREATE TABLE `t_test_user` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `member_id` bigint(20) NOT NULL COMMENT '會員id',
  `real_name` varchar(255) CHARACTER SET utf8 DEFAULT NULL COMMENT '真實姓名',
  `nickname` varchar(255) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '會員昵稱',
  `date_create` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '創(chuàng)建時間',
  `date_update` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時間',
  `deleted` bigint(20) DEFAULT '0' COMMENT '刪除標識,0未刪除,時間戳-刪除時間',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=42013 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='測試表';

DROP TABLE IF EXISTS `t_test_user_info`;
CREATE TABLE `t_test_user_info` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id',
  `member_id` bigint(20) NOT NULL COMMENT '會員id',
  `member_phone` varchar(50) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '電話',
  `member_province` varchar(50) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '省',
  `member_city` varchar(50) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '市',
  `member_county` varchar(50) CHARACTER SET utf8mb4 DEFAULT NULL COMMENT '區(qū)',
  `date_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '創(chuàng)建時間',
  `date_update` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時間',
  `deleted` bigint(20) NOT NULL DEFAULT '0' COMMENT '刪除標識,0未刪除,時間戳-刪除時間',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='用戶信息測試表';

3.2 使用Java JDBC進行操作數(shù)據(jù)庫

JDBC(Java Database Connectivity,簡稱JDBC)是Java中用來規(guī)范客戶端程序如何來訪問數(shù)據(jù)庫的應(yīng)用程序接口,提供了諸如查詢和更新數(shù)據(jù)庫中數(shù)據(jù)的方法。使用JDBC操作數(shù)據(jù)庫,一般包含7步,代碼如下。

public class JDBCTest {

    /**
     * 數(shù)據(jù)庫地址 替換成本地的地址
     */
    private static final String url = "jdbc:mysql://localhost:3306/test?useUnicode=true";
    /**
     * 數(shù)據(jù)庫用戶名
     */
    private static final String username = "test";
    /**
     * 密碼
     */
    private static final String password = "test";

    public static void main(String[] args) {
        try {
            // 1. 加載數(shù)據(jù)庫驅(qū)動
            Class.forName("com.mysql.jdbc.Driver");
            // 2. 獲得連接
            Connection connection = DriverManager.getConnection(url, username, password);
            // 3. 創(chuàng)建sql語句
            String sql = "select * from t_test_user";
            Statement statement = connection.createStatement();
            // 4. 執(zhí)行sql
            ResultSet result = statement.executeQuery(sql);
            // 5. 處理結(jié)果
            while(result.next()){
                System.out.println("result = " + result.getString(1));
            }
            // 6. 關(guān)閉連接
            result.close();
            connection.close();
        } catch (Exception e){
            System.out.println(e);
        }

    }
}

3.3 使用Mybatis進行操作數(shù)據(jù)庫

3.3.1 新增mybatis-config.xml配置

在路徑src/main/resources/mybatis-config.xml新增配置,配置內(nèi)容如下

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

    <!--一些重要的全局配置-->
    <settings>
        <setting name="cacheEnabled" value="true"/>
        <!--<setting name="lazyLoadingEnabled" value="true"/>-->
        <!--<setting name="multipleResultSetsEnabled" value="true"/>-->
        <!--<setting name="useColumnLabel" value="true"/>-->
        <!--<setting name="useGeneratedKeys" value="false"/>-->
        <!--<setting name="autoMappingBehavior" value="PARTIAL"/>-->
        <!--<setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>-->
        <!--<setting name="defaultExecutorType" value="SIMPLE"/>-->
        <!--<setting name="defaultStatementTimeout" value="25"/>-->
        <!--<setting name="defaultFetchSize" value="100"/>-->
        <!--<setting name="safeRowBoundsEnabled" value="false"/>-->
        <!--<setting name="mapUnderscoreToCamelCase" value="false"/>-->
        <!--<setting name="localCacheScope" value="STATEMENT"/>-->
        <!--<setting name="jdbcTypeForNull" value="OTHER"/>-->
        <!--<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>-->
        <!--<setting name="logImpl" value="STDOUT_LOGGING" />-->
    </settings>

    <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://localhost:3306/test?useUnicode=true"/>
                <property name="username" value="test"/>
                <property name="password" value="test"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <!--這邊可以使用package和resource兩種方式加載mapper-->
        <!--<package name="包名"/>-->
        <package name="com.example.demo.dao"/> -->
        <mapper resource="./mapper/TTestUserMapper.xml"/>
    </mappers>

</configuration>
3.3.2 新增mapper接口

新增src/main/java/com/example/demo/dao/TTestUserMapper.java 接口

package com.example.demo.dao;

import com.example.demo.entity.TTestUser;
import org.apache.ibatis.annotations.Mapper;

import java.util.List;

@Mapper
public interface TTestUserMapper {
    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table t_test_user
     *
     * @mbggenerated
     */
    int deleteByPrimaryKey(Long id);

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table t_test_user
     *
     * @mbggenerated
     */
    int insert(TTestUser record);

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table t_test_user
     *
     * @mbggenerated
     */
    int insertSelective(TTestUser record);

    int batchInsert(List<TTestUser> records);

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table t_test_user
     *
     * @mbggenerated
     */
    TTestUser selectByPrimaryKey(Long id);

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table t_test_user
     *
     * @mbggenerated
     */
    int updateByPrimaryKeySelective(TTestUser record);

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table t_test_user
     *
     * @mbggenerated
     */
    int updateByPrimaryKey(TTestUser record);
}
3.3.3 新增映射配置文件

src/main/resources/mapper/TTestUserMapper.xml 新增映射配置文件

<?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.example.demo.dao.TTestUserMapper">
  <resultMap id="BaseResultMap" type="com.example.demo.entity.TTestUser">
    <!--
      WARNING - @mbggenerated
      This element is automatically generated by MyBatis Generator, do not modify.
    -->
    <id column="id" jdbcType="BIGINT" property="id" />
    <result column="member_id" jdbcType="BIGINT" property="memberId" />
    <result column="real_name" jdbcType="VARCHAR" property="realName" />
    <result column="nickname" jdbcType="VARCHAR" property="nickname" />
    <result column="date_create" jdbcType="TIMESTAMP" property="dateCreate" />
    <result column="date_update" jdbcType="TIMESTAMP" property="dateUpdate" />
    <result column="deleted" jdbcType="BIGINT" property="deleted" />
  </resultMap>
  <sql id="Base_Column_List">
    <!--
      WARNING - @mbggenerated
      This element is automatically generated by MyBatis Generator, do not modify.
    -->
    id, member_id, real_name, nickname, date_create, date_update, deleted
  </sql>
  <select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
    <!--
      WARNING - @mbggenerated
      This element is automatically generated by MyBatis Generator, do not modify.
    -->
    select 
    <include refid="Base_Column_List" />
    from t_test_user
    where id = #{id,jdbcType=BIGINT}
  </select>
  <delete id="deleteByPrimaryKey" parameterType="java.lang.Long">
    <!--
      WARNING - @mbggenerated
      This element is automatically generated by MyBatis Generator, do not modify.
    -->
    delete from t_test_user
    where id = #{id,jdbcType=BIGINT}
  </delete>
  <insert id="insert" parameterType="com.example.demo.entity.TTestUser">
    <!--
      WARNING - @mbggenerated
      This element is automatically generated by MyBatis Generator, do not modify.
    -->
    insert into t_test_user (id, member_id, real_name, 
      nickname, date_create, date_update, 
      deleted)
    values (#{id,jdbcType=BIGINT}, #{memberId,jdbcType=BIGINT}, #{realName,jdbcType=VARCHAR}, 
      #{nickname,jdbcType=VARCHAR}, #{dateCreate,jdbcType=TIMESTAMP}, #{dateUpdate,jdbcType=TIMESTAMP}, 
      #{deleted,jdbcType=BIGINT})
  </insert>
  <insert id="insertSelective" parameterType="com.example.demo.entity.TTestUser">
    <!--
      WARNING - @mbggenerated
      This element is automatically generated by MyBatis Generator, do not modify.
    -->
    insert into t_test_user
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="id != null">
        id,
      </if>
      <if test="memberId != null">
        member_id,
      </if>
      <if test="realName != null">
        real_name,
      </if>
      <if test="nickname != null">
        nickname,
      </if>
      <if test="dateCreate != null">
        date_create,
      </if>
      <if test="dateUpdate != null">
        date_update,
      </if>
      <if test="deleted != null">
        deleted,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides=",">
      <if test="id != null">
        #{id,jdbcType=BIGINT},
      </if>
      <if test="memberId != null">
        #{memberId,jdbcType=BIGINT},
      </if>
      <if test="realName != null">
        #{realName,jdbcType=VARCHAR},
      </if>
      <if test="nickname != null">
        #{nickname,jdbcType=VARCHAR},
      </if>
      <if test="dateCreate != null">
        #{dateCreate,jdbcType=TIMESTAMP},
      </if>
      <if test="dateUpdate != null">
        #{dateUpdate,jdbcType=TIMESTAMP},
      </if>
      <if test="deleted != null">
        #{deleted,jdbcType=BIGINT},
      </if>
    </trim>
  </insert>
  <update id="updateByPrimaryKeySelective" parameterType="com.example.demo.entity.TTestUser">
    <!--
      WARNING - @mbggenerated
      This element is automatically generated by MyBatis Generator, do not modify.
    -->
    update t_test_user
    <set>
      <if test="memberId != null">
        member_id = #{memberId,jdbcType=BIGINT},
      </if>
      <if test="realName != null">
        real_name = #{realName,jdbcType=VARCHAR},
      </if>
      <if test="nickname != null">
        nickname = #{nickname,jdbcType=VARCHAR},
      </if>
      <if test="dateCreate != null">
        date_create = #{dateCreate,jdbcType=TIMESTAMP},
      </if>
      <if test="dateUpdate != null">
        date_update = #{dateUpdate,jdbcType=TIMESTAMP},
      </if>
      <if test="deleted != null">
        deleted = #{deleted,jdbcType=BIGINT},
      </if>
    </set>
    where id = #{id,jdbcType=BIGINT}
  </update>
  <update id="updateByPrimaryKey" parameterType="com.example.demo.entity.TTestUser">
    <!--
      WARNING - @mbggenerated
      This element is automatically generated by MyBatis Generator, do not modify.
    -->
    update t_test_user
    set member_id = #{memberId,jdbcType=BIGINT},
      real_name = #{realName,jdbcType=VARCHAR},
      nickname = #{nickname,jdbcType=VARCHAR},
      date_create = #{dateCreate,jdbcType=TIMESTAMP},
      date_update = #{dateUpdate,jdbcType=TIMESTAMP},
      deleted = #{deleted,jdbcType=BIGINT}
    where id = #{id,jdbcType=BIGINT}
  </update>
</mapper>
3.3.5 新增實體類
package com.example.demo.entity;

import java.io.Serializable;
import java.util.Date;

public class TTestUser implements Serializable {
    /**
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database column t_test_user.id
     *
     * @mbggenerated
     */
    private Long id;

    /**
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database column t_test_user.member_id
     *
     * @mbggenerated
     */
    private Long memberId;

    /**
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database column t_test_user.real_name
     *
     * @mbggenerated
     */
    private String realName;

    /**
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database column t_test_user.nickname
     *
     * @mbggenerated
     */
    private String nickname;

    /**
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database column t_test_user.date_create
     *
     * @mbggenerated
     */
    private Date dateCreate;

    /**
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database column t_test_user.date_update
     *
     * @mbggenerated
     */
    private Date dateUpdate;

    /**
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database column t_test_user.deleted
     *
     * @mbggenerated
     */
    private Long deleted;

    /**
     * This field was generated by MyBatis Generator.
     * This field corresponds to the database table t_test_user
     *
     * @mbggenerated
     */
    private static final long serialVersionUID = 1L;

    /**
     * This method was generated by MyBatis Generator.
     * This method returns the value of the database column t_test_user.id
     *
     * @return the value of t_test_user.id
     *
     * @mbggenerated
     */
    public Long getId() {
        return id;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method sets the value of the database column t_test_user.id
     *
     * @param id the value for t_test_user.id
     *
     * @mbggenerated
     */
    public void setId(Long id) {
        this.id = id;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method returns the value of the database column t_test_user.member_id
     *
     * @return the value of t_test_user.member_id
     *
     * @mbggenerated
     */
    public Long getMemberId() {
        return memberId;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method sets the value of the database column t_test_user.member_id
     *
     * @param memberId the value for t_test_user.member_id
     *
     * @mbggenerated
     */
    public void setMemberId(Long memberId) {
        this.memberId = memberId;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method returns the value of the database column t_test_user.real_name
     *
     * @return the value of t_test_user.real_name
     *
     * @mbggenerated
     */
    public String getRealName() {
        return realName;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method sets the value of the database column t_test_user.real_name
     *
     * @param realName the value for t_test_user.real_name
     *
     * @mbggenerated
     */
    public void setRealName(String realName) {
        this.realName = realName == null ? null : realName.trim();
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method returns the value of the database column t_test_user.nickname
     *
     * @return the value of t_test_user.nickname
     *
     * @mbggenerated
     */
    public String getNickname() {
        return nickname;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method sets the value of the database column t_test_user.nickname
     *
     * @param nickname the value for t_test_user.nickname
     *
     * @mbggenerated
     */
    public void setNickname(String nickname) {
        this.nickname = nickname == null ? null : nickname.trim();
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method returns the value of the database column t_test_user.date_create
     *
     * @return the value of t_test_user.date_create
     *
     * @mbggenerated
     */
    public Date getDateCreate() {
        return dateCreate;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method sets the value of the database column t_test_user.date_create
     *
     * @param dateCreate the value for t_test_user.date_create
     *
     * @mbggenerated
     */
    public void setDateCreate(Date dateCreate) {
        this.dateCreate = dateCreate;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method returns the value of the database column t_test_user.date_update
     *
     * @return the value of t_test_user.date_update
     *
     * @mbggenerated
     */
    public Date getDateUpdate() {
        return dateUpdate;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method sets the value of the database column t_test_user.date_update
     *
     * @param dateUpdate the value for t_test_user.date_update
     *
     * @mbggenerated
     */
    public void setDateUpdate(Date dateUpdate) {
        this.dateUpdate = dateUpdate;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method returns the value of the database column t_test_user.deleted
     *
     * @return the value of t_test_user.deleted
     *
     * @mbggenerated
     */
    public Long getDeleted() {
        return deleted;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method sets the value of the database column t_test_user.deleted
     *
     * @param deleted the value for t_test_user.deleted
     *
     * @mbggenerated
     */
    public void setDeleted(Long deleted) {
        this.deleted = deleted;
    }

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table t_test_user
     *
     * @mbggenerated
     */
    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(getClass().getSimpleName());
        sb.append(" [");
        sb.append("Hash = ").append(hashCode());
        sb.append(", id=").append(id);
        sb.append(", memberId=").append(memberId);
        sb.append(", realName=").append(realName);
        sb.append(", nickname=").append(nickname);
        sb.append(", dateCreate=").append(dateCreate);
        sb.append(", dateUpdate=").append(dateUpdate);
        sb.append(", deleted=").append(deleted);
        sb.append(", serialVersionUID=").append(serialVersionUID);
        sb.append("]");
        return sb.toString();
    }
}
3.3.6 執(zhí)行查詢
@Slf4j
public class MyBatisBootStrap {

    public static void main(String[] args) {
        try {
            // 1. 讀取配置
            InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
            // 2. 創(chuàng)建SqlSessionFactory工廠
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            // 3. 獲取sqlSession
            SqlSession sqlSession = sqlSessionFactory.openSession();
            // 4. 獲取Mapper
            TTestUserMapper userMapper = sqlSession.getMapper(TTestUserMapper.class);
            // 5. 執(zhí)行接口方法
            TTestUser userInfo = userMapper.selectByPrimaryKey(16L);
            System.out.println("userInfo = " + JSONUtil.toJsonStr(userInfo));
            // 6. 提交事物
            sqlSession.commit();
            // 7. 關(guān)閉資源
            sqlSession.close();
            inputStream.close();
        } catch (Exception e){
            log.error(e.getMessage(), e);
        }
    }
}

3.4 區(qū)別

發(fā)現(xiàn)沒有在寫MyBatis的時候,新增了dao, mapper.xml, entity, mybatis-config.xml等很多東西,工作量反而增大了。但是dao, mapper.xml, entity都是可以根據(jù)插件mybatis-generator生成的,我們也不用一一去創(chuàng)建,而且我們沒有涉及到原生JDBC中加載驅(qū)動,創(chuàng)建連接,處理結(jié)果集,關(guān)閉連接等等這些操作,這些都是MyBatis幫我們做了,我們只用關(guān)心提供的查詢接口和sql編寫即可。

如果使用原生的JDBC進行數(shù)據(jù)庫操作,我們需要關(guān)心如何加載驅(qū)動,如何獲取連接關(guān)閉連接,如何獲取結(jié)果集等等與業(yè)務(wù)無關(guān)的地方,而MyBatis通過“映射”這個核心概念將sql和java接口關(guān)聯(lián)起來,我們調(diào)用java接口就相當于可以直接執(zhí)行sql,并且將結(jié)果映射為java pojo對象,這也是我們開頭說的“映射”,“面向?qū)ο蟮摹钡脑蛄恕?/p>

4. 總結(jié)

這篇文章簡單的介紹了下MyBatis的基本概念,并提供了簡單的栗子,接下來幾篇文章打算寫下Mybatis的啟動流程,讓我們更好的了解下mybatis的各模塊協(xié)作。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容