Mybatis概述

本文详细介绍了MyBatis的功能架构,包括API接口、动态SQL和Select执行过程。MyBatis提供了Java API,支持动态构造SQL语句,并通过SqlSessionFactory和SqlSession管理数据库交互。在执行过程中,它首先创建SqlSession,然后根据Statement ID找到MappedStatement,通过Executor执行查询。文章还讨论了MyBatis的优点,如ORM映射和解耦,以及缺点,如SQL的编写工作量和数据库移植性问题。最后,简要提及了MyBatis的配置选项和接口使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

MyBatis的功能架构

这里写图片描述

API接口层
参见下方API

数据处理层

参数映射:指的是对于java 数据类型和jdbc数据类型之间的转换
SQL解析:SQL语句配置、解析、动态生成
SQL执行:Executor
结果映射处理:

基础支撑层

连接管理
事务管理
配置加载
缓存机制
SQL语句的配置方式

  • 基于注解
  • 基于XML文件

MyBatis Java API

SqlSessionFactoryBuilder

  • 创建SqlSessionFactory实例
  • build()方法从不同的资源中创建:InputStream或Configuration
  • InputStream可选的参数是 environment 和 properties
  • mybatis提供Resources 工具帮助加载资源文件
Reader getResourceAsReader(String resource)
Properties getResourceAsProperties(String resource)
InputStream getResourceAsStream(ClassLoader loader, String resource)

SqlSessionFactory

  • 调用openSession()创建SqlSession实例
  • 可选参数有:自动提交、事务隔离级别、预处理、自定义连接、执行器类型

SqlSession

语句执行方法

T selectOne(String statement)
List selectList(String statement)
Map selectMap(String statement, String mapKey)
int insert(String statement)
int update(String statement)
int delete(String statement)

事务控制方法

void commit()
void commit(boolean force)
void rollback()
void rollback(boolean force)

清理 Session 级的缓存

void clearCache()

关闭SqlSession

void close()

使用映射器

T getMapper(Class type)

动态 SQL

MyBatis 通过传入的参数值,使用 Ognl 来动态地构造SQL语句

  • if
  • choose (when, otherwise)
  • trim (where, set)
  • foreach

Select执行过程分析

1.创建SqlSession对象

2.为SqlSession传递参数:Statement Id和params

  • Statement Id对应xml配置文件里的sql语句
  • params 是传递的查询参数

分析源码可知
1.根据Statement Id,在mybatis 配置对象Configuration中查找和配置文件相对应的MappedStatement
2. 将查询任务委托给MyBatis 的执行器 Executor

3.执行器Executor根据SqlSession传递的参数执行query()方法

1.根据具体传入的参数,动态地生成需要执行的SQL语句,用BoundSql对象表示
2.为当前的查询创建一个缓存Key
3.缓存中没有值,直接从数据库中读取数据
4. 执行查询,返回结果,然后将查询的结果放入缓存之中
5. 根据既有的参数,创建StatementHandler对象来执行查询操作
6. 创建jStatement对象,传递给StatementHandler对象
7. 调用StatementHandler.query()方法,返回结果集

Executor.query()方法创建一个StatementHandler对象,然后将必要的参数传递给StatementHandler,使用StatementHandler来完成对数据库的查询,最终返回结果集


客户端如何调用接口?

1.MyBatis提供的API
如后面的例子

2.调用getMapper:面向接口编程
MyBatis 会根据相应的接口声明的方法信息,通过动态代理机制生成一个Mapper 实例,我们使用Mapper 接口的某一个方法时,MyBatis 会根据这个方法的方法名和参数类型,确定Statement Id


MyBatis的优缺点

优点

  • 解除sql与程序代码的耦合:通过提供DAL层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。
  • 提供映射标签,支持对象与数据库的orm字段关系映射
  • 提供对象关系映射标签,支持对象关系组建维护
  • 提供xml标签,支持编写动态sql。

缺点

  • 编写SQL语句时工作量很大。
  • SQL语句依赖于数据库,导致数据库移植性差,不能更换数据库。

配置

1.XML 映射配置文件
  • properties
    这些属性都是可外部配置且可动态替换的,既可以在典型的 Java 属性文件中配置,亦可通过 properties 元素的子元素来传递。
  • settings
    MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为
  • typeAliases
    存在的意义仅在于用来减少类完全限定名的冗余
<?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>

    <settings>
        <!-- 该配置影响的所有映射器中配置的缓存的全局开关 -->
        <setting name="cacheEnabled" value="false" />
        <!-- 允许 JDBC 支持自动生成主键,需要驱动兼容 -->
        <setting name="useGeneratedKeys" value="true" />
        <!-- 配置默认的执行器 :REUSE 执行器会重用预处理语句 -->
        <setting name="defaultExecutorType" value="REUSE" />
    </settings>

    <!-- 别名 -->
    <typeAliases>
        <typeAlias alias="User" type="com.moni.mybatis.models.User" />
    </typeAliases>

    <!-- 配置环境 -->
    <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/hibernate?&amp;useSSL=true" />
                <property name="username" value="moni" />
                <property name="password" value="520610" />
            </dataSource>
        </environment>
    </environments>

    <!-- 映射器用来定位映射文件 -->
    <mappers>
        <mapper resource="com/moni/mybatis/models/User.xml" />
    </mappers>
</configuration>
2.MyBatis XML映射文件
  • cache – 给定命名空间的缓存配置。
  • cache-ref – 其他命名空间缓存配置的引用。
  • resultMap – 是最复杂也是最强大的元素,用来描述如何从数据库结果集中来加载对象。
  • sql – 可被其他语句引用的可重用语句块。
  • insert – 映射插入语句
  • update – 映射更新语句
  • delete – 映射删除语句
  • select – 映射查询语句
<?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.moni.mybatis.models.IUser">

    <resultMap id="BaseResultMap" type="User">
        <result column="user_username" property="username" />
        <result column="user_password" property="password" />
    </resultMap>

    <!-- 外部 resultMap 的命名引用 -->
    <select id="Query" resultMap="BaseResultMap"
        parameterType="String" resultType="User">
        select * from user_info where user_username = #{username}
    </select>
    <insert id="Insert" parameterType="User">
        insert into user_info (user_username,user_password)
        values (#{username},#{password})
    </insert>
</mapper>

接口

package com.moni.mybatis.models;

import java.util.List;

public interface IUser {
    public List<User> getUserList();

    public void Insert(User user);

    public void updateUser(User user);

    public void deleteUser(String username);

    public String Query(String username);
}

测试

    private static SqlSessionFactory sqlSessionFactory;
    private static Reader reader;
    private static SqlSession sqlsession;
    //初始化
    static {    
        try {
            reader = Resources.getResourceAsReader("Configure.xml");
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);

        } catch (IOException e) {
            e.printStackTrace();
        }   
    }
    @Test
    public void Query() throws IOException {
        sqlsession = sqlSessionFactory.openSession();
        List<User> userList = sqlsession.selectList("com.moni.mybatis.models.IUser.Query","moni10");    
        for (User p : userList){
            System.out.println(p);
        }    
        sqlsession.close();
    }
    @Test
    public void Insert() throws IOException {
        sqlsession = sqlSessionFactory.openSession();
        // 获取Mapper
        IUser userMapper = sqlsession.getMapper(IUser.class);
        User user = new User();
        user.setUsername("moni10");
        user.setPassword("10");
        userMapper.Insert(user);
        sqlsession.commit();
        sqlsession.close();
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值