MyBatis源码之前言—JDBC编码存在的问题和Mybatis的介绍

为了方便操作,我们在sjdwz_test数据库下建立一张表:

CREATE TABLE `t_student` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
`name` varchar(255) DEFAULT NULL COMMENT '名字',
`age` int(255) DEFAULT NULL COMMENT '年龄',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4;

数据如下:

实体类如下:

package com.sjdwz.db;

import lombok.*;

/**
* @Description 数据库实体
* @Created by 随机的未知
*/
@Data
@ToString
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Student {
private Long id;
private String name;
private Integer age;
}

JDBC操作数据库

我们先来回顾一下JDBC操作数据库的代码:

package com.sjdwz.jdbc;

import com.sjdwz.db.Student;

import java.sql.*;
import java.util.ArrayList;
import java.util.List; /**
* @Description JDBC操作数据库代码示例
* @Date 2023/12/14
* @Created by 随机的未知 sjdwz.com
*/
public class JDBCMain {
public static void main(String[] args) throws SQLException, ClassNotFoundException {
//数据库连接地址
String url = "jdbc:mysql://localhost:3306/sjdwz_test";
String user = "root";//用户名
String password = "1234567";//密码
//1.注册数据库驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取数据库连接对象Connection。
Connection conn = DriverManager.getConnection(url, user, password);
//3.创建Sql语句对象Statement,填写SQL语句
PreparedStatement preparedStatement = conn.prepareStatement("select * from t_student where `name` = ?; ");
//传入查询参数
preparedStatement.setString(1, "张三");
//4.执行SQL查询,返回结果集对象ResultSet
ResultSet resultSet = preparedStatement.executeQuery();
List<Student> studentList = new ArrayList<>();
//5.循环解析结果集,获取查询用户list集合
while (resultSet.next()) {
Student student = Student.builder()
.id(resultSet.getLong("id"))
.name(resultSet.getString("name"))
.age(resultSet.getInt("age"))
.build();
studentList.add(student);
}
//打印查询结果
System.out.println(studentList);
//6.关闭连接,释放资源
resultSet.close();//关闭结果集对象
preparedStatement.close();//关闭Sql语句对象
conn.close();//关闭数据库连接对象
}
}

运行截图如下:

这段代码主要有如下四点问题:

  1. 结果集解析复杂,列名硬编码,sql变化导致解析代码变化,系统不易维护;
  2. sql语句硬编码,数据库配置硬编码,难以维护;
  3. 频繁连接、释放数据库资源,没有用到池化思想,系统性能不高;
  4. prepareadStatement向占位符传参数存在硬编码,不易维护。

所以我们需要一个ORM框架,来解决这些痛点。我用的最多的ORM框架是MyBatis,我们就来从源码角度来分析它,看看MyBatis是怎么解决这些问题的。

MyBatis介绍

什么是MyBatis

  • MyBatis是一款优秀的持久层框架,它支持自定义SQL、存储过程以及高级映射。
  • MyBatis对JDBC封装使得开发者只需要关注SQL语句与业务本身即可,无需开发者处理加载驱动、获取连接、创建Statement等繁琐的过程。
  • MyBatis可以通过简单的XML或注解来配置和映射原始类型、接口和Java POJO为数据库中的记录。
  • MyBatis是一个实现了ORM思想的持久层框架。

什么是ORM?为什么说MyBatis是一个半ORM框架?

  • ORM:Object/Relation Mapping 对象/关系映射。
  • ORM思想:将数据库中的关系数据表映射为Java中的对象,把对数据表的操作转换为操作对象,实现面向对象编程。因此,ORM的目的是使得开发人员以面向对象的思想来操作数据库
  • MyBatis框架是一个半自动的ORM持久层框架,也可以在Java中实现类似insert(Student)的操作最终操作数据库,但是需要我们自己写SQL语句。

MyBatis操作数据库

项目结构截图如下:

在resources目录下创建mybatis-config.xml文件,内容如下:

<?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>
<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/sjdwz_test?useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="1234567"/>
</dataSource>
</environment>
</environments>
<mappers>
<!-- 加载sql映射文件-->
<mapper resource="StudentMapper.xml"/>
</mappers>
</configuration>

