Mybatis 简介与入门

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/yubujian_l/article/details/82379541

目录

1. Mybatis是什么?

1.1 Mybatis的发展

1.2 Mybatis vs JDBC SQL

2. 开始使用Mybatis

2.1 构建 SqlSessionFactory

2.1.1 XML 构建

 2.1.2 编码构建

2.2 使用 SqlSession

3. Mybatis的核心概念

3.1 核心类型

3.1.1 SqlSessionFactoryBuilder

3.1.2 SqlSessionFactory

3.1.3 SqlSession

3.1.4 Mapper interface

3.1.5 核心类的实践总结

3.2 SQL 的命名空间

3.2.1 SQL 映射简述

3.2.2 SQL 映射案例


1. Mybatis是什么?


Mybatis(3.x版本以前叫 ibatis)是一款一流的支持自定义 SQL、存储过程和高级映射的持久化框架。Mybatis 几乎消除了所有的 JDBC 代码,也基本不需要手工去设置参数和获取检索结果。Mybatis 能够使用简单的 XML 格式或者注解来进行配置,能够映射基本数据元素、Map 接口和 POJOs(普通 java 对象)到数据库的记录。

1.1 Mybatis的发展

Mybatis 的发展历程中有两个重要版本 2.x 和 3.x,3.x版本上 Mybatis 的配置更加简洁,我现在所使用的就是 mybatis-3.4.5。

1.2 Mybatis vs JDBC SQL

对比 Mybatis JDBC SQL
连接 托管 编码
SQL 隔离/集中 混合/分散
缓存 两级缓存 不支持
结果映射 自动映射 硬编码
维护性

2. 开始使用Mybatis


  • 在 IDEA 中安装 Mybatis 插件(Free Mybatis Plugin)
    • IDEA Settings -> Plugins -> Browse repositories -> Free Mybatis Plugin
    • 安装完成后重启IDEA

  •  准备 Mybatis 项目 
    • 创建一个 Maven 的 Application 项目
    • 在 pom.xml 中添加 Mybatis 依赖,org.mybatis:mybatis:3.4.5
    • pom.xml 中添加 JDBC 驱动依赖,比如:mysql:mysql-connector-java:5.1.46
<dependencies>

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

    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.4.5</version>
    </dependency>

</dependencies>
  • 准备数据库
    • 创建数据库
    • 创建数据库表

2.1 构建 SqlSessionFactory

2.1.1 XML 构建

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

  • 创建 Mybatis 配置文件(mybatis-config.xml 归档到 src/main/resources/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>
    <environments default="dev">
        <environment id="dev">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/memo"/>
                <property name="username" value="root"/>
                <property name="password" value="xyxy"/>
            </dataSource>
        </environment>
        
        <environment id="prod">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/memo"/>
                <property name="username" value="root"/>
                <property name="password" value="xyxy"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <mapper resource="mapper/MemoGroupMapper.xml"/>
    </mappers>

</configuration>

从 XML 文件中构建 SqlSessionFactory 的实例非常简单,建议使用类路径下的资源文件进行配置。但是也可以使用任意的输入流(InputStream)实例,包括字符串形式的文件路径或者 file:// 的 URL 形式的文件路径来配置。

Mybatis 包含一个名叫 Resources 的工具类,它包含一些实用方法,可以非常容易从 classpath 或其他位置家在资源文件。

public static void main(String[] args) {

    try {
       SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(
                Resources.getResourceAsReader("mybatis-config.xml")
        );
        System.out.println(sqlSessionFactory);
    } catch (IOException e) {
        e.printStackTrace();
    }

}

 2.1.2 编码构建

如果你更愿意直接从 Java 程序而不是 XML 文件中创建 configuration,或者创建你自己的 configuration 构建器,Mybatis 也提供了完整的配置类,提供所有和 XML 文件相同功能的配置项。

// mybatis提供的数据库连接池
DataSource dataSource = new PooledDataSource();
TransactionFactory transactionFactory = new JdbcTransactionFactory();
Environment environment = new Environment("development", transactionFactory, dataSource);
Configuration configuration = new Configuration(environment);
configuration.addMapper(MemoGroupMapper.class);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);

