Mybatis

Mybatis简介

MyBatis 是一个操作数据库的框架,它专注于简化 Java 应用与数据库之间的交互。MyBatis 主要用于持久化数据,也就是将应用程序中的对象与数据库表中的数据进行映射和操作。

**通过 MyBatis,开发者可以执行常见的数据库操作,例如 增(INSERT)、删(DELETE)、改(UPDATE)、查(SELECT),并且可以灵活地编写 SQL 语句和自定义结果映射。**MyBatis 解决了 Java 开发中频繁编写 JDBC 代码、处理 SQL 语句和结果集的麻烦,同时又不会像其他 ORM(对象关系映射)框架那样完全自动化生成 SQL,它保留了手写 SQL 的灵活性。

它主要通过 XML 或注解的方式将 SQL 语句和 Java 方法进行映射,避免了像传统 JDBC 需要手动编写大量的 SQL 语句和处理繁琐的结果集转换。MyBatis 的核心思想是通过配置文件或注解将数据库查询与 Java 对象之间的映射做好,从而大大减少了开发人员在处理数据库交互时的工作量。

与其他 ORM 框架(如 Hibernate)不同,MyBatis 不会自动生成 SQL,而是允许开发者手动编写 SQL,从而提供更高的 SQL 控制力和灵活性。

Q1: 为什么 MyBatis 相比于其他 ORM 框架如 Hibernate 更加灵活?

MyBatis 允许开发者手动编写 SQL,而不像 Hibernate 那样自动生成 SQL 语句。这种方式给了开发者更多的灵活性,特别是面对复杂查询时,开发者可以完全控制 SQL 的结构和优化。这在需要对性能进行细粒度控制的场景中尤为重要。另一方面,MyBatis 的映射机制也使得它适用于简单或复杂的数据库结构,并且它不会强制开发者遵循特定的设计模式。

Q2: MyBatis 中如何处理 SQL 查询的参数和结果映射?

MyBatis 通过 动态 SQL 功能,允许开发者在配置文件中定义查询的参数,利用标签如 <if><foreach> 来实现动态 SQL 语句生成。对于结果映射,MyBatis 提供了 <resultMap> 标签,允许开发者将 SQL 查询结果映射到自定义的 Java 对象,甚至可以处理嵌套对象、集合等复杂场景。

Q3: 在使用 MyBatis 时,如何管理事务?

MyBatis 支持通过数据库的事务机制来管理事务。一般情况下,MyBatis 可以与 Spring 框架集成,由 Spring 来管理事务,也可以通过编程的方式手动提交和回滚事务。如果不使用 Spring 框架,开发者可以通过 SqlSession 对象来控制事务的提交与回滚。在复杂应用中,使用 Spring 来管理事务能够简化开发并确保事务的稳定性。

