MyBatis 源码分析 - MyBatis入门,张口就来

*   *   [4.1 在pom.xml添加依赖](about:blank#41_pomxml_276)

    *   [4.2 在application.yml配置](about:blank#42_applicationyml_322)

    *   [4.3 mapper文件](about:blank#43_mapper_362)

    *   [4.4 创建用户表与添加用户数据](about:blank#44__395)

    *   [4.5 创建实体类](about:blank#45__435)

    *   [4.6 新建dto和vo对象](about:blank#46_dtovo_478)

    *   [4.7 bean转换工具类](about:blank#47_bean_554)

    *   [4.8 用户service接口](about:blank#48_service_577)

    *   [4.9 用户controller](about:blank#49_controller_615)

    *   [4.10 启动类](about:blank#410__636)

*   [5.总结](about:blank#5_662)

*   [参考](about:blank#_670)

| 序号 | 内容 | 链接 |

| — | — | — |

| 1 | MyBatis 源码分析 - MyBatis入门 | [https://thinkwon.blog.csdn.net/article/details/114808852](

) |

| 2 | MyBatis 源码分析 - 配置文件解析过程 | [https://thinkwon.blog.csdn.net/article/details/114808962](

) |

| 3 | MyBatis 源码分析 - 映射文件解析过程 | [https://thinkwon.blog.csdn.net/article/details/115423167](

) |

| 4 | MyBatis 源码分析 - SQL 的执行过程 | [https://thinkwon.blog.csdn.net/article/details/115603376](

) |

| 5 | MyBatis 源码分析 - 内置数据源 | [https://thinkwon.blog.csdn.net/article/details/116331419](

) |

| 6 | MyBatis 源码分析 - 缓存原理 | [https://thinkwon.blog.csdn.net/article/details/116809942](

) |

| 7 | MyBatis 源码分析 - 插件机制 | [https://thinkwon.blog.csdn.net/article/details/116809961](

) |

[](

)1.本文速览


本篇文章从 MyBatis 是什么(what),为什么要使用(why),以及如何使用(how)等三个角度进行了说明和演示。

[](

)2.什么是 MyBatis


MyBatis 的前身是 iBatis,其是 Apache 软件基金会下的一个开源项目。2010年该项目从 Apache 基金会迁出,并改名为 MyBatis。同期,iBatis 停止维护。

MyBatis 是一种半自动化的 Java 持久层框架(persistence framework),其通过注解或 XML 的方式将对象和 SQL 关联起来。之所以说它是半自动的,是因为和 Hibernate 等一些可自动生成 SQL 的 ORM(Object Relational Mapping) 框架相比,使用 MyBatis 需要用户自行维护 SQL。维护 SQL 的工作比较繁琐,但也有好处。比如我们可控制 SQL 逻辑,可对其进行优化,以提高效率。

MyBatis 是一个容易上手的持久层框架,使用者通过简单的学习即可掌握其常用特性的用法。这也是 MyBatis 被广泛使用的一个原因。

[](

)3.为什么要使用 MyBatis


技术之间通常没有高下之分。从应用场景的角度来说,符合应用场景需求的技术才是合适的选择。那下面我会通过写代码的方式,来比较一下这几种数据库访问技术的优缺点,并会在最后说明 MyBatis 的适用场景。

这里,先把本章所用到的一些公共类和配置贴出来


public class Article {

    private Integer id;

    private String title;

    private String author;

    private String content;

    private Date createTime;

    

    // 省略 getter/setter 和 toString

} 

数据库相关配置放在了 jdbc.properties 文件中,详细内容如下:


jdbc.driver=com.mysql.cj.jdbc.Driver

jdbc.url=jdbc:mysql://localhost:3306/coolblog?useUnicode=true&characterEncoding=utf8&autoReconnect=true&rewriteBatchedStatements=TRUE

jdbc.username=root

jdbc.password=**** 

表记录如下:

数据库sql如下:


DROP TABLE IF EXISTS `article`;



CREATE TABLE `article` (

  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,

  `author_id` int(11) NOT NULL,

  `title` varchar(32) DEFAULT NULL,

  `type` tinyint(4) DEFAULT NULL,

  `content` text,

  `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,

  PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;



LOCK TABLES `article` WRITE;

/*!40000 ALTER TABLE `article` DISABLE KEYS */;



INSERT INTO `article` (`id`, `author_id`, `title`, `type`, `content`, `create_time`)

VALUES

	(1,1,'MyBatis 源码分析系列文章导读',8,'MyBatis 源码分析系列文章导读','2018-07-15 15:30:09'),

	(2,2,'HashMap 源码详细分析(JDK1.8)',1,'HashMap 源码详细分析(JDK1.8)','2018-01-18 15:29:13'),

	(3,1,'Java CAS 原理分析',1,'Java CAS 原理分析','2018-05-15 15:28:33'),

	(4,1,'Spring IOC 容器源码分析 - 获取单例 bean',4,'Spring IOC 容器源码分析 - 获取单例 bean','2018-06-01 00:00:00'),

	(5,1,'Spring IOC 容器源码分析 - 循环依赖的解决办法',4,'Spring IOC 容器源码分析 - 循环依赖的解决办法','2018-06-08 00:00:00'),

	(6,2,'Spring AOP 源码分析系列文章导读',4,'Spring AOP 源码分析系列文章导读','2018-06-17 00:00:00'),

	(7,2,'Spring AOP 源码分析 - 创建代理对象',4,'Spring AOP 源码分析 - 创建代理对象','2018-06-20 00:00:00'),

	(8,1,'Spring MVC 原理探秘 - 一个请求的旅行过程',4,'Spring MVC 原理探秘 - 一个请求的旅行过程','2018-06-29 00:00:00'),

	(9,2,'Spring MVC 原理探秘 - 容器的创建过程',4,'Spring MVC 原理探秘 - 容器的创建过程','2018-06-30 00:00:00'),

	(10,2,'Spring IOC 容器源码分析系列文章导读',4,'Spring IOC 容器源码分析系列文章导读','2018-05-30 00:00:00');



/*!40000 ALTER TABLE `article` ENABLE KEYS */;

UNLOCK TABLES;



# Dump of table author

# ------------------------------------------------------------



DROP TABLE IF EXISTS `author`;



CREATE TABLE `author` (

  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,

  `name` varchar(32) DEFAULT NULL,

  `age` tinyint(4) DEFAULT NULL,

  `sex` tinyint(4) DEFAULT NULL,

  `email` varchar(64) DEFAULT NULL,

  PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;



LOCK TABLES `author` WRITE;

/*!40000 ALTER TABLE `author` DISABLE KEYS */;



INSERT INTO `author` (`id`, `name`, `age`, `sex`, `email`)

VALUES

	(1,'coolblog.xyz',28,0,'coolblog.xyz@outlook.com'),

	(2,'nullllun',29,1,'coolblog.xyz@outlook.com');



/*!40000 ALTER TABLE `author` ENABLE KEYS */;

UNLOCK TABLES;



# Dump of table student

# ------------------------------------------------------------



DROP TABLE IF EXISTS `student`;



CREATE TABLE `student` (

  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,

  `name` varchar(32) DEFAULT NULL,

  `age` tinyint(4) DEFAULT NULL,

  PRIMARY KEY (`id`)

) ENGINE=InnoDB DEFAULT CHARSET=utf8;



LOCK TABLES `student` WRITE;

/*!40000 ALTER TABLE `student` DISABLE KEYS */;



INSERT INTO `student` (`id`, `name`, `age`)

VALUES

	(1,'coolblog',20);



/*!40000 ALTER TABLE `student` ENABLE KEYS */;

UNLOCK TABLES; 

[](

)3.1 使用 MyBatis 访问数据库

前面说过,MyBatis 是一种半自动化的 Java 持久化框架,使用 MyBatis 需要用户自行维护 SQL。这里,我们把 SQL 放在 XML 中,文件名称为 ArticleMapper.xml。相关配置如下:


<mapper namespace="xyz.coolblog.dao.ArticleDao">

    <resultMap id="articleResult" type="xyz.coolblog.model.Article">

        <id property="id" column="id"/>

        <result property="title" column="title"/>

        <result property="author" column="author"/>

        <result property="content" column="content"/>

        <result property="createTime" column="create_time"/>

    </resultMap>

    

    <select id="findByAuthorAndCreateTime" resultMap="articleResult">

        SELECT

            `id`, `title`, `author`, `content`, `create_time`

        FROM

            `article`

        WHERE

            `author` = #{author} AND `create_time` > #{createTime}

    </select>

</mapper> 

上面的 SQL 用于从article表中查询出某个作者从某个时候到现在所写的文章记录。在 MyBatis 中,SQL 映射文件需要与数据访问接口对应起来,比如上面的配置对应xyz.coolblog.dao.ArticleDao接口,这个接口的定义如下:


public interface ArticleDao {

    List<Article> findByAuthorAndCreateTime(@Param("author") String author, @Param("createTime") String createTime);

} 

要想让 MyBatis 跑起来,还需要进行一些配置。比如配置数据源、配置 SQL 映射文件的位置信息等。本节所使用到的配置如下:


<configuration>

    <properties resource="jdbc.properties"/>



    <environments default="development">

        <environment id="development">

            <transactionManager type="JDBC"/>

            <dataSource type="POOLED">

                <property name="driver" value="${jdbc.driver}"/>

                <property name="url" value="${jdbc.url}"/>

                <property name="username" value="${jdbc.username}"/>

                <property name="password" value="${jdbc.password}"/>

            </dataSource>

        </environment>

    </environments>

    

    <mappers>

        <mapper resource="mapper/ArticleMapper.xml"/>

    </mappers>

</configuration> 

到此,MyBatis 所需的环境就配置好了。接下来把 MyBatis 跑起来吧,相关测试代码如下:


public class MyBatisTest {



    private SqlSessionFactory sqlSessionFactory;



    @Before

    public void prepare() throws IOException {

        String resource = "mybatis-config.xml";

        InputStream inputStream = Resources.getResourceAsStream(resource);

        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        inputStream.close();

    }



    @Test

    public void testMyBatis() throws IOException {

        SqlSession session = sqlSessionFactory.openSession();

        try {

            ArticleDao articleDao = session.getMapper(ArticleDao.class);

            List<Article> articles = articleDao.findByAuthorAndCreateTime("coolblog.xyz", "2018-06-10");

        } finally {

            session.commit();

            session.close();

        }

    }

} 

在上面的测试代码中,prepare 方法用于创建SqlSessionFactory工厂,该工厂的用途是创建SqlSession。通过 SqlSession,可为我们的数据库访问接口ArticleDao接口生成一个代理对象。MyBatis 会将接口方法findByAuthorAndCreateTime和 SQL 映射文件中配置的 SQL 关联起来,这样调用该方法等同于执行相关的 SQL。

上面的测试代码运行结果如下:

img

如上,大家在学习 MyBatis 框架时,可以配置一下 MyBatis 的日志,这样可把 MyBatis 的调试信息打印出来,方便观察 SQL 的执行过程。在上面的结果中,==>符号所在的行表示向数据库中输入的 SQL 及相关参数。<==符号所在的行则是表示 SQL 的执行结果。

[](

)3.2 JDBC 和 Spring JDBC 简介

JDBC

JDBC 作为 Java 平台的数据库访问规范,它仅提供一种访问数据库的能力。使用步骤:加载数据库驱动,创建数据库连接对象,创建 SQL 执行语句对象,执行 SQL 和处理结果集。缺点: JDBC 流程繁琐;拼接 SQL 可能会导致 SQL 出错;将 SQL 和 Java 代码混在一起,会降低代码的可读性,不利于维护;执行结果的处理麻烦;用户还需要手动管理数据库连接,开始要手动获取数据库连接。使用好后,又要手动关闭数据库连接

Spring JDBC

Spring JDBC 在 JDBC 基础上,进行了比较薄的包装,易用性得到了不少提升。不过它也是存在一定缺陷的,比如 SQL 仍是写在代码中,需要用户自行处理 ResultSet 等。不过与 JDBC 相比,使用 Spring JDBC 无需手动加载数据库驱动,获取数据库连接,以及创建 Statement 对象等操作。总的来说,易用性上得到了不少的提升。

[](

)3.3 MyBatis 和 Hibernate 比较

MyBatis 和 Hibernate共同点:都是对jdbc的封装,都是持久层的框架,都用于dao层的开发。

| | MyBatis | Hibernate |

| — | — | — |

| 映射关系 | 配置Java对象与sql语句执行结果的对应关系,多表关联关系配置简单 | 配置Java对象与数据库表的对应关系,多表关联关系配置复杂 |

| SQL优化和移植性 | MyBatis 需要手动编写 SQL,支持动态 SQL、处理列表、动态生成表名、支持存储过程。开发工作量相对大些。直接使用SQL语句操作数据库,不支持数据库无关性,但sql语句优化容易。 | Hibernate 对SQL语句封装,提供了日志、缓存、级联(级联比 MyBatis 强大)等特性,此外还提供 HQL(Hibernate Query Language)操作数据库,数据库无关性支持好,但会多消耗性能。如果项目需要支持多种数据库,代码开发量少,但SQL语句优化困难。 |

| 学习成本 | MyBatis 是轻量级框架,学习使用门槛低 | Hibernate 是重量级框架,学习使用门槛高 |

| 使用场景 | 适合于需求变化频繁,大型的项目,比如:互联网电子商务系统 | 适合于需求相对稳定,中小型的项目,比如:办公自动化系统 |

| 总结 | MyBatis 是一个小巧、方便、高效、简单、直接、半自动化的持久层框架 | Hibernate 是一个强大、方便、高效、复杂、间接、全自动化的持久层框架 |

[](

)4.如何使用 MyBatis


使用 MyBatis 的方式主要有:单独使用 MyBatis,与 Spring 整合使用,与 Spring Boot 整合使用。鉴于目前使用 Spring Boot 的方式比较流行,接下来就介绍 MyBatis 与 Spring Boot 整合使用,其他两种方式读者感兴趣可以自行进行尝试。

[](

)4.1 在pom.xml添加依赖


<dependencies>

    <!-- mybatis -->

    <dependency>

        <groupId>org.mybatis.spring.boot</groupId>

        <artifactId>mybatis-spring-boot-starter</artifactId>

        <version>2.1.4</version>

    </dependency>



    <!-- mysql数据库驱动 -->

    <dependency>

        <groupId>mysql</groupId>

        <artifactId>mysql-connector-java</artifactId>

        <scope>runtime</scope>

    </dependency>



    <!-- lombok -->

    <dependency>

        <groupId>org.projectlombok</groupId>

        <artifactId>lombok</artifactId>

        <optional>true</optional>

    </dependency>



    <!-- springboot 2.3.0及以上版本 解决@Validated @Valid 不起作用的问题 -->

    <dependency>

        <groupId>org.springframework.boot</groupId>

        <artifactId>spring-boot-starter-validation</artifactId>

    </dependency>



    <dependency>

        <groupId>org.springframework.boot</groupId>

        <artifactId>spring-boot-starter-web</artifactId>

    </dependency>



    <dependency>

        <groupId>org.springframework.boot</groupId>

        <artifactId>spring-boot-starter-test</artifactId>

        <scope>test</scope>

    </dependency>

</dependencies> 

[](

)4.2 在application.yml配置


# 应用服务 WEB 访问端口

server:

  port: 8080



# spring配置

spring:

  application:

    name: spring-boot-mybatis

  # 数据库配置


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值