MyBatis入门篇

1,631 阅读8分钟

这是我参与8月更文挑战的第9天,活动详情查看:8月更文挑战

MyBatis概述

MyBatis是一个半ORM优秀持久层框架,封装了JDBC操作的很多细节,免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作,使我们只需关注SQL语句本身,它使用ORM思想实现对结果集的封装。ORM (Object Relationalp Mapping)对象关系映射把数据库表和实体类对应起来(数据库表与我们的实体类相对应,数据库表中的一行行记录就与我们一个一个实例对象相对应,数据库表字段就与我们类的属性所对应),让我们可以通过操作实体类来操作数据库表。

image.png

  • 首先看传统的JDBC编码
//1. 加载数据库连接驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//2. 获取连接
Connection connection = DriverManager.getConnection("url","username", "password");
//3. 获取预编译语句
PreparedStatement preparedStatement = connection.prepareStatement("select * from test where username=?");
//4.设置预编译参数
preparedStatement.setString(1, "param");
//5. 执行SQL语句
ResultSet resultSet = preparedStatement.executeQuery();
//6. 处理返回结果集
List<Object> result = dealResultSet(resultSet);
//7. 关闭连接
connection.close()

从以上我们可以看出使用JDBC来进行数据库操作首先需要获得数据库的链接connection,然后创建预编译语句preparedStatement对象并向其注入参数,执行查询语句返回ResultSet结果集,从结果集中获取数据构造对象。那么有了MyBatis后,像这些数据库连接、参数注入、获取结果集的工作就不用我们来实现,而是交给MyBatis来处理,我们只需关注SQL语句本身。

MyBatis与Hibernate的区别

  • MyBatis是一种半自动映射的ORM框架。所谓半自动是指我们需要手动配置POJO、SQL和映射关系,而Hibernate只需提供POJO和映射关系即可。MyBatis支持配置动态SQL和SQL优化,且MyBatis支持存储过程。
  • Hibernate是一种全自动映射的ORM框架,我们只需要定义好持久化对象到数据库表的映射关系,就可以完成持久岑操作。

MyBatis的使用

入门程序

目录结构 image.png

创建一个Maven工程,引入Mybatis的相关依赖

<dependencies>
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.4.5</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.11</version>
    </dependency>
    <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.12</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
</dependencies>

创建一个实体类

public class User {
    private Integer id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;
}
  • MySQL数据库中创建的数据库表
Create Table  CREATE TABLE `user` (   
    `id` int(11) NOT NULL AUTO_INCREMENT,
    `username` varchar(32) NOT NULL COMMENT '用户名称',
    `birthday` datetime DEFAULT NULL COMMENT '生日',
    `sex` char(1) DEFAULT NULL COMMENT '性别',
    `address` varchar(256) DEFAULT NULL COMMENT '地址', 
    PRIMARY KEY (`id`) 
) ENGINE=InnoDB AUTO_INCREMENT=54 DEFAULT CHARSET=utf8

创建Dao接口

public interface UserDao {
    User getUserById(int id);
}

创建映射配置文件UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.demo.mybatis.dao.UserDao">

    <select id="getUserById" resultType="com.demo.mybatis.pojo.User">
        select * from user where id=#{id};
    </select>
</mapper>

创建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">
<!--mybatis的 主配置文件-->
<configuration>
    <!--配置环境-->
    <environments default="mysql">
        <!--配置mysql环境-->
        <environment id="mysql">
            <!--transactionManager代表配置事务的类型-->
            <transactionManager type="JDBC"></transactionManager>
            <!--配置数据源(连接池)-->
            <dataSource type="POOLED">
                <!--配置连接数据库的4个基本信息-->
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/students?serverTimezone=GMT"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>

    <!--指定映射配置文件的位置-->
    <mappers>
        <mapper resource="mapper/UserMapper.xml"/>
    </mappers>
</configuration>

测试

public static void main(String[] args) throws IOException {
    //1、读取配置文件
    InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");

    //2、创建SqlSessionFactory工厂
    SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
    SqlSessionFactory factory = builder.build(is);

    //3、使用工厂生产SqlSession对象
    SqlSession session = factory.openSession();

    //4、使用SqlSeesion创建Dao接口的代理对象
    UserDao userDao = session.getMapper(UserDao.class);

    //5、使用代理对象执行方法
    System.out.println(userDao.getUserById(42));
    //6、释放资源
    session.close();
    is.close();
}

以上就是MyBatis简单的入门程序,在现实的开发中我们并不会去用这种方式,而是用Mybatis与Spring整合、或者在SpringBoot中引入Mybatis的方式来进行开发。

MyBatis执行步骤

