来自MyBatis不一样收获结果的探索之旅

本文深入探讨MyBatis的源码,从如何获取数据库源、执行Sql语句到处理结果集,揭示其内部机制。通过分析JDBC操作、配置解析和Executor的执行流程,理解MyBatis的ORM核心思想。同时,文章介绍了MyBatis-Plus的概述和简单示例,以及MybatisX和Mybatis-Mate等周边生态工具。
摘要由CSDN通过智能技术生成

概述

 

定义

MyBatis官网** mybatis – MyBatis 3 | Introduction 最新版本为3.5.9**

MyBatis是一个的ORM框架,支持自定义SQL、存储过程和高级映射。MyBatis对JDBC做了稳定封装使我们不再需要直接操作繁琐JDBC的代码进行参数的手动设置和结果检索。在MyBatis可以使用XML、注解和Java pojo映射到数据库记录。

由于我们Java技术栈程序员对MyBatis都已非常熟悉,本篇我们则主要是从源码的角度去收获不一样MyBatis理解之旅。众所周知JDBC操作核心步骤包括创建连接、创建Statement和执行SQL语句、ResultSet接收结果;MyBatis的ORM核心思想是用于实现面向对象编程语言里不同类型系统的数据之间的转换,我们接下来探索三个问题。

  • 如何获取数据库源?
  • 如何执行Sql语句?
  • 结果集如何处理?

源码探索

JDBC

我们先简单回顾下JDBC操作MySQL数据库的例子

package org.apache.ibatis.itxs;
​
import java.sql.*;
​
public class JDBCMain {
  public static void main(String[] args) {
    Connection connection = null;
    Statement st = null;
    ResultSet rs = null;
​
    try {
      //第一种注册驱动
      DriverManager.registerDriver(new com.mysql.jdbc.Driver());
​
      //第二种方式也可加载驱动程序
      //Class.forName("com.mysql.jdbc.Driver");
​
      //2.建立连接,参数一:协议+访问数据库,参数二:用户名,参数三:密码
      connection = DriverManager.getConnection("192.168.50.68:3306/testdb?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull", "test", "");
​
      //3.创建statement,跟数据库打交道一定需要这个对象
      st = connection.createStatement();
​
      //4.执行查询
      String sql = "select * from blog";
      rs = st.executeQuery(sql);
​
      //5.遍历查询每一条记录
      while(rs.next()) {
        int id = rs.getInt("id");
        String title = rs.getString("title");
        String content = rs.getString("content");
        System.out.println("id = " + id + "; title = " + title + "; content = " + content);
      }
​
      connection.close();
      st.close();
      rs.close();
​
    } catch (SQLException e) {
      e.printStackTrace();
    }
  }
}

搭建源码调试环境

mybatis源码GitHub - mybatis/mybatis-3: MyBatis SQL mapper framework for Java

由于我们直接在mybatis源码演示demo,所以需要先将mybatis源码下的pom中mysql-connector-java依赖的**<scope>test </scope>**注释掉,

数据库准备Blog表并初始数据,新建resources并标记为资源目录,常见mybatis-config.xml和db.properties文件,创建实体类Blog、还有对应Mapper接口、Mapper xml文件。创建一个main类调试。

Blog表语句

CREATE TABLE `blog` (
  `id` BIGINT NOT NULL,
  `title` VARCHAR(100) DEFAULT NULL,
  `content` VARCHAR(300) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;
insert into blog(id,title,content) values(1,'Java','面向对象');

mybatis-config.xml

<?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>
  <properties resource="config/db.properties"></properties>
  <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED">
        <property name="driver" value="${driver}"/>
        <property name="url" value="${url}"/>
        <property name="username" value="${username}"/>
        <property name="password" value="${password}"/>
      </dataSource>
    </environment>
  </environments>
  <mappers>
    <mapper resource="org/apache/ibatis/example/BlogMapper.xml"/>
  </mappers>
</configuration>

**db.properties **

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://192.168.50.68:3306/testdb?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&zeroDateTimeBehavior=convertToNull
username=test
password=

Blog.java

package org.apache.ibatis.example;
​
public class Blog {
  private long id;
  private String title;
  private String content;
​
  public long getId() {
    return id;
  }
​
  public void setId(long id) {
    this.id = id;
  }
​
  public String getTitle() {
    return title;
  }
​
  public void setTitle(String title) {
    this.title = title;
  }
​
  public String getContent() {
    return content;
  }
​
  public void setContent(String content) {
    this.content = content;
  }
​
  @Override
  public String toString() {
    return "Blog{" +
      "id=" + id +
      ", title='" + title + '\'' +
      ", content='" + content + '\'' +
      '}';
  }
}

BlogMapper.java

package org.apache.ibatis.example;
​
public interface BlogMapper {
  Blog selectBlog111(Long id);
}

BlogMapper.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="org.apache.ibatis.example.BlogMapper">
  <select id="selectBlog" resultType="org.apache.ibatis.example.Blog">
    select * from Blog where id = #{id}
  </select>
</mapper>

Main.java

package org.apache.ibatis.itxs;
​
import org.apache.ibatis.example.Blog;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
​
import java.io.IOException;
import java.io.InputStream;
​
public class Main {
  public static void main(String[] args) {
    String resource = "config/mybatis-config.xml";
    InputStream inputStream = null;
    try {
      inputStream = Resources.getResourceAsStream(resource);
      SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
      try (SqlSession session = sqlSessionFactory.openSession()) {
        Blog blog = session.selectOne("org.apache.ibatis.example.BlogMapper.selectBlog", 1);
        System.out.printf(blog.toString());
      }
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}

如何获取数据源

加载数据源配置信息

我们这里采用基于XML配置文件方式来演示,这样方式来学习通过mybatis源码笔者也认为最能得到,是Main类的main方法逐步调试进入mybatis的源码,从下面的堆栈调用链可以看出操作mybatis是从SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream)这一行开始,在这里先读取mybatis配置文件数据加载到全局配置Configuration里

首先parseConfiguration(XNode root)这个方法主要是初始化处理mybatis配置文件,我们发现配置文件中的**<properties resource="config/db.properties">****</properties>**在源码中是放在最前面,这个也解释如果我们把这行放在environments节点后面XML格式校验提示错误。org.apache.ibatis.builder.xml.XMLConfigBuilder中parseConfiguration方法代码如下:

  private void parseConfiguration(XNode roo
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值