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

简单手写Mybatis大致原理

    • 大致原理
    • 项目结构
    • 项目代码
    • 代码测试

大致原理

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

项目结构

在这里插入图片描述

项目代码

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;@Overridepublic 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;}@Overridepublic 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

在这里插入图片描述

MapperProxy.java

在这里插入图片描述

MybatisTest.java

在这里插入图片描述

MapperProxy.java

在这里插入图片描述

MybatisTest.java

在这里插入图片描述

运行结果

在这里插入图片描述

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

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

相关文章

SpringBoot统一功能处理(AOP思想实现)(统一用户登录权限验证 / 异常处理 / 数据格式返回)

主要是三个处理&#xff1a; 1、统一用户登录权限验证&#xff1b; 2、统一异常处理&#xff1b; 3、统一数据格式返回。 目录 一、用户登录权限校验 &#x1f345; 1、使用拦截器 &#x1f388; 1.1自定义拦截器 &#x1f388; 1.2 设置自定义拦截器 &#x1f388;创建cont…

一零六七、JVM梳理

JVM&#xff1f; Java虚拟机&#xff0c;可以理解为Java程序的运行环境&#xff0c;可以执行Java字节码&#xff08;Java bytecode&#xff09;并提供了内存管理、垃圾回收、线程管理等功能 java内存区域划分?每块内存中都对应什么? 方法区&#xff1a;类的结构信息、常量池、…

Typescript+vite+sass手把手实现五子棋游戏(放置类)

Typescriptvitesass手把手实现五子棋游戏&#xff08;放置类&#xff09; 下面有图片和gif可能没加载出来 上面有图片和gif可能没加载出来 导言 最近练习Typescript&#xff0c;觉得差不多了&#xff0c;就用这个项目练练手&#xff0c;使用Typescript纯面向对象编程。 开源…

马斯克收购AI.com域名巩固xAI公司地位;如何评估大型语言模型的性能

&#x1f989; AI新闻 &#x1f680; AI拍照小程序妙鸭相机上线商业工作站并邀请摄影师进行内测 摘要&#xff1a;AI拍照小程序妙鸭相机将上线面向商业端的工作站&#xff0c;并邀请摄影师进行模板设计的内测。妙鸭相机希望为行业提供更多生态产品&#xff0c;扩大行业规模&a…

在java中如何使用openOffice进行格式转换,word,excel,ppt,pdf互相转换

1.首先需要下载并安装openOffice,下载地址为&#xff1a; Apache OpenOffice download | SourceForge.net 2.安装后&#xff0c;可以测试下是否可用&#xff1b; 3.build.gradle中引入依赖&#xff1a; implementation group: com.artofsolving, name: jodconverter, version:…

安卓4G核心板开发板_MTK6785/MT6785(Helio G95)安卓手机主板方案

联发科MTK6785&#xff08;Helio G95&#xff09;安卓核心板采用八核 CPU 具有两个强大的 Arm Cortex-A76 处理器内核&#xff0c;主频高达 2.05GHz&#xff0c;外加六个 Cortex-A55 高效处理器。其强大的图形性能由 Arm Mali-G76 MC4 提供&#xff0c;速度可提升至 900MHz 。 …

【云原生】K8S二进制搭建二:部署CNI网络组件

目录 一、K8S提供三大接口1.1容器运行时接口CRI1.2云原生网络接口CNI1.3云原生存储接口CSI 二、Flannel网络插件2.1K8S中Pod网络通信2.2Overlay Network2.3VXLAN2.4Flannel 三、Flannel udp 模式的工作原理3.1ETCD 之 Flannel 提供说明 四、vxlan 模式4.1Flannel vxlan 模式的工…

无向图-已知根节点求高度

深搜板子题&#xff0c;无向图&#xff0c;加边加两个&#xff0c;dfs输入两个参数变量&#xff0c;一个是当前深搜节点&#xff0c;另一个是父节点&#xff08;避免重复搜索父节点&#xff09;&#xff0c;恢复现场 ///首先完成数组模拟邻接表#include<iostream> #incl…

记一次 HTTPS 抓包分析和 SNI 的思考

日常听说 HTTPS 是加密协议&#xff0c;那现实中的 HTTPS 流量&#xff0c;是真的完全加密吗&#xff1f; ——答案是&#xff0c;不一定。原因嘛&#xff0c;抓个包就知道了。 我们用 curl 命令触发一下&#xff1a; curl -v https://s-api.37.com.cn/api/xxx * Trying 1…

