一文教你如何手写一个mybatis自定义框架

2024-06-12 11:12

本文主要是介绍一文教你如何手写一个mybatis自定义框架,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 本文主要介绍原始jdbc操作有哪些弊端等方面说明持久层框架出现的原因,另一方面介绍如何自己仿写一个mybatis框架。学习完本文相信你对日常使用的mybatis框架有更深的理解!

简介

说到持久层框架,我们很快能想到hibernate、mybatis。Hibernate是全自动的持久层框架,而mybatis则是半自动的。那么两者有何区别?下面先简单认识一下这两个框架的异同,以便更好的理解下面阐述的自定义持久层框架的设计思想,毕竟下面的自定义框架实际就是通过阅读mybatis源码,取其核心设计,去掉细枝旁叶而设计的一个半自动持久层框架。

ORM全称Object/Relation Mapping:表示对象-关系映射的缩写。

Hibernate:全自动的持久层ORM框架。Hibernate是一个开源的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO(Plain Ordinary Java Object)与数据库表建立映射关系,是一个全自动的ORM框架,hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。

Mybatis:MyBatis 是一款优秀的半自动持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO为数据库中的记录。

使用 Hibernate 查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取,所以它是全自动的。而 MyBatis 在查询关联对象或关联集合对象时,需要手动编写 sql 来完成,所以,称之为半自动 ORM 映射工具。

既然无论是全自动的hibernate,或是半自动的mybatis,其本质都是对JDBC进行了封装,使Java程序员可以使用对象编程思维来操纵数据库。

下面我们不妨看看使用JDBC编程是怎样的,直接使用JDBC编程会有什么问题,找到问题,解决问题,然后提出针对问题的解决方案。

jdbc操作存在的问题

一个使用原始jdbc对数据进行查询的案例

package com.kmning.wallet.jdbc;import com.kmning.wallet.jdbc.pojo.User;import java.sql.*;
import java.util.ArrayList;
import java.util.List;/*** @author kangming.ning* @date 2021/5/2 9:16*/
public class JdbcQueryDemo {public static void main(String[] args) {Connection connection=null;PreparedStatement preparedStatement=null;ResultSet resultSet =null;try {//加载数据库驱动//Class.forName("com.mysql.jdbc.Driver");//过驱动管理类获取数据库链接connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/yourdb?characterEncoding=UTF-8&serverTimezone=Asia/Shanghai", "root", "root");//编写sql语句String sql="select * from user where username=? or telphone=?";//获取预处理statementpreparedStatement = connection.prepareStatement(sql);//设置参数,第一个参数为sql语句中参数的序号(从1开始),第二个参数为设置的参数值preparedStatement.setString(1,"aa");preparedStatement.setString(2,"666");//向数据库发出sql执行查询,查询出结果集resultSet = preparedStatement.executeQuery();//遍历结果集,封装数据List<User> userList=new ArrayList<>(10);while (resultSet.next()){int id = resultSet.getInt("id");String username = resultSet.getString("username");String telphone = resultSet.getString("telphone");//封装结果集User user = new User();user.setId(id);user.setUsername(username);user.setTelphone(telphone);userList.add(user);}System.out.println(userList);}catch (Exception e){e.printStackTrace();}finally {//释放资源if (resultSet!=null){try {resultSet.close();} catch (SQLException e) {e.printStackTrace();}}if (preparedStatement!=null){try {preparedStatement.close();} catch (SQLException e) {e.printStackTrace();}}if (connection!=null){try {connection.close();} catch (SQLException e) {e.printStackTrace();}}}}
}
​代码非常简单且常规,JDBC操作无非都类似于上面的套路。通过驱动获取数据库连接,通过PreparedStatement预编译SQL语句,设置参数,然后向数据库发出sql执行查询,查询出结果集,遍历结果集,将结果集封装到POJO对象集合。当然,最后还得将相关资源释放。

但在实际的企业应用中,数据库的表少则几十个,多则几百个,如果使用类似于上述的方式去操作数据库,不仅前期开发工作巨大,而且后期的维护也将是一场灾难。那么上述代码存在哪些问题?让我们带着疑问对代码进行分析,然后找出问题所在,然后找到解决方案去解决它们。

以上代码存在的问题:

  • 数据库配置信息存在硬编码

