MyBatis的运行原理

news2024/12/29 9:34:39

目录

1、目的:梳理一下MyBatis运行时的几个对象,我们需要搞清楚他们的作用,进而需要理解mybatis的整个工作流程和执行原理。

2、简要概括各个类

2.1 Resources

作用:编写资源加载类,使用类加载器加载 配置文件(mybatis-config.xml ),即:读取mybatis-config.xml

2.2 SqlSessionFactoryBuilder

作用:将配置资源封装成Configuration对象,并且将该资源对象传到工厂对象中

2.2.1 Configuration

作用:配置类 --> 把所有的配置信息 都装进去

2.2.2 MappedStatement

作用:用来封装 sql语句 和 查询结果集(即:返回值类型)

2.3 SqlSessionFactory

2.4 SqlSession

2.5 ProxyFactory

3、测试


1、目的:梳理一下MyBatis运行时的几个对象,我们需要搞清楚他们的作用,进而需要理解mybatis的整个工作流程和执行原理。

mybatis-config.xml

mapper.xml mapper.xml mapper.xml...

|

|

Resources

|

|---->InputStream

|

SqlSessionFactoryBuilder

|

|---->Configuration(conn, Map<namespace+"."+id, MappedStatement(sql, resultType)>)

|

SqlSessionFactory

|

|---->Configuration(conn, Map<namespace+"."+id, MappedStatement(sql, resultType)>)

|

SqlSession

|

|---->conn, Map<namespace+"."+id, MappedStatement(sql, resultType)>

|

ProxyFactory

|

|---->MappedStatement(sql, resultType), conn

|

Executor

| |

| |

| |

输入出映射

2、简要概括各个类

2.1 Resources

作用:编写资源加载类,使用类加载器加载 配置文件(mybatis-config.xml ),即:读取mybatis-config.xml

package com.by.io;

import java.io.InputStream;

public class Resources {
    //根据文件名称,加载类路径下面的配置文件
    public static InputStream getResourceAsStream(String filePath){
        return Resources.class.getClassLoader().getResourceAsStream(filePath);
    }
}

2.2 SqlSessionFactoryBuilder

作用:将配置资源封装成Configuration对象,并且将该资源对象传到工厂对象中

package com.by.builder;

import com.by.cfg.Configuration;
import com.by.factory.DefaultSqlSessionFactory;
import com.by.factory.SqlSessionFactory;
import com.by.utils.XMLConfigBuilder;

import java.io.InputStream;

public class SqlSessionFactoryBuilder {

    /**
     * 构建SqlSessionFactory对象
     * @param in
     * @return
     */
    public SqlSessionFactory build(InputStream in){
        Configuration configuration = XMLConfigBuilder.loadConfiguration(in);
        return  new DefaultSqlSessionFactory(configuration);
    }
}

2.2.1 Configuration

作用:配置类 --> 把所有的配置信息 都装进去

package com.by.cfg;

import com.by.mapping.MappedStatement;

import java.util.HashMap;
import java.util.Map;

public class Configuration {

    private String driver;
    private String url;
    private String username;
    private String password;
	
    /**
       Map<"com.by.dao.UserDao.findAll", MappedStatement>     
    */
    private Map<String, MappedStatement> mappers = new HashMap<String,MappedStatement>();

    public Map<String, MappedStatement> getMappers() {
        return mappers;
    }

    public void setMappers(Map<String, MappedStatement> mappers) {
        this.mappers.putAll(mappers);//此处需要使用追加的方式
    }

    public String getDriver() {
        return driver;
    }

    public void setDriver(String driver) {
        this.driver = driver;
    }

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

2.2.2 MappedStatement

作用:用来封装 sql语句 和 查询结果集(即:返回值类型)

package com.by.mapping;

public class MappedStatement {

    private String queryString;//SQL
    private String resultType;//实体类的全限定类名

    public String getQueryString() {
        return queryString;
    }

    public void setQueryString(String queryString) {
        this.queryString = queryString;
    }

    public String getResultType() {
        return resultType;
    }

    public void setResultType(String resultType) {
        this.resultType = resultType;
    }
}

2.3 SqlSessionFactory

package com.by.factory;
public interface SqlSessionFactory {
    //获取SQLSession对象
    public SqlSession openSession();
}
package com.by.factory;

import com.by.cfg.Configuration;
import com.by.session.DefaultSqlSession;
import com.by.session.SqlSession;

public class DefaultSqlSessionFactory implements SqlSessionFactory {

    private Configuration cfg;

    public DefaultSqlSessionFactory(Configuration cfg) {
        this.cfg = cfg;
    }

    /**
     * 获取一个SqlSession对象
     * @return
     */
    @Override
    public SqlSession openSession() {
        return new DefaultSqlSession(cfg);
    }
}

2.4 SqlSession

public interface SqlSession {
    //获取代理对象
    public <T> T getMapper(Class<T> tClass);
     //释放资源
    void close();
}
package com.by.session;

import com.by.utils.DataSourceUtil;
import com.by.cfg.Configuration;

import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.SQLException;

public class DefaultSqlSession implements SqlSession {

    private Configuration cfg;
    private Connection conn;

