Mr. Cappuccino的第57杯咖啡——简单手写Mybatis大致原理

这篇具有很好参考价值的文章主要介绍了Mr. Cappuccino的第57杯咖啡——简单手写Mybatis大致原理。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

大致原理

底层基于JDK动态代理技术实现

项目结构

Mr. Cappuccino的第57杯咖啡——简单手写Mybatis大致原理,mybatis,mr,mybatis

项目代码

pom.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>com</groupId>
    <artifactId>mybatis-jdk-proxy</artifactId>
    <version>1.0-SNAPSHOT</version>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>8</source>
                    <target>8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

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

</project>

config.properties

driverClass=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/db_mybatis?serverTimezone=UTC
user=root
password=admin

UserEntity.java

package com.mybatis.entity;

/**
 * @author honey
 * @date 2023-07-26 15:29:38
 */
public class UserEntity {

    private Integer id;
    private String name;

    @Override
    public String toString() {
        return "UserEntity{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

UserMapper.java

package com.mybatis.mapper;

import com.mybatis.proxy.Insert;

/**
 * @author honey
 * @date 2023-07-26 21:04:23
 */
public interface UserMapper {

    /**
     * 新增用户
     *
     * @return int
     */
    @Insert("INSERT INTO `tb_user` (`id`, `name`) VALUES (null, 'Faker');")
    int insertUser();
}

Insert.java

package com.mybatis.proxy;

import java.lang.annotation.*;

/**
 * @author honey
 * @date 2023-07-27 20:48:38
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Insert {

    String value();
}

JdbcUtils.java

package com.mybatis.proxy;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Properties;

/**
 * @author honey
 * @date 2023-07-27 20:57:08
 */
public class JdbcUtils {
    
    private JdbcUtils() {

    }

    private static String url;
    private static String user;
    private static String password;

    static {
        try {
            InputStream resourceAsStream = JdbcUtils.class.getClassLoader().
                    getResourceAsStream("config.properties");
            Properties properties = new Properties();
            properties.load(resourceAsStream);
            String driverClass = properties.getProperty("driverClass");
            url = properties.getProperty("url");
            user = properties.getProperty("user");
            password = properties.getProperty("password");
            Class.forName(driverClass);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static Connection getConnection() {
        try {
            return DriverManager.getConnection(url, user, password);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
    
    public static void closeConnection(ResultSet resultSet, Statement statement, Connection connection) {
        try {
            if (resultSet != null) {
                resultSet.close();
            }
            if (statement != null) {
                statement.close();
            }
            if (connection != null) {
                connection.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    public static void closeConnection(Statement statement, Connection connection) {
        closeConnection(null, statement, connection);
    }
}

MapperProxy.java

package com.mybatis.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.PreparedStatement;

/**
 * @author honey
 * @date 2023-07-27 20:17:23
 */
public class MapperProxy implements InvocationHandler {

    private final Class<?> mapperClass;

    public MapperProxy(Class<?> mapperClass) {
        this.mapperClass = mapperClass;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 使用Java反射技术获取该方法上的注解
        Insert declaredAnnotation = method.getDeclaredAnnotation(Insert.class);
        String insertSql = declaredAnnotation.value();
        // 执行sql语句
        Connection connection = JdbcUtils.getConnection();
        PreparedStatement preparedStatement = connection.prepareStatement(insertSql);
        return preparedStatement.executeUpdate();
    }

    public <T> T getProxy() {
        return (T) Proxy.newProxyInstance(mapperClass.getClassLoader(), new Class[]{mapperClass}, this);
    }
}

SqlSession.java

package com.mybatis.proxy;

/**
 * @author honey
 * @date 2023-07-27 21:10:30
 */
public class SqlSession {

    public static <T> T getMapper(Class<T> type) {
        return new MapperProxy(type).getProxy();
    }
}

MybatisTest.java

package com.mybatis.test;

import com.mybatis.mapper.UserMapper;
import com.mybatis.proxy.SqlSession;

/**
 * @author honey
 * @date 2023-07-26 15:26:48
 */
public class MybatisTest {

    public static void main(String[] args) {
        System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
        UserMapper userMapper = SqlSession.getMapper(UserMapper.class);
        int result = userMapper.insertUser();
        System.out.println(result);
    }
}

代码测试

运行MybatisTest类

SqlSession.java

Mr. Cappuccino的第57杯咖啡——简单手写Mybatis大致原理,mybatis,mr,mybatis

MapperProxy.java

Mr. Cappuccino的第57杯咖啡——简单手写Mybatis大致原理,mybatis,mr,mybatis

MybatisTest.java

Mr. Cappuccino的第57杯咖啡——简单手写Mybatis大致原理,mybatis,mr,mybatis

MapperProxy.java

Mr. Cappuccino的第57杯咖啡——简单手写Mybatis大致原理,mybatis,mr,mybatis

MybatisTest.java

Mr. Cappuccino的第57杯咖啡——简单手写Mybatis大致原理,mybatis,mr,mybatis

运行结果

Mr. Cappuccino的第57杯咖啡——简单手写Mybatis大致原理,mybatis,mr,mybatis文章来源地址https://www.toymoban.com/news/detail-625917.html

到了这里,关于Mr. Cappuccino的第57杯咖啡——简单手写Mybatis大致原理的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Mr. Cappuccino的第69杯咖啡——Oracle之存储过程

    概念 PLSQL是Oracle对sql语言的过程化扩展,指在SQL命令语言中增加了过程处理语句(如分支、循环等),使SQL语言具有过程处理能力。 程序结构 PL/SQL可以分为三个部分:声明部分、可执行部分、异常处理部分。 其中DECLARE部分用来声明变量或游标(结果集类型变量),如果程序

    2024年01月17日
    浏览(48)
  • Mr. Cappuccino的第62杯咖啡——Spring之Bean的生命周期

    实现Aware接口是为了bean能获取某些信息、感知某些信息。Aware自身是一个空的接口,Spring提供了很多它的实现接口,开发者实现这些已有的接口就能获取特定的一些信息。 Spring提供了一些Aware接口的实现接口: ApplicationContextAware、ApplicationEventPublisherAware、BeanClassLoaderAware、Be

    2024年02月12日
    浏览(36)
  • Mr. Cappuccino的第60杯咖啡——Spring之BeanFactory和ApplicationContext

    概述 BeanFactory,以Factory结尾,表示它是一个工厂类(接口), 它是负责生产和管理bean的一个工厂。在Spring中,BeanFactory是IOC容器的核心接口,它的职责包括:实例化、定位、配置应用程序中的对象及建立这些对象间的依赖; BeanFactory只是个接口,并不是IOC容器的具体实现,但是

    2024年02月13日
    浏览(41)
  • Mr. Cappuccino的第68杯咖啡——基于Docker安装Oracle11g

    拉取镜像 以持久化的方式启动容器 关于持久化,source=oracle_vol指的是容器中的数据卷路径,target指的是容器外需要被挂载的目录路径。 查看volume的具体位置 修改配置文件 使用I键进入编辑模式,添加以下配置信息,再使用Esc键退出编辑模式,输入:wq保存配置信息。 检查配置

    2024年01月17日
    浏览(58)
  • Mr. Cappuccino的第58杯咖啡——MacOS配置Maven和Java环境

    如果使用的是bash,则使用以下命令 因为我这里使用的是zsh,所以使用以下命令 下载Maven Maven下载地址 配置前准备 使用command+shift+G进入/usr/local/目录 创建maven文件夹 将下载好的Maven压缩包解压 把解压后的文件复制到maven文件夹下面,并创建repo文件夹用来存放拉取的maven依赖

    2024年02月14日
    浏览(40)
  • Mr. Cappuccino的第63杯咖啡——Spring之AnnotationConfigApplicationContext源码分析

    以上一篇文章《Spring之Bean的生命周期》的代码进行源码分析 AnnotationConfigApplicationContext.java AbstractApplicationContext.java BeanFactory中两个重要的对象 DefaultListableBeanFactory.java DefaultSingletonBeanRegistry.java Debug源码分析 register(componentClasses):注册指定的配置类SpringConfig02到beanDefinitionMap集

    2024年02月13日
    浏览(39)
  • MyBatis原理分析手写持久层框架

    JDBC API 允许应用程序访问任何形式的表格数据,特别是存储在关系数据库中的数据 代码示例: 剖开代码,逐个分析: (1)加载驱动,获取链接: 存在问题1:数据库配置信息存在 硬编码 问题。 优化思路:使用配置文件! 存在问题2:频繁创建、释放 数据库连接 问题。 优

    2024年02月09日
    浏览(46)
  • 三分钟简单了解VR、AR、MR、XR是什么

    目录 一、VR虚拟现实( Virtual Reality ) 二、AR增强现实(Augmented Reality) 三、MR 混合现实(Mixed Reality) 四、XR扩展现实( Extended Reality)         如今随着各类3D技术、AI技术的不断发展,随着“元宇宙”概念的兴起,VR、AR、MR、XR等词频频映入眼帘,究竟什么是AR?VR?

    2024年02月08日
    浏览(41)
  • 【cobra】手写你的第一个命令行脚手架工具 | cobra整合go template通过终端以命令行方式生成.drone.yml 模板

    本次教程使用的开源框架如下: 名字 开源地址 作用 Cobra 命令行工具 https://github.com/spf13/cobra Aurora 字体颜色 https://github.com/logrusorgru/aurora go-zero go-z框架 模板功能 https://github.com/zeromicro/go-zero 本项目完整源码 :https://github.com/ctra-wang/cobra-gen-drone 概述 :Cobra 是一个 Golang 包,它

    2024年02月16日
    浏览(44)
  • 手写简单的RPC

    RPC(Remote Procedure Call,远程过程调用)是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布

    2024年04月22日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包