Mybatis入门程序

  • 创建 resources 目录

    • resources 目录用于存放资源文件和配置文件。一般 MyBatis 的配置文件会放在这里。
  • 引入依赖

    • 引入 MyBatis 的依赖以及数据库驱动(如 MySQL 驱动)。

    • 使用 Maven 引入依赖

      如果你使用 Maven 构建项目,需要在 pom.xml 文件中引入 MyBatis 和数据库驱动的依赖项。

      XML 复制代码
      <?xml version="1.0" encoding="UTF-8"?>
      <project xmlns="http://maven.apache.org/POM/4.0.0"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
          <modelVersion>4.0.0</modelVersion>
      
          <groupId>org.example</groupId>
          <artifactId>mybatis-introduction</artifactId>
          <version>1.0-SNAPSHOT</version>
      <dependencies>
      <!--    mybatis依赖-->
          <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
          <dependency>
              <groupId>org.mybatis</groupId>
              <artifactId>mybatis</artifactId>
              <version>3.5.16</version>
          </dependency>
      
      <!--    mysql依赖-->
          <!-- https://mvnrepository.com/artifact/com.mysql/mysql-connector-j -->
          <dependency>
              <groupId>com.mysql</groupId>
              <artifactId>mysql-connector-j</artifactId>
              <version>9.0.0</version>
          </dependency>
      
      
      </dependencies>
      
          <properties>
              <maven.compiler.source>22</maven.compiler.source>
              <maven.compiler.target>22</maven.compiler.target>
              <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
          </properties>
      
      </project>
  • 编写 MyBatis 核心配置文件 mybatis-config.xml(可以更改文件名)

    • 这个文件主要是用来配置数据库连接和 MyBatis 的全局设置。

    • 文件名通常为 mybatis-config.xml,但实际上可以根据需要使用其他名称。

    • 文件一般放在 resources 目录下,方便 MyBatis 自动加载。

      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="development">
              <environment id="development">
                  <transactionManager type="JDBC"/>
                  <dataSource type="POOLED">
                      <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
      <!--           jdbc:mysql://localhost:3306/     数据库的名称-->
                      <property name="url" value="jdbc:mysql://localhost:3306/Test"/>
      <!--                自己管理的账号密码-->
                      <property name="username" value="root"/>
                      <property name="password" value="gege5211314"/>
                  </dataSource>
              </environment>
          </environments>
      
          <!--执行XxxMapper.xml文件的路径-->
          <!--resource属性自动会从类的根路径下开始查找资源。-->
      
      <!--    <mapper resource="carMapper.XML"/>:
      告诉 MyBatis 从类路径的根目录加载名为 carMapper.XML 的 SQL 映射文件-->
          <mappers>
              <mapper resource="carMapper.XML"/>
          </mappers>
      </configuration>
  • 编写 SQL 映射文件 XxxxMapper.xml

    • 每个表对应一个 Mapper.xml 文件,用于定义 SQL 语句(如 insert, update, delete, select)。

    • XxxxMapper.xml 文件需要在 mybatis-config.xml 文件中进行注册,告诉 MyBatis 去哪里查找这些 SQL 映射文件。

      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.mybatis.example.BlogMapper">
      
      <!--    insert语句 id 是sql语句的唯一标识,这个id就代表了这条sql语句-->
          <insert id="insertCar">
              insert into t_car(id,car_num, brand, guide_price, produce_time, car_type)
              values(null,'1003','丰田霸道',30.0,'2000-10-11','燃油车')
          </insert>
      
      
      
      </mapper>

      注意,这个地方一定要和数据库里面的对应!!

第一个比较完整的Mybatis程序

java 复制代码
package test;

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;

public class complete {
    public static void main(String[] args) {
        SqlSession sqlSession = null;

        try {
            SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
            SqlSessionFactory factory = sqlSessionFactoryBuilder.build(Resources.getResourceAsStream("mybatis-config.XML"));

            // 开启会话(底层会开启事务)
            sqlSession = factory.openSession();

            // 执行sql语句,处理相关业务
            int insertCar = sqlSession.insert("insertCar");

            System.out.println("插入了 " + insertCar +"条记录");
            // 手动提交
            sqlSession.commit();
        } catch (IOException e) {
            // 最好回滚事务
            if(sqlSession != null){
                sqlSession.rollback();
            }
            e.printStackTrace();
        }finally {
            // 关闭会话 释放资源
            if(sqlSession != null){
                sqlSession.close();
            }
        }
    }
}

1. SqlSessionFactoryBuilder

java 复制代码
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
  • 作用SqlSessionFactoryBuilder 用来创建 SqlSessionFactory 对象。
  • 原理 :MyBatis通过读取配置文件(mybatis-config.xml)来构建 SqlSessionFactory。它是 MyBatis 的核心工厂,用来管理数据库会话 (SqlSession) 的创建。
  • 生命周期SqlSessionFactoryBuilder 通常用于应用程序启动时,它是一次性的,在创建好 SqlSessionFactory 之后可以被丢弃。

2. build() 方法

java 复制代码
SqlSessionFactory factory = sqlSessionFactoryBuilder.build(Resources.getResourceAsStream("mybatis-config.XML"));
//如果位于resources类的根目录下就是直接写xml的名称,否则需要根据具体情况分析
  • 作用build() 方法用于从配置文件中读取MyBatis的全局配置信息,并基于这些配置构建一个 SqlSessionFactory 实例。
  • Resources.getResourceAsStream():该方法用于加载位于类路径下的资源文件(如 mybatis-config.xml 配置文件),并返回文件的输入流。
  • 参数"mybatis-config.XML" 是 MyBatis 的核心配置文件,配置数据库连接信息、Mapper 映射文件等。