该例中,configuration 添加了一个映射类(mapper class)。映射器类是 Java 类,它们包含 SQL 映射语句的注解,从而避免了 XML 文件的依赖。不过,由于 Java 注解的一些限制加之某些 Mybatis 映射的复杂性,XML 映射对于大多数高级映射(比如:嵌套 join 映射)来说仍然是必须的。有鉴于此,如果存在一个对等的 XML 配置文件的话,Mybatis 会自动查找并加载它(在这种情况下,MemoGroupMapper.xml 将会基于类路径和 MemoGroupMapper.class 的类名被加载进来)。

2.2 使用 SqlSession

既然有了 SqlSessionFactory,顾名思义,我们就可以从中获得 SqlSession 的实例了。SqlSession 完全包含了面向数据库执行 SQL 命令所需的所有方法。可以通过 SqlSession 实例来直接执行已映射的 SQL 语句。例如:

SqlSession session = sqlSessionFactory.openSession();
// 自动提交
// SqlSession session = sqlSessionFactory.openSession(true);
try {
    MemoGroup memoGroup = (MemoGroup)
    session.selectOne("com.lwstudy.mybatis.mapper.MemoGroupMapper.selectMemoGroup", 1);
} finally {
    session.close();
}

 诚然这种方式能够正常工作,并且对于使用旧版本MyBatis 的用户来说也比较熟悉,不过现在有了一种更直白的方式。使用对于给定语句能够合理描述参数和返回值的接口(比如说MemoGroupMapper.class),现在不但可以执行更清晰和类型安全的代码,而且还不用担心易错的字符串字面值以及强制类型转换。例如:

SqlSession session = sqlSessionFactory.openSession();
// 自动提交
// SqlSession session = sqlSessionFactory.openSession(true);
try {
    MemoGroupMapper mapper = session.getMapper(MemoGroupMapper.class);
    MemoGroup memoGroup = mapper.selectMemoGroup(1);
} finally {
    session.close();
}

SQL 映射文件内容

<?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.lwstudy.mybatis.mapper.MemoGroupMapper">

    <resultMap id="memoGroup" type="com.lwstudy.mybatis.entity.MemoGroup">
        <id property="id" column="id" jdbcType="INTEGER"/>
        <result property="name" column="name" jdbcType="VARCHAR"/>
        <result property="createdTime" column="created_time" jdbcType="TIMESTAMP"/>
        <result property="modifyTime" column="modify_time" jdbcType="TIMESTAMP"/>
    </resultMap>

    <select id="selectMemoGroup" resultType="com.lwstudy.mybatis.entity.MemoGroup">
        select id, name, created_time, modify_time from memo_group
        where id=#{id}
    </select>

</mapper>

3. Mybatis的核心概念


3.1 核心类型

3.1.1 SqlSessionFactoryBuilder

sqlSessionFactoryBuilder 这个类可以在任何时候被实例化、使用和销毁。一旦创造了 SqlSessionFactory 就不需要再保留它。所以 SqlSessionFactoryBuilder 实例的最好的作用域就是方法体内(即一个本地方法变量)。虽然能重用 SqlSessionFactoryBuilder 创建多个 SqlSessionFactory 实例,但最好不要把时间、资源放在解析 XML 文件上,而要从中解放出来做最重要的事情。

3.1.2 SqlSessionFactory

sqlSessionFactory 一旦创建,SqlSessionFactory 将会存在于应用程序整个运行生命周期中。很少或根本没有理由去销毁它或者重新创建它。最佳实践是不要在一个应用中多次创 SqlSessionFactory。这样做会被视为“没品味”,SqlSessionFactory 最好的作用域范围是一个应用的生命周期范围。这可以由多种方式来实现,最简单的方式是使用 Singleton 模式或静态 Singleton 模式。但这不是被广泛接受的最佳做法,相反,您可能更愿意使用像 Google Guice 或Spring 的依赖注入方式。这些框架允许您创造一个管理器,用于管理 SqlSessionFactory 的生命周期。

3.1.3 SqlSession