  • 数据库连接创建、释放频繁造成系统资源浪费,从而影响系统性能

  • Sql语句在代码中硬编码,造成代码不易维护,实际应用中sql变化的可能较大,sql变动需要改变java代码

  • 使用preparedStatement向占位符号传参数存在硬编码,因为sql语句的where条件不一定,可能多也可能少,修改sql还要修改代码,系统不易维护

  • 对结果集解析存在硬编码(查询列名),sql变化导致解析代码变化,系统不易维护,如果能将数据库记录封装成pojo对象解析比较方便

解决思路:

  • 数据库配置信息提供配置文件,避免改动连接等配置信息需要重新编译代码

  • 使用数据库连接池初始化连接资源

  • 将sql语句、设置参数、获取结果集参数抽取到xml配置文件中

  • 使用反射、内省等底层技术,自动将实体与表进行属性与字段的自动映射

问题找到了,也整理出了解决思路,那么就可以着手设计框架了。

自定义mybatis框架

我们整理出了解决思路,接下来需要编写一个通用的解决方案,也就是框架,去解决问题。下面我们整理一下实现这样一个框架需要去做哪些工作。

首先是自定义框架肯定是独立的一个jar,然后提供给客户端使用。我们可以将开发工作分为两部分,一是框架需要做哪些东西,二是使用端(项目)需要做哪些东西。为了描述与理解方便,下面称框架端为mybatis-custom框架。

mybatis-custom框架负责对jdbc进行封装,提供基本操作接口,并对结果集和pojo实体进行映射,而客户端(项目)则需要提供数据库配置信息、sql配置信息(如UserMapper.xml)。使用端提供xxMapper.xml,意味着对sql的编写的控制权还是属于用户的(半自动映射框架)。

使用端

提供两部分配置信息:一是数据库配置信息。二是sql mapper配置信息,mapper文件定义了sql语句、参数类型、返回值类型、结果返回类型等信息。

使用配置文件来提供这两部分配置信息

  • sqlMapConfig.xml:存放数据库配置信息、同时存放mapper.xml的全路径(这样在方便在解析sqlMapConfig时直接解析mapper.xml,相关信息保存到Configuration)。样例如下

    <configuration>       <!--数据库配置信息-->   <dataSource>       <property name="driverClass" value="com.mysql.jdbc.Driver"></property>       <property name="jdbcUrl" value="jdbc:mysql:///yourdb?serverTimezone=Asia/Shanghai"></property>       <property name="username" value="root"></property>       <property name="password" value="root"></property>   </dataSource>
    ​   <!--存放mapper.xml的全路径-->   <mapper resource="UserMapper.xml"></mapper>   <mapper resource="ProductMapper.xml"></mapper></configuration>

  • mapper.xml:存放sql配置信息。样例如下