在resources目录下创建StudentMapper.xml文件,内容如下:

<?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="test">
<!-- id是指sql的唯一标识,resulttype是指返回值的类型-->
<select id="findListByName" resultType="com.sjdwz.db.Student" parameterType="string">
select * from t_student where `name` = #{name};
</select>
</mapper>

MyBatis操作数据库代码如下:

package com.sjdwz.mybatis;

import com.sjdwz.db.Student;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder; import java.io.IOException;
import java.io.InputStream;
import java.util.List; /**
* @Description Mybatis示例
* @Created by 随机的未知
*/
public class MybatisTest {
public static void main(String[] args) throws IOException {
//1.创建SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
//2.SqlSessionFactoryBuilder对象创建工厂对象
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
//3.工厂对象Factory打开SqlSession会话
SqlSession sqlSession = sqlSessionFactory.openSession();
//4.SqlSession会话对象执行SQL语句,findListByName(命名空间+查询语句唯一标识)
List<Student> studentList = sqlSession.selectList("test.findListByName","张三");
//5.打印查询结果
System.out.println(studentList);
//6.关闭sqlSession会话
sqlSession.close();
}
}

运行截图如下:

Mybatis配置和代码解决的问题

在前文,使用JDBC存在四个问题,而Mybatis就解决了这四个问题。

JDBC编码存在的第一个问题的解决

第一个问题是结果集解析复杂,列名硬编码,sql变化导致解析代码变化,系统不易维护;

MyBatis编码中我们不需要进行结果集解析,只需要在编码时指定sql即可,MyBatis会给我们结果;

List<Student> studentList = sqlSession.selectList("test.findListByName","张三");

JDBC编码存在的第二个问题的解决

第二个问题是sql语句硬编码,数据库配置硬编码,难以维护;

数据库的配置和sql语句,我们写到了xml文件,解决了硬编码的问题

JDBC编码存在的第三个问题的解决

第三个问题是频繁连接、释放数据库资源,没有用到池化思想,系统性能不高

MyBatis使用了池化思想,解决了这个问题;

JDBC编码存在的第四个问题的解决

第三个问题是prepareadStatement向占位符传参数存在硬编码,不易维护

我们在配置文件标签上写明了参数,并在代码中传入,避免了占位符的硬编码,解决了此问题。

总结

我们回顾了JDBC和MyBatis的编码方式,了解了JDBC编码存在的问题,并知道了MyBatis编码确实解决了这几个问题。

后面我们就来分析MyBatis源码了。

MyBatis源码之前言—JDBC编码存在的问题和Mybatis的介绍的更多相关文章

  1. Mybatis源码解析1—— JDBC

    在之前的文章中,我为大家介绍了 Mybatis 的详细用法,算是基础教程. 详细链接:Mybatis 基础教程 言归正传,只懂基础可不行,接下来将给大家带来高阶的源码解析教程,从浅入深,通过源码解析, ...

  2. 【Mybatis源码解析】- JDBC连接数据库的原理和操作

    JDBC连接数据库的原理和操作 JDBC即Java DataBase Connectivity,java数据库连接:JDBC 提供的API可以让JAVA通过API方式访问关系型数据库,执行SQL语句, ...

  3. MyBatis源码分析(七):动态代理(Mybatis核心机制)

    一.动态代理 动态代理是一种比较高级的代理模式,它的典型应用就是Spring AOP. 在传统的动态代理模式中,客户端通过ProxySubject调用RealSubject类的request( )方法 ...

  4. MyBatis源码分析(5)——内置DataSource实现

    @(MyBatis)[DataSource] MyBatis源码分析(5)--内置DataSource实现 MyBatis内置了两个DataSource的实现:UnpooledDataSource,该 ...

  5. MyBatis源码分析之环境准备篇

    前言 之前一段时间写了[Spring源码分析]系列的文章,感觉对Spring的原理及使用各方面都掌握了不少,趁热打铁,开始下一个系列的文章[MyBatis源码分析],在[MyBatis源码分析]文章的 ...

  6. 【MyBatis源码分析】环境准备

    前言 之前一段时间写了[Spring源码分析]系列的文章,感觉对Spring的原理及使用各方面都掌握了不少,趁热打铁,开始下一个系列的文章[MyBatis源码分析],在[MyBatis源码分析]文章的 ...

  7. 深入浅出Mybatis系列(三)---配置详解之properties与environments(mybatis源码篇)

    上篇文章<深入浅出Mybatis系列(二)---配置简介(mybatis源码篇)>我们通过对mybatis源码的简单分析,可看出,在mybatis配置文件中,在configuration根 ...

  8. MyBatis 源码分析 - 内置数据源

    1.简介 本篇文章将向大家介绍 MyBatis 内置数据源的实现逻辑.搞懂这些数据源的实现,可使大家对数据源有更深入的认识.同时在配置这些数据源时,也会更清楚每种属性的意义和用途.因此,如果大家想知其 ...

  9. MyBatis 源码分析 - 映射文件解析过程

    1.简介 在上一篇文章中,我详细分析了 MyBatis 配置文件的解析过程.由于上一篇文章的篇幅比较大,加之映射文件解析过程也比较复杂的原因.所以我将映射文件解析过程的分析内容从上一篇文章中抽取出来, ...

  10. MyBatis 源码分析 - 配置文件解析过程

    * 本文速览 由于本篇文章篇幅比较大,所以这里拿出一节对本文进行快速概括.本篇文章对 MyBatis 配置文件中常用配置的解析过程进行了较为详细的介绍和分析,包括但不限于settings,typeAl ...