sqlSession 每个线程都有一个 SqlSession 实例,SqlSession 实例是不被共享的,并且不是线程安全的。因此最好的作用域是request 或者 method。决不要用一个静态字段或者一个类的实例字段来保存 SqlSession 实例引用。也不要用任何一个管理作用域,如 Servlet 框架中的 HttpSession,来保存 SqlSession 的引用。如果您正在用一个 WEB 框架,可以把 SqlSession 的作用域看作类似于 HTTP 的请求范围。也就是说,在收到一个 HTTP 请求,可以打开一个 SqlSession,当把 response 返回时,就可以把 SqlSession 关闭。关闭会话是非常重要的,应该要确保会话在一个 finally 块中被关闭。

3.1.4 Mapper interface

mapper 是创建来绑定映射语句的接口,该 Mapper 实例是从 SqlSession 得到的。因此,所有 mapper 实例的作用域跟创建它的 SqlSession 一样。但是,mapper 实例最好的作用域是 method,也就是他们应该在方法内被调用,使用完即被销毁。并且 mapper 实例不用显式的被关闭。虽然把 mapper 实例保持在一个 request 范围(与 SqlSession 相似)不会产生太大的问题,但是,在这个层次管理太多资源可能会失控。保持简单,就是让 Mappers 保持在一个方法内。

3.1.5 核心类的实践总结

作用域
SqlSessionFactoryBuilder method
SqlSessionFactory application(单例)
SqlSession request、thread、method(非线程安全)
Mapper interface request、thread、method

3.2 SQL 的命名空间

3.2.1 SQL 映射简述

Mybatis 中关于 SQL 的部分主要集中在 SQL 映射,其支持 SQL 映射的方式有两种,一种是基于 XML 的方式,一种是基于注解。

Mybatis 的所有特性都是可以通过 XML 配置的方式进行定义,通常情况都是通过 XML 配置来使用 Mybatis 的 SQL 映射,主要原因有以下几种:

  • XML 配置支持 Mybatis 的所有特性
  • XML 的维护性、可读性强
  • 开发工具对 Mybatis 的 SQL 映射 XML 配置具有良好的支持
  • XML 配置集中管理 SQL 是使用 Mybatis 的一个重要因素
  • 注解方式难以处理复杂 SQL

3.2.2 SQL 映射案例

<?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.lwstudy.mybatis.mapper.MemoGroupMapper">

    <resultMap id="memoGroup" type="com.lwstudy.mybatis.entity.MemoGroup">
        <id property="id" column="id" jdbcType="INTEGER"/>
        <result property="name" column="name" jdbcType="VARCHAR"/>
        <result property="createdTime" column="created_time" jdbcType="TIMESTAMP"/>
        <result property="modifyTime" column="modify_time" jdbcType="TIMESTAMP"/>
    </resultMap>

    <select id="selectMemoGroup" resultMap="memoGroup" resultType="com.lwstudy.mybatis.entity.MemoGroup">
        select id, name, created_time, modify_time from memo_group
        where id=#{id}
    </select>

</mapper>

上面映射文件中的 com.lwstudy.mybatis.mapper.MemoGroupMapper 就是命名空间名称,selectMemoGroup 是 SQL 的名称,在同一个命名空间下,SQL 名称是唯一的。

第一种查询

SqlSession sqlSession = sqlSessionFactory.openSession();
MemoGroup memoGroup = sqlSession.selectOne(
        "com.lwstudy.mybatis.mapper.MemoGroupMapper.selectMemoGroup", 1);

通过 命名空间 + SQL 名称 映射到具体的 SQL。

第二种查询

MemoGroupMapper memoGroupMapper = sqlSession.getMapper(MemoGroupMapper.class);
MemoGroup memoGroup = memoGroupMapper.selectMemoGroup(1);

通过接口类映射,相比第一种查询有以下几个优势:

  • 不依赖字符串,不容易出错,所以安全。
  • 通过 IDE 的自动完成功能,可以快速通过映射类导航到具体的 SQL 语句。
  • 不需要关注方法返回类型,不需要进行类型强转。 

猜你喜欢

转载自blog.csdn.net/yubujian_l/article/details/82379541
今日推荐