51工具盒子

依楼听风雨
笑看云卷云舒,淡观潮起潮落

Mybatis的原理介绍及超详细使用

# (一)MyBatis简单介绍: {#一-mybatis简单介绍}

MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。iBATIS一词来源于"internet"和"abatis"的组合,是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects。

简而言之,MyBatis是一个能将传统JDBC变得很方便和易于维护 的框架。我们只需要提供SQL语句,而建立连接,创建Statement,处理JDBC异常等工作都可以交给MyBatis去做。

mybatis官方中文网站:https://mybatis.org/mybatis-3/zh/index.html

学习技术还是强烈建议大家通过官网学习,并参考博客,形成自己的一份见解。本系列文章基于Mybatis官方文档编写。

# (二)MyBatis环境搭建: {#二-mybatis环境搭建}

在这里我们使用maven仓库来引入对应的依赖,我们选一个用的最多的maven仓库

maven仓库:

<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.4.6</version>
</dependency>

# 2.1 创建一个数据库用于mybatis的学习 {#_2-1-创建一个数据库用于mybatis的学习}

create database `mybatis`;
use mybatis;

create table `user`(
	`id` INT(20) NOT NULL AUTO_INCREMENT,
	`name` VARCHAR(40) DEFAULT NULL,
	primary key(`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8;

insert into user(name) values('javayz'),('zhangsan')

这里主要建了一个数据库,并新建一张user表,并往里面插入两条数据,虽然现在数据库的可视化工具很多,还是建议大家平常联系中手动编写sql语句。

# 2.2 新建项目 {#_2-2-新建项目}

新建一个maven项目,并导入mybatis的相关依赖,我们需要在pom.xml中导入三个依赖:mysql驱动依赖、mybatis依赖以及junit依赖用于测试。

<dependencies>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.46</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
    <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>
</dependencies>

# 2.3 创建mybatis配置文件 {#_2-3-创建mybatis配置文件}

每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心的。SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先配置的 Configuration 实例来构建出 SqlSessionFactory 实例。

有了 SqlSessionFactory,顾名思义,我们可以从中获得 SqlSession 的实例。SqlSession 提供了在数据库执行 SQL 命令所需的所有方法

上面这几句话就是从官方中文文档中获取整合的,MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心,我们需要首先建立一个mybatis的配置文件。官方文档中把配置文件的名称叫做mybatis-config.xml。

我们在resources目录下新建这样一个配置文件mybatis-config.xml

<?xml version="1.0" encoding="UTF8" ?>
<!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.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&amp;useUnicode=true&amp;characterEncoding=UTF-8"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <!--每个mapper.xml都需要在mybatis配置文件中进行配置-->
    <mappers>
        <mapper resource="com/javayz/mapper/UserMapper.xml"/>
    </mappers>
</configuration>

这一段代码同样来自于官方文档,配置了事务管理器为JDBC,以及连接需要的一些属性,这些属性改成自己的配置。

最后mappers标签中需要加入接下来在代码中写的mapper.xml路径,不然运行时会报以下错误:

org.apache.ibatis.binding.BindingException: Type interface com.javayz.mapper.UserMapper is not known to the MapperRegistry.

# 2.4 编写工具类 {#_2-4-编写工具类}

接下来的步骤应该是去获取配置文件并构建SqlSessionFactory,官网提供了这样一段代码:

String resource = "org/mybatis/example/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

这里我们去编写一个工具类来实现以后需要多次实现的内容。

新建一个utils包,并在utils包下创建MybatisUtils类

public class MybatisUtils {
    private static SqlSessionFactory sqlSessionFactory;
    static {
        //获取SqlSessionFactory工厂类
        String resource = "mybatis-config.xml";
        InputStream inputStream = null;
        try {
            inputStream = Resources.getResourceAsStream(resource);
        } catch (IOException e) {
            e.printStackTrace();
        }
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    }
    //通过SqlSessionFactory获取SqlSession实例
    public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession();
    }
}

通过上面的工具类即可获取到sqlSession实例,剩下的就是对sqlSession一系列操作了。

# (三) Mybatis代码实践 {#三-mybatis代码实践}

首先编写一个实体类User,这一块的代码不作介绍了

public class User {
    private int id;
    private String name;
    //......
    //省略构造方法、get、set、toString方法
}

SqlSession对数据库的操作既可以使用XML方式也可以使用注解的方式,我们这里先介绍XML的方式,还是参考官方中文文档里面的xml代码。

新建一个名称为mapper的包,在里面新建一个UserMapper接口以及UserMapper.xml

public interface UserMapper {
    List<User> getUserList();
}

UserMapper.xml

<?xml version="1.0" encoding="UTF8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.javayz.mapper.UserMapper">
    <select id="getUserList" resultType="com.javayz.pojo.User">
        select * from user;
    </select>
</mapper>

xml文件中有几个点需要提一下,首先是namespace,每一个接口对应一个命名空间,这个命名空间就是接口的全路径。其次还需要注意resultType,也就是返回的类型,如果只填User也无法被找到。

最后在test包下编写测试类

public class UserMapperTest {
    @Test
    public void test(){
        //获取SqlSession
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        //执行Sql
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        List<User> userList = mapper.getUserList();
        System.out.println(userList);
       sqlSession.close();
    }
}

如果一切顺利这里就会输出正确结果,但是很有可能会出现下面这段报错信息

Error parsing SQL Mapper Configuration. Cause: java.io.IOException: Could not find resource com/javayz/mapper/UserMapper.xml

意思是找不到UserMapper.xml这个文件,但我们明明有,这里的问题是maven在编译过程中没有将上面的xml文件导出,我们需要在pom.xml中增加下面一段来配置resources

<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>true</filtering>
        </resource>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.properties</include>
                <include>**/*.xml</include>
            </includes>
            <filtering>true</filtering>
        </resource>
    </resources>
</build>

最终输出正确结果。

# (四)作用域和生命周期 {#四-作用域和生命周期}

在上面编写工具类的时候,我们用到了三个类:SqlSessionFactoryBuilderSqlSessionFactorySqlSession

由于SqlSession不是线程安全的,意味着在并发情况下使用不当会造成很严重的并发问题,因此我们有必要讨论这三个类的作用域以及生命周期。

首先SqlSessionFactoryBuilder是用来创建SqlSessionFactory的,用完之后就可以丢弃,因此将SqlSessionFactoryBuilder放到方法作用域内即可。

SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,因此我们将它放到应用作用域,在工具类中我将其设置成一个静态变量,这样就不会多次去创建。

SqlSession 的实例不是线程安全的,SqlSession 只在一个方法或者一个请求中使用,并且使用完之后必须关闭它。参考我上面的UserMapperTest 类,创建SqlSession 以及关闭SqlSession 都在一个方法中完成。

注意如果你使用的是依赖注入框架如MyBatis-Spring,就不必关注生命周期,因为依赖注入框架可以创建线程安全的、基于事务的 SqlSession 和映射器

# (五)总结 {#五-总结}

整体来看Mybatis的使用好像和jdbc相比没有方便多少,那是因为到现在为止我们做的都是各种配置,而等配置完成后,我们需要做的只不过是在mapper下写各种增删改查罢了。

赞(5)
未经允许不得转载:工具盒子 » Mybatis的原理介绍及超详细使用