3. openSession() 方法

java 复制代码
sqlSession = factory.openSession();
  • 作用openSession() 用来开启一个数据库会话(SqlSession),这是 MyBatis 的核心接口,所有的数据库操作都依赖于它。
  • 事务管理 :默认情况下,MyBatis 的会话是手动提交事务的,所以在你进行增删改操作后,需要手动调用 commit() 来提交事务。
  • SqlSession:是MyBatis用于执行SQL语句、获取映射器和管理事务的主要接口。

4. insert() 方法

java 复制代码
int insertCar = sqlSession.insert("insertCar");
  • 作用insert() 方法执行 SQL 插入操作。
  • 参数insertCar 是 MyBatis Mapper XML 文件中定义的 insertCar 操作的 ID,MyBatis 会根据这个 ID 找到对应的 SQL 语句并执行。
  • 返回值insertCar 是插入记录的条数。返回一个整数值,表示插入的行数。

对应的 insertCar 映射在 CarMapper.xml 中可能是这样的:

XML 复制代码
 <insert id="insertCar">
        insert into t_car(id,car_num, brand, guide_price, produce_time, car_type)
        values(null,'1003','丰田霸道',30.0,'2000-10-11','燃油车')
    </insert>

5. commit() 方法

java 复制代码
sqlSession.commit();
  • 作用commit() 方法手动提交事务。由于 MyBatis 默认情况下需要手动提交事务,特别是当涉及到 INSERTUPDATEDELETE 操作时,必须通过 commit() 来保存对数据库的修改。
  • 事务的作用:确保操作是原子性的(要么全部执行,要么都不执行),保证数据库数据的完整性和一致性。

6. catch 块与异常处理

java 复制代码
} catch (IOException e) {
    // 最好回滚事务
    if(sqlSession != null){
        sqlSession.rollback();
    }
    e.printStackTrace();
}
  • 作用catch 块用于捕获可能发生的 IOException 异常(通常是读取配置文件失败或数据库连接失败)。
  • rollback() 方法 :在 catch 块中,当发生异常时,调用 rollback() 方法回滚事务,防止数据库操作部分完成而导致数据不一致。
  • 异常捕获和处理IOException 是可能在 Resources.getResourceAsStream() 读取配置文件时抛出的异常,这里使用 e.printStackTrace() 打印错误信息。

7. finally 块与资源释放

java 复制代码
} finally {
    // 关闭会话 释放资源
    if(sqlSession != null){
        sqlSession.close();
    }
}
  • 作用finally 块确保无论是否发生异常,数据库会话都会被关闭,释放资源。
  • close() 方法SqlSession 需要在使用完成后显式关闭。虽然 SqlSession 实现了 AutoCloseable 接口,但没有使用 try-with-resources 来自动管理资源,因此必须手动调用 close() 来释放资源。
  • 资源管理的重要性:关闭会话避免内存泄漏和连接资源的占用。数据库连接是宝贵的资源,必须在使用后及时关闭。
相关推荐
南城花随雪。9 分钟前
硬盘(HDD)与固态硬盘(SSD)详细解读
数据库
儿时可乖了10 分钟前
使用 Java 操作 SQLite 数据库
java·数据库·sqlite
懒是一种态度12 分钟前
Golang 调用 mongodb 的函数
数据库·mongodb·golang
天海华兮14 分钟前
mysql 去重 补全 取出重复 变量 函数 和存储过程
数据库·mysql
gma9991 小时前
Etcd 框架
数据库·etcd
爱吃青椒不爱吃西红柿‍️1 小时前
华为ASP与CSP是什么?
服务器·前端·数据库
Yz98762 小时前
hive的存储格式
大数据·数据库·数据仓库·hive·hadoop·数据库开发
苏-言2 小时前
Spring IOC实战指南:从零到一的构建过程
java·数据库·spring
Ljw...2 小时前
索引(MySQL)
数据库·mysql·索引
菠萝咕噜肉i2 小时前
超详细:Redis分布式锁
数据库·redis·分布式·缓存·分布式锁