MyBatis操作数据库可以分成以下几个步骤:

  1. 首先Mybatis会通过Io流读取主配置文件SqlMapConfig.xml以及所有的Mapper.xml映射文件。

  2. 构建会话工厂SqlSessionFactory。使用new SqlSessionFactoryBuilder().bulid(InputStream in)获取构造对象,利用build方法获取SqlSessionFactory接口的实现类DefaultSqlSessionFactory,在build方法中使用XMLConfigBuilder的parse()方法将数据库、映射文件、配置文件等相关信息封装为Configuration对象,将获取的Configuration对象作为创建DefaultSqlSessionFactory的参数。

  3. 创建SqlSession对象。通过前面创建的DefaultSqlSessionFactory来创建SqlSession对象,该对象中包含了执行SQL的所有方法(其底层封装了JDBC连接、可以直接使用其实例来执行已映射SQL语句)

  4. Executor执行器是MySQL用来操作数据库的一个接口,他会根据SqlSession传递的参数动态地生成需要执行的SQL语句。

  5. 在Executor接口中的方法都包含有一个MapperStatement类型的参数,该参数是对映射信息的封装,用于存储要执行的SQL语句的id,参数等。Mapper.xml映射文件中的一个SQL语句就对应一个MapperStatement对象,SQL语句配置的id就是MapperStatement的id。

  6. 输入参数映射。在执行持久层接口方法时,MappedStatement对象会对执行SQL语句的参数进行定义,然后Executor会通过MappedStatment对象,在执行SQL前将输入的Java对象映射到SQL语句中。

  7. 输出结果映射。执行完SQL语句后,MappedStatement会对数据结果进行定义,将然后Exeutor会通过MappedStatement将SQL执行后的输出结果映射为Java对象。

image.png

Mybatis核心配置文件详解

< configuration >

<configuration>是Mybatis核心配置文件的根标签。所有的其他标签都必须包含在< configuration >标签中。

< environments>

用于对数据库环境进行配置。它包含< dataSource> 和< transactionManager>两个子标签。< dataSource>用于配置数据源,他的type属性用于指定哪种数据源< transactionManager>用于配置事务管理,他的type属性用于指定使用哪种事务管理器

< settings >

< settings >下包含报个< setting >标签, <setting>标签主要用于改变Mybatis运行时的行为,如开启二级缓存,开启延迟加载等。常见参数如下:

  • cacheEnabled:是否开启二级缓存,默认为false
  • lazyLoadingEnabled:是否开启延迟加载,默认为false
  • multipleResultSetsEnabled:是否允许单一语句返回多结果集,默认为true

< typeAliases>

配置别名,用于为配置文件中的Java类型设置一个简短的名字。< typeAliases>标签有两个子标签分别为< typeAlias>和< package>, < typeAlias>子标签只能对单个Java类设置别名,而< package name="包名">子标签,可以将所配置的包下面的所有Java类统一设置别名。▶ps:也可以通过在实体类上使用@Alias(value = "别名")注解来设置

< typeHandlers>

标签中有< typeHandler>和< package>子标签,< typeHandlers>标签的作用就是配置一个类型处理器,将预处理语句中传入的参数从Java类型转换为JDBC类型,或者对从数据库取出的结果由JDBC类型转换为Java类型。

< mappers>

标签用于指定映射文件的位置。包含子标签,其中mapper子标签有以下属性:

  • resource:使用类路径指定映射文件位置
  • url:使用本地文件路径指定映射文件位置
  • class:使用接口口指定Mapper映射文件位置
  • package:使用包名指定Mapper映射文件的位置

Mapper映射文件

Mapper映射文件主要是用来定义操作数据库的SQL语句,在Mapper文件中,以mapper作为根节点,其下面可以配置的子节点有: select, insert, update, delete, cache, cache-ref, resultMap,下面将对他们逐个描述。

< mapper>根标签

namespace属性用于指定该映射文件所映射的Dao接口的全限定类名。

< select>

用于映射查询语句。其包含以下几个常用属性:

  • id:命名空间的唯一标识,即接口Dao接口中的方法名称
  • useCache :将其设置为 true 后,将会导致本条语句的结果被二级缓存缓存起来,默认值:对 select 元素为 true。
  • parameterType:标识传入SQL语句额参数类的全限定类名,可选属性,因为MyBatis的类型处理器TypeHandler会推断出具体的传入参数类型。
  • resultType:执行SQL后返回额结果集类型的全限定类名。
  • useCache:用于控制二级缓存的开闭。
  • resultMap:对外部 resultMap 的命名引用。resultType 和 resultMap 之间只能同时使用一个。
  • flushCache:将其设置为true 后,只要语句被调用,都会导致本地缓存和二级缓存被清空,默认值:false。

< insert>

用于映射插入语句,其包含以下几个属性:

  • keyProperty:用于将插入或更新操作时的返回值赋值给POJO的某个属性,通常设置为主键对应的属性,如我们需要返回插入成功后的新数据的主键值,就可以利用该属性。
  • keyColumn:当主键不是第一列时,用于设置第几列是主键。

< update>、< delete>

用于映射更新和删除的SQL语句。

< resultMap>

表示用于结果集映射,< resultMap>中包含两个常用的子标签,分别为< collection>和< association>,他们是用来处理多表时的关联关系的,< collection>用于一对多的关联关系,< association>用于一对一的关联关系。

< cache-ref>

对某一namespace命名空间的语句,只会使用该命名空间的缓存进行缓存或刷新。如果想要在多个命名空间中共享相同的缓存配置和实例,可以使用 cache-ref标签来引用另一个缓存。如<cache-ref namespace="com.demo.mybatis.EmployeeMapper"/>

< cache >

默认情况下,MyBatis只启用了本地的会话缓存即SqlSession对象的缓存(一级缓存),它仅仅对一个会话中的数据进行缓存。 要启用全局的二级缓存即多个SqlSession共享缓存,那么需要在你的Mapper映射文件中添加< cache/>标签。

🏁以上就是MyBatis入门的简单介绍,后面还回继续推出系列文章,如果有错误的地方,还请留言指正,如果觉得本文对你有帮助那就点个赞👍吧😻😍

默认标题_动态分割线_2021-07-15-0.gif