    <mapper namespace="com.kmning.mybatis.test.dao.UserDao">
    ​   <!--sql的唯一标识:namespace.id来组成 : statementId-->   <select id="findAll" resultType="com.kmning.mybatis.test.pojo.User" >       select * from user   </select>   <select id="findByCondition" resultType="com.kmning.mybatis.test.pojo.User" parameterType="com.kmning.mybatis.test.pojo.User">       select * from user where id = #{id} and username = #{username}   </select>
    ​   <update id="updateUserById" resultType="java.lang.Integer" parameterType="com.kmning.mybatis.test.pojo.User">       UPDATE `user` SET username=#{username},telphone=#{telphone} WHERE id=#{id};   </update>
    ​   <insert id="insertUser" resultType="java.lang.Integer" parameterType="com.kmning.mybatis.test.pojo.User">       INSERT INTO `user` VALUES(#{id},#{username},#{telphone});   </insert>
    ​   <delete id="deleteUserById" resultType="java.lang.Integer" parameterType="com.kmning.mybatis.test.pojo.User">       DELETE FROM `user` WHERE id=#{id};   </delete>
    </mapper>

自定义持久层框架端

创建框架工程,引入相关maven依赖,根据上面的分析,框架需要解析xml,用连接池解决连接创建关闭频繁问题,那么引入相关依赖如下

<dependency>           <groupId>dom4j</groupId>           <artifactId>dom4j</artifactId>           <version>1.6.1</version>       </dependency>       <dependency>           <groupId>jaxen</groupId>           <artifactId>jaxen</artifactId>           <version>1.2.0</version>       </dependency>       <dependency>           <groupId>mysql

这篇关于一文教你如何手写一个mybatis自定义框架的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1054057

相关文章

Spring Boot + MyBatis Plus 高效开发实战从入门到进阶优化(推荐)

《SpringBoot+MyBatisPlus高效开发实战从入门到进阶优化(推荐)》本文将详细介绍SpringBoot+MyBatisPlus的完整开发流程,并深入剖析分页查询、批量操作、动... 目录Spring Boot + MyBATis Plus 高效开发实战:从入门到进阶优化1. MyBatis

MyBatis 动态 SQL 优化之标签的实战与技巧(常见用法)

《MyBatis动态SQL优化之标签的实战与技巧(常见用法)》本文通过详细的示例和实际应用场景,介绍了如何有效利用这些标签来优化MyBatis配置,提升开发效率,确保SQL的高效执行和安全性,感... 目录动态SQL详解一、动态SQL的核心概念1.1 什么是动态SQL?1.2 动态SQL的优点1.3 动态S

使用Sentinel自定义返回和实现区分来源方式

《使用Sentinel自定义返回和实现区分来源方式》:本文主要介绍使用Sentinel自定义返回和实现区分来源方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Sentinel自定义返回和实现区分来源1. 自定义错误返回2. 实现区分来源总结Sentinel自定

一文教你如何将maven项目转成web项目

《一文教你如何将maven项目转成web项目》在软件开发过程中,有时我们需要将一个普通的Maven项目转换为Web项目,以便能够部署到Web容器中运行,本文将详细介绍如何通过简单的步骤完成这一转换过程... 目录准备工作步骤一:修改​​pom.XML​​1.1 添加​​packaging​​标签1.2 添加

Spring Boot结成MyBatis-Plus最全配置指南

《SpringBoot结成MyBatis-Plus最全配置指南》本文主要介绍了SpringBoot结成MyBatis-Plus最全配置指南,包括依赖引入、配置数据源、Mapper扫描、基本CRUD操... 目录前言详细操作一.创建项目并引入相关依赖二.配置数据源信息三.编写相关代码查zsRArly询数据库数

Python Dash框架在数据可视化仪表板中的应用与实践记录

《PythonDash框架在数据可视化仪表板中的应用与实践记录》Python的PlotlyDash库提供了一种简便且强大的方式来构建和展示互动式数据仪表板,本篇文章将深入探讨如何使用Dash设计一... 目录python Dash框架在数据可视化仪表板中的应用与实践1. 什么是Plotly Dash?1.1

基于Flask框架添加多个AI模型的API并进行交互

《基于Flask框架添加多个AI模型的API并进行交互》:本文主要介绍如何基于Flask框架开发AI模型API管理系统,允许用户添加、删除不同AI模型的API密钥,感兴趣的可以了解下... 目录1. 概述2. 后端代码说明2.1 依赖库导入2.2 应用初始化2.3 API 存储字典2.4 路由函数2.5 应

Python GUI框架中的PyQt详解

《PythonGUI框架中的PyQt详解》PyQt是Python语言中最强大且广泛应用的GUI框架之一,基于Qt库的Python绑定实现,本文将深入解析PyQt的核心模块,并通过代码示例展示其应用场... 目录一、PyQt核心模块概览二、核心模块详解与示例1. QtCore - 核心基础模块2. QtWid

一文教你Python引入其他文件夹下的.py文件

《一文教你Python引入其他文件夹下的.py文件》这篇文章主要为大家详细介绍了如何在Python中引入其他文件夹里的.py文件,并探讨几种常见的实现方式,有需要的小伙伴可以根据需求进行选择... 目录1. 使用sys.path动态添加路径2. 使用相对导入(适用于包结构)3. 使用pythonPATH环境

如何自定义Nginx JSON日志格式配置

《如何自定义NginxJSON日志格式配置》Nginx作为最流行的Web服务器之一,其灵活的日志配置能力允许我们根据需求定制日志格式,本文将详细介绍如何配置Nginx以JSON格式记录访问日志,这种... 目录前言为什么选择jsON格式日志?配置步骤详解1. 安装Nginx服务2. 自定义JSON日志格式各