    public DefaultSqlSession(Configuration cgf){
        this.cfg = cgf;
        this.conn = DataSourceUtil.getConnection(cfg);
    }


    /*
    * 创建代理对象
    */
    @Override
    public <T> T getMapper(Class<T> tClass) {
        /**
         * tClass.getClassLoader():类加载器
         * new Class[]{tClass}:Class数组,让代理对象和被代理对象有相同的行为
         *  new ProxyFactory:调用真实角色,附加自己的操作
         */
        return (T) Proxy.newProxyInstance(tClass.getClassLoader(),
                new Class[]{tClass},
                new ProxyFactory(cfg.getMappers(),conn));
    }

    @Override
    public void close() {
        try {
            conn.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

2.5 ProxyFactory

package com.by.session;

import com.by.mapping.MappedStatement;
import com.by.utils.Executor;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.util.Map;

public class ProxyFactory implements InvocationHandler {

    private Map<String, MappedStatement> mappers;
    private Connection conn;
    public ProxyFactory(Map<String, MappedStatement> mappers, Connection conn){
       this.mappers = mappers;
       this.conn = conn;
    }
    //调用代理对象的任何方法,都会在这执行
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //1.获取方法名
        String methodName = method.getName();
        //2.获取方法所在类的名称
        String className = method.getDeclaringClass().getName();
        //3.组合key
        String key = className+"."+methodName;
        //4.获取mappers中的Mapper对象
        MappedStatement mappedStatement = mappers.get(key);
        //5.判断是否有mapper
        if(mappedStatement == null){
            throw new IllegalArgumentException("传入的参数有误");
        }
        //6.调用工具类执行查询所有
        return new Executor().selectList(mappedStatement,conn);
    }
}

3、测试

//1.读取配置文件
    InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
    //2.创建SqlSessionFactory工厂
    SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
    SqlSessionFactory factory = builder.build(in);
    System.out.println("-----" + factory);
    //3.使用工厂生产SqlSession对象
    SqlSession session = factory.openSession();
    //4.使用SqlSession创建Dao接口的代理对象
    UserDao userDao = session.getMapper(UserDao.class);
    //5.使用代理对象执行方法
    List<User> users = userDao.findAll();
    for(User user : users){
        System.out.println(user);
    }
    //6.释放资源
    session.close();
    in.close();

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1814436.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

AI驱动的电子元器件商城物流优化

随着电子元器件市场的不断发展&#xff0c;电子元器件商城&#xff08;ECM&#xff09;的物流管理变得越来越复杂。如何通过人工智能&#xff08;AI&#xff09;技术优化物流流程&#xff0c;提高物流效率&#xff0c;成为电子元器件商城需要解决的重要问题。本文将探讨AI驱动的…

RawChatGPT:公益大模型使用网站

文章目录 一、Rawchat简介1.1 RawChat的主要特性1.2 RawChat的技术原理简述 二、使用教程三、案例应用3.1 图片内容分析3.2 生图演示3.3 文档解析 一、Rawchat简介 RawChat平台的诞生&#xff0c;其核心理念是降低用户访问类似ChatGPT这类先进AI服务的门槛&#xff0c;同时提供…

Python基础教程(十四):OS 文件/目录方法

&#x1f49d;&#x1f49d;&#x1f49d;首先&#xff0c;欢迎各位来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里不仅可以有所收获&#xff0c;同时也能感受到一份轻松欢乐的氛围&#xff0c;祝你生活愉快&#xff01; &#x1f49d;&#x1f49…

【Python】一文向您详细介绍 sys.argv

【Python】一文向您详细介绍 sys.argv 下滑即可查看博客内容 &#x1f308; 欢迎莅临我的个人主页 &#x1f448;这里是我静心耕耘深度学习领域、真诚分享知识与智慧的小天地&#xff01;&#x1f387; &#x1f393; 博主简介&#xff1a;985高校的普通本硕&#xff0c;曾…

数字化:蚓链帮你打通企业营销线上线下的“任督二脉”!

​在这个飞速发展的时代&#xff0c;数字化如同一把神奇的钥匙&#xff0c;开启了企业营销的全新篇章&#xff01;它正以惊人的力量助力企业实现线上线下的融合&#xff0c;为企业带来新的机遇和挑战&#xff01; 数字化成为企业营销的关键驱动力。它通过多种方式实现线上和线…

AI助手:Agent工作流程与应用场景详解

引言 智能体&#xff08;Agent&#xff09;是一种在特定环境中自主行动、感知环境、做出决策并与其他智能体或人类进行交互的计算机程序或实体。它们具备自主性、反应性、社交性和适应性等特点&#xff0c;能够根据环境的变化调整自己的行为&#xff0c;以达到预设的目标。本文…

晶体管类型及结构,晶体管的电流放大作用

晶体管类型及结构 1.3.1 晶体管的结构及类型根据不同的掺杂方式在同一个硅片上制造出三个掺杂区域&#xff0c;并形成两个PN结&#xff0c;就构成晶体管。采用平面工艺制成的 NPN型硅材料晶体管的结构如图1.3.2(a)所示&#xff0c;位于中间的P区称为基区&#xff0c;它很薄且杂…

MySQL JDBC驱动包引入有版本要求吗

提示&#xff1a;有关数据库的任何操作&#xff0c;请事先都做好备份&#xff0c;一定不会错的&#xff1b; 文章目录 前言一、com.mysql.jdbc.Driver和com.mysql.cj.jdbc.Driver如何选择&#xff1f;1、概念2、引入驱动3、总结 前言 新老项目的交替中&#xff0c;如果你使用的…

旅游网页(HTML+CSS+JS)

前言 本篇博客就不给大家讲解了&#xff0c;直接上代码 &#x1f493; 个人主页&#xff1a;普通young man-CSDN博客 ⏩ 文章专栏&#xff1a;https://blog.csdn.net/2302_78381559/category_12644031.html?spm1001.2014.3001.5482https://blog.csdn.net/2302_78381559/catego…

最受欢迎的测试用例管理工具,14款软件全方位对比

14款不错的测试用例管理工具对比&#xff1a;PingCode、TestRAIl、Xray、PractiTest、Tricentis qTest、禅道&#xff08;ZenTao&#xff09;、Zephyr、Tapd、TestLink、TestCollab、Testin云测、云效&#xff08;Alibaba Cloud Effect&#xff09;、TeavCloud、FitNesse。 在软…

如何做好期货投资?

期货&#xff0c;这个词对于很多人来说可能还是个陌生的词汇&#xff0c;但是&#xff0c;随着经济的发展和人们对金融投资的需求增加&#xff0c;期货投资也变得越来越受到关注。那么&#xff0c;如何才能做好期货投资呢&#xff1f; 首先&#xff0c;了解期货的基本知识是非…

Linux网络编程(二)Socket编程

Socket编程 一、网络套接字概念&#xff1a;socket 一个文件描述符指向一个套接字&#xff08;该套接字内部由内核借助两个缓冲区实现。&#xff09;在通信过程中&#xff0c; 套接字一定是成对出现的。二、网络字节序和主机字节序的转换函数&#xff08;ip和端口&#xff09…

戎码翼龙NG-EDR白皮书

NG-EDR 很轻 内核轻量不卡机&#xff01; ◆ 戎码翼龙AI原生NG-EDR具备强大的数据采集能力&#xff0c;涵盖了MITRE ATT&CK框架下的终端数据源&#xff0c;能为威胁检测提供强力基础。在技术实现层面&#xff0c;戎码翼龙采用了先进的内核级数据采集技术&#xff0c;以超…

aardio - 关于字符串指针的操作

一、前言&#xff1a; aardio中的字符串&#xff0c;是不可修改的。 我们对字符串变量重新赋值一个不同的字符串&#xff0c;并不是“修改数据”&#xff0c;而是“更换地址”&#xff0c;实际上是赋予了一个新的内存指针。 先看下图&#xff0c;理解一下aardio中字符串变量…

跳动圆点加载动画

效果图: 完整代码: <!DOCTYPE html> <html> <head><meta charset="UTF-8" /><title>跳动圆点加载动画</title><style type="text/css">body {background: #ECF0F1;display: flex;justify-content: center;al…

MATLAB神经网络---激活层

reluLayer 修正线性单元 (ReLU) 层 ReLU 层对输入的每个元素执行阈值运算&#xff0c;其中任何小于零的值都设置为零。 此运算等效于 语法 layer reluLayer 创建一个 ReLU 层。 layer reluLayer(Name,Name) 创建一个 ReLU 层&#xff0c;并使用名称-值对组设置可选的 Nam…

【机器学习】机器学习与金融科技在智能投资中的融合应用与性能优化新探索

文章目录 引言机器学习与金融科技的基本概念机器学习概述监督学习无监督学习强化学习 金融科技概述股票预测风险管理资产配置 机器学习与金融科技的融合应用实时市场数据分析数据预处理特征工程 股票预测与优化模型训练模型评估 风险管理与优化深度学习应用 资产配置与优化强化…

产品管理:抓住关键要素的ABC分类法

目录 简介 ABC 分类法步骤 第一步&#xff1a;收集数据 第二步&#xff1a;处理数据 第三步&#xff1a;根据 ABC 分析表确定分类 第四步&#xff1a;绘制ABC分析图 第五步&#xff1a;根据 ABC 分析的结果&#xff0c;对 ABC 三类商品采取不同的管理策略 附&#xff1…

jenkins 自动化任务构建案例

一新建Item 输入一个名称&#xff0c;点击Freestyle project 进入到配置项 选择 This project is parameterized&#xff0c;点击String Parameter 添加 变量值 command添加执行的命令 二构建 点击build构建触发器 三查看控制台 控制台输出信息无误

双亲委派模型是什么,为什么要使用双亲委派模型

双亲委派模型是什么&#xff0c;为什么要使用双亲委派模型 在Java中&#xff0c;类加载器&#xff08;ClassLoader&#xff09;是负责将类文件加载到JVM中的关键组件。为了确保类加载过程的安全性和稳定性&#xff0c;Java引入了一种叫做双亲委派模型&#xff08;Parent Deleg…