python 常见数据类型和方法

不可变数据类型 不支持直接增删改 只能查 str 字符串 int 整型 bool 布尔值 None None型特殊常量 tuple 元组(,,,)回到顶部 可变数据类型&#xff0c;支持增删改查 list 列表[,,,] dic 字典{"":"","": ,} set 集合("",""…

Flutter 文件上传(七牛云)简单封装

前言&#xff1a;记录了七牛云上传图片的简单封装、若有不足 欢迎指正。 开始前准备&#xff1a; A、七牛sdk版本一定要和dart版本相对应&#xff08;推荐用any方式、让其自己去匹配&#xff09;&#xff1b; qiniu_flutter_sdk: any B、七牛上传文件所需的参数&#xff1a; …

GPIO实验

一、GPIO GPIO&#xff08;General-purpose input/output&#xff09;即通用型输入输出&#xff0c;GPIO可以控制连接在其之上的引脚实现信号的输入和输出 芯片的引脚与外部设备相连&#xff0c;从而实现与外部硬件设备的通讯、控制及信号采集等功能 LED实验步骤 最终目的&am…

windows 同时安装 Mysql 5.7 和8.0

下载链接 https://dev.mysql.com/downloads/mysql/ 推荐下载 MSI&#xff0c;可以通过图像化界面配置 8.1 版本 安装5.7 系统安装两个MySQL 怎么访问 都是mysql&#xff0c;所以环境变量 配置&#xff0c;只能一个生效&#xff0c;生效就是谁靠前谁生效 cmd 录入 services.m…

Linux用户管理

一、linux用户&#xff1a;username/UID Linux用户分为以下几种 root用户&#xff1a;UID为0&#xff0c;也称超级用户&#xff0c;权限最高。系统用户&#xff1a;UID为1~999&#xff0c;也称虚拟用户、伪用户、假用户&#xff0c;是系统自身拥有的用户&#xff0c;比如bin、…

SpringBoot+SSM实战<一>:打造高效便捷的企业级Java外卖订购系统

文章目录 项目简介项目架构功能模块管理端用户端 技术选型用户层网关层应用层数据层工具 项目优缺点结语 黑马程序员最新Java项目实战《苍穹外卖》&#xff1a;让你轻松掌握SpringBootSSM的企业级开发技巧项目简介 《苍穹外卖》是一款为餐饮企业&#xff08;餐厅、饭店&#x…

C++ 类的继承与派生

1.继承关系举例 交通工具的分类如下图所示&#xff1a; 这个分类树反映了交通工具的派生关系&#xff0c;最高层是抽象程度最高的&#xff0c;是最具有普遍和一般意义的概念&#xff0c;下层具有了上层的特性&#xff0c;同时加入了自己的新特征&#xff0c;而最下层是最为具…

[CKA]考试之PersistentVolumeClaims

由于最新的CKA考试改版&#xff0c;不允许存储书签&#xff0c;本博客致力怎么一步步从官网把答案找到&#xff0c;如何修改把题做对&#xff0c;下面开始我们的 CKA之旅 题目为&#xff1a; Task 创建一个名字为pv-volume的pvc&#xff0c;指定storageClass为csi-hostpath-…

HTML中元素和标签有什么区别?

聚沙成塔每天进步一点点 ⭐ 专栏简介⭐ 标签&#xff08;Tag&#xff09;⭐元素&#xff08;Element&#xff09;⭐ 写在最后 ⭐ 专栏简介 前端入门之旅&#xff1a;探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅&a…

Leetcode-每日一题【剑指 Offer 17. 打印从1到最大的n位数】

题目 输入数字 n&#xff0c;按顺序打印出从 1 到最大的 n 位十进制数。比如输入 3&#xff0c;则打印出 1、2、3 一直到最大的 3 位数 999。 示例 1: 输入: n 1输出: [1,2,3,4,5,6,7,8,9] 说明&#xff1a; 用返回一个整数列表来代替打印 n 为正整数 解题思路 前置知识 M…

kubernetes基于helm部署gitlab

kubernetes基于helm部署gitlab 这篇博文介绍如何在 Kubernetes 中使用helm部署 GitLab。 先决条件 已运行的 Kubernetes 集群负载均衡器&#xff0c;为ingress-nginx控制器提供EXTERNAL-IP&#xff0c;本示例使用metallb默认存储类&#xff0c;为gitlab pods提供持久化存储&…