随机推荐

  1. 候捷-C++程序设计(Ⅱ)兼谈对象模型

    目录 笔记参考 学习目标 转换函数与explicit pointer-like classes function-like classes 模板template 模板特化与偏特化 模板模板参数 引用( ...

  2. TTS 擂台: 文本转语音模型的自由搏击场

    对文本转语音 (text-to-speech, TTS) 模型的质量进行自动度量非常困难.虽然评估声音的自然度和语调变化对人类来说是一项微不足道的任务,但对人工智能来说要困难得多.为了推进这一领域的发 ...

  3. 09.Java数据算法

    好消息 博客笔记大汇总[15年10月到至今],包括Java基础及深入知识点,Android技术博客,Python学习笔记等等,还包括平时开发中遇到的bug汇总,当然也在工作之余收集了大量的面试题,长期 ...

  4. flutter版本的玩Android客户端

    flutter学习案例 目录介绍 00.项目下载与查看 01.项目介绍 02.项目优势 03.部分功能介绍 04.部分截图展示 05.版本更新 06.flutter系列博客 07.感谢 08.如何辨别 ...

  5. 基于PyQGIS实现遥感影像下载

    1. 引言 之前的文章:QGIS中下载遥感影像的Python代码片段 - 当时明月在曾照彩云归 - 博客园 (cnblogs.com),记述了在 QGIS 的 Python Console 中使用Py ...

  6. KingbaseES V8R6集群运维案例-- 备库数据库服务意外down分析

    案例说明: KingbaseES V8R6一主二备架构的集群,两个备库节点sys_log日志分别不同时间点收到'fast shutdown request'的日志信息,导致备库数据库服务down,需要 ...

  7. KingbaseES V8R6 集群环境备库不结束旧事务快照将影响主库的vacuum操作

    前言 昨天同事遇到了一个有关vacuum的典型问题. V8R6读写分离集群环境,一主多备. 版本:kingbaseesv008r006c004 问题现象: 主库日常巡检发现日志大量记录: waring ...

  8. 【已解决】mysql8.0安装报错 error: Found option without preceding group in config file:

    D:\Program Files (x86)\mysql-8.0.13-winx64\mysql-8.0.13-winx64 在此路径下找到my.ini(在个人安装的路径下) 另存为ANSI编码:

  9. #拓扑排序#洛谷 4645 [COCI2006-2007 Contest#3] BICIKLI

    题目 这个地方有 \(n\) 个城镇,从 \(1\sim n\) 编号, 其中有 \(m\) 条单向道路连接它们. 比赛将在 \(1\) 号城镇开始并在 \(2\) 号城镇结束. 主办方想知道,一共有 ...

  10. AVX256加速矩阵乘法

    最近打PKU的HPCGAME留下的代码,速度不是很快 const int BLOCK_SIZE = 1024; const int BLOCK_SIZE2 = 256; inline static v ...