MyBatis 源码学习 | Day 1 | 了解 MyBatis

什么是 MyBatis

在对一项技术进行深入学习前,我们应该先对它有个初步的认识。MyBatis 是一个 Java 持久层框架,用于简化数据库的操作。它通过 XML 或注解的方式配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
在此之前,如果直接使用 JDBC 进行数据库操作,我们也可以轻松完成一些简单的任务,但是当数据量越来越大,业务越来越复杂,这种方式会带来很多困难和挑战,比如:

  1. SQL语句的硬编码:使用JDBC时,SQL语句通常是直接在Java代码中编写的,这可能导致代码和SQL逻辑的紧密耦合,使得维护和升级变得困难。
  2. 结果集的处理繁琐:JDBC要求开发者手动处理结果集(ResultSet),包括从结果集中检索数据、将其转换为Java对象等。这个过程可能相当繁琐,特别是对于复杂的数据结构或大量数据的处理。
  3. 数据库连接的频繁开启与关闭:JDBC中,数据库连接(Connection)是宝贵的资源,需要妥善管理
  4. 事务管理复杂:在使用JDBC进行数据库操作时,事务的管理(如提交和回滚)需要开发者手动控制,这要求开发者对数据库事务有深入的理解。
  5. 动态SQL语句构建困难:在复杂的业务逻辑中,经常需要根据不同的条件动态地构建SQL语句。直接使用JDBC时,这通常需要编写复杂的逻辑来拼接SQL字符串,这不仅容易出错,还可能增加SQL注入的风险。

下面将会展示使用 JDBC 操作 MySQL 数据库

使用 JDBC 操作数据库

首先,使用 Maven 创建项目,并引入相关依赖

<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.34</version><scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/com.mysql/mysql-connector-j -->
<dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><version>8.4.0</version>
</dependency>

接下来,在本地连接数据库,建立测试数据表 user 并插入测试数据

# 创建测试数据库 mybatis_learn
create database if not exists `mybatis_learn`;
use `mybatis_learn`;
# 创建user表
create table if not exists `user`
(`id`       bigint primary key not null auto_increment comment 'id',`username` varchar(20)        not null comment '用户名',`password` varchar(20)        not null comment '密码'
);
# 插入数据
insert into `user`(`username`, `password`)
values ('admin', '123456');
insert into `user`(`username`, `password`)
values ('user1', '123456');
insert into `user`(`username`, `password`)
values ('user2', '123456');

可以看到,数据已经插入成功
在这里插入图片描述
接下来我们还要进行一些准备工作,要创建一个 User 实体类来对应 user 表中的各个数据,方便我们后续进行解析

package com.nx.domain;import lombok.Data;/*** user实体类** @author nx-xn2002* @date 2024-08-02*/
@Data
public class User {private Long id;private String username;private String password;
}

接下来,通过加载驱动 -> 获取连接 -> 获取statement并构造sql语句 -> 执行查询并获取结果集 -> 解析结果集 -> 打印结果 -> 关闭连接这一系列行为,我们可以将刚刚创建的数据库里的内容查询出来

/*** 直接使用 jdbc 操作数据库** @author nx-xn2002* @date 2024-08-02*/
public class QueryWithJdbc {static String url = "jdbc:mysql://localhost:3306/mybatis_learn";static String userName = "root";static String password = "123456";public static void main(String[] args) throws ClassNotFoundException, SQLException {// 加载驱动Class.forName("com.mysql.cj.jdbc.Driver");// 获取连接Connection connection = DriverManager.getConnection(url, userName, password);// 获取预编译的 statementPreparedStatement preparedStatement = connection.prepareStatement("select * from user");// 执行查询ResultSet resultSet = preparedStatement.executeQuery();List<User> users = new ArrayList<>();// 遍历结果集while (resultSet.next()) {User user = new User();user.setId(resultSet.getLong("id"));user.setUsername(resultSet.getString("username"));user.setPassword(resultSet.getString("password"));users.add(user);}users.forEach(System.out::println);connection.close();}
}

查询结果
可以看到,虽然使用 JDBC 可以正常操作数据库,但是还是存在较多问题,比如每次获取结果,都要去手动进行实体类对象的值的设定,代码中存在大量的硬编码的 sql 语句,频繁开启关闭数据库连接,这些都会大大降低我们的开发效率。
对于以上问题,MyBatis 在 java 和 sql 之间提供了更灵活的映射方案,MyBatis 将 sql 语句和方法实现,直接写到 xml 文件中,实现和 java 程序解耦

MyBatis 操作数据库

首先,我们引入 MyBatis 依赖

<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.16</version>
</dependency>

要想正常使用 MyBatis,我们需要几个文件,首先是配置文件src/main/resources/mybatis-config.xml,在这里面我们可以配置数据库连接以及选定项目中的 xml 映射文件,如下所示

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configurationPUBLIC "-//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.cj.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/mybatis_learn"/><property name="username" value="root"/><property name="password" value="123456"/></dataSource></environment></environments><!-- 引入映射文件,如果有多个文件,则在此处添加 --><mappers>--><mapper resource="UserMapper.xml"/></mappers>
</configuration>

接下来就是刚刚提到的映射文件,此处也就是配置文件中的UserMapper.xml,在这里面可以定义一系列的 sql 语句和对应的方法名,此处我就写了listAll,以此完成前面的查找所有用户的功能

<?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="com.nx.mapper.UserMapper"><!-- 定义查询所有用户的 SQL 语句--><select id="listAll" resultType="com.nx.domain.User">SELECT * FROM user;</select>
</mapper>

可以看到,要想让 MyBat​is 能够完成 ORM 的转化工作,我们还需要定义一个实体类,在这里我们复用前面创建的 com.nx.domain.User
接下来要创建一个与 UserMapper.xml 映射文件对应的映射接口,这样才能正常进行调用,这个接口就是映射文件中<mapper namespace="com.nx.mapper.UserMapper">里提到的 UserMapper 接口

package com.nx.mapper;import com.nx.domain.User;
import org.apache.ibatis.annotations.Mapper;import java.util.List;/*** user mapper** @author nx-xn2002* @date 2024-08-02*/
@Mapper
public interface UserMapper {/*** 查询所有用户** @return {@link List }<{@link User }>* @author nx-xn2002*/List<User> listAll();
}

接口中我们需要创建与映射文件中相对应的方法声明,在这里,@Mapper注解仅作为标识,没有特殊作用,只有在 Spring Boot 等项目中具有实际作用。

接下来我们可以写一个简单程序来检验一下刚刚完成的内容

package com.nx;import com.nx.domain.User;
import com.nx.mapper.UserMapper;
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;/*** 使用 MyBatis 操作数据库** @author nx-xn2002* @date 2024-08-02*/
public class QueryWithMyBatis {public static void main(String[] args) throws IOException {// 加载核心配置文件路径String resource = "mybatis-config.xml";//通过SqlSessionFactor的openSqlSession()方法获取SqlSession对象InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);SqlSession sqlSession = sqlSessionFactory.openSession();//使用SqlSession.getMapper()来获取UserMapper接口对象UserMapper mapper = sqlSession.getMapper(UserMapper.class);//调用接口方法List<User> users = mapper.listAll();users.forEach(System.out::println);sqlSession.close();}
}

打印结果如下:
在这里插入图片描述
可以看到,在刚刚的代码里,我们已经成功完成了 java 与 sql 语句的解耦合,同时,项目中可以很轻松的获取到查询结果的实体类对象,大大减少了冗余代码。以上就是 MyBatis 的简单应用。

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

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

相关文章

如何理解复信号z的傅里叶变换在频率v<0的时候恒为0,是解析信号

考虑例子2.12.1的说法。 首先我尝试解释第二个说法。需要注意一个事实是 实函数f的傅里叶变换F的实部是偶函数&#xff0c;虚部是奇函数。如图所示&#xff1a; 注意的是这个图中虽然是离散傅里叶变换的性质&#xff0c;但是对于一般的傅里叶变换的性质是适用的。 推导过程如下…

5款免费写作生成软件,自动生成原创文章很简单

在人工智能时代的今天&#xff0c;创作者面对写作不再是一件令人望而生畏的事情。随着AI技术的不断发展&#xff0c;涌现出了许多优秀的免费写作生成软件&#xff0c;让自动生成原创文章变得轻松简单。以下为大家详细介绍5款备受赞誉的免费写作生成软件&#xff0c;下面跟随小编…

深度学习DeepLearning Inference 学习笔记

神经网络预测 术语 隐藏层神经元多层感知器 神经网络概述 应当选择正确的隐藏层数和每层隐藏神经元的数量&#xff0c;以达到这一层的输出是下一层的输入&#xff0c;逐层变得清晰&#xff0c;最终输出数据的目的。 在人脸识别的应用中&#xff0c;我们将图片视作连续的像…

pytest测试框架之http协议接口测试

1 接口测试 日常测试中接口测试是一项重要的工作&#xff0c;尤其是http协议的接口测试更加普遍,比如一些常用的测试框架或者工具&#xff08;robotframework框架&#xff0c;testng框架&#xff0c;postman等&#xff09;都支持http接口的测试&#xff0c;而这节内容主要介绍…

【PythonCode】力扣Leetcode36~40题Python版

【PythonCode】力扣Leetcode36~40题Python版 前言 力扣Leetcode是一个集学习、刷题、竞赛等功能于一体的编程学习平台&#xff0c;很多计算机相关专业的学生、编程自学者、IT从业者在上面学习和刷题。 在Leetcode上刷题&#xff0c;可以选择各种主流的编程语言&#xff0c;如C…

使用 Python 确保结构在被释放后被垃圾回收

在 Python 中&#xff0c;确保对象在不再使用时被垃圾回收是很重要的。Python 的垃圾回收机制基于引用计数&#xff0c;并配有一个循环垃圾回收器&#xff0c;以处理引用循环。 以下就是一些确保对象被正确垃圾回收的技巧和方法&#xff1a; 1、问题背景 在 Python 中&#x…

“八股文”:程序员的福音还是梦魇?

——一场关于面试题的“代码战争” 在程序员的世界里&#xff0c;“八股文”这个词儿可谓是“如雷贯耳”。不&#xff0c;咱们可不是说古代科举考试中的那种八股文&#xff0c;而是指程序员面试中的那些固定套路的题目。如今&#xff0c;各大中小企业在招聘程序员时&#xff0…

59在Linux中加docker中加mysql,tomcat,redis

一、引言 1.1 环境不一致 我本地运行没问题啊&#xff1a;由于环境不一致&#xff0c;导致相同的程序&#xff0c;运行结果却不一致。 1.2 隔离性 哪个哥们又写死循环了&#xff0c;怎么这么卡&#xff1a;在多用户的操作系统下&#xff0c;会因为其他用户的操作失误影响到你自…

Logistic回归

Logistic回归模型&#xff1a; 适用于二分类或多分类问题&#xff0c;样本特征是数值型&#xff08;否则需要转换为数值型&#xff09; 策略&#xff1a;极大似然估计 算法&#xff1a;随机梯度 或 BFGS算法&#xff08;改进的拟牛顿法&#xff09; 线性回归表达式&#xf…

队列的基本运算(顺序,环形,链式)

以下分别介绍了顺序队列&#xff0c;环形队列&#xff0c;链式队列的基本运算。主要有五种基本运算&#xff1a;1.初始化队列&#xff0c;2.销毁队列&#xff0c;3.判断队列是否为空&#xff0c;4.进队列&#xff0c;5.出队。 目录 顺序队列 环形队列 链式队列 顺序队列与环…

upload-labs靶场练习

文件上传函数的常见函数&#xff1a; 在PHP中&#xff0c;‌文件上传涉及的主要函数包括move_uploaded_file(), is_uploaded_file(), get_file_extension(), 和 mkdir()。‌这些函数共同协作&#xff0c;‌使得用户可以通过HTTP POST方法上传文件&#xff0c;‌并在服务器上保存…

pycharm安装与配置Pyqt5

pycharm安装与配置Pyqt5 1、创建项目、虚拟环境 打开pycharm&#xff0c;File->New Project 2、安装pyqt5库 在pycharm下方Terminal终端窗口输入&#xff1a; pip install PyQt5 -i https://pypi.douban.com/simple pip install PyQt5-tools -i https://pypi.douban.c…

模拟实现strcmp,判断二个字符串是否相等

1.判断二个字符串是否相等&#xff0c;可以模仿strcmp.当二个字符串相等的时候ruturn 0.,当二个字符串小于时返回为小于0&#xff0c;当二个字符串大于时返回为大于0。const为不可以更改。 //方法一 int my_strcmp(const char* arr1, const char* arr2) {assert(arr1 &&…

CFA FRM原創講義和視頻等備考全部資料內容,順便征求建議

大家好&#xff0c;我是小伯&#xff0c; 曾經我也很喜歡上這個壇子查資料&#xff0c;好多年過去&#xff0c;現在論壇蠻雕零的很感慨。我和幾個朋友原創作了一些CFA一級二級三級和FRM一級二級雙語中英文的課件、視頻、資料&#xff0c; 是我們從2024年起一起合作的一個以自學…

C语言 | Leetcode C语言题解之第316题去除重复字母

题目&#xff1a; 题解&#xff1a; char* removeDuplicateLetters(char* s) {int vis[26], num[26];memset(vis, 0, sizeof(vis));memset(num, 0, sizeof(num));int n strlen(s);for (int i 0; i < n; i) {num[s[i] - a];}char* stk malloc(sizeof(char) * 27);int stk…

算法学习day27

一、寻找重复数(链表中找环) 给定一个包含 n 1 个整数的数组 nums &#xff0c;其数字都在 [1, n] 范围内&#xff08;包括 1 和 n&#xff09;&#xff0c;可知至少存在一个重复的整数。 假设 nums 只有 一个重复的整数 &#xff0c;返回 这个重复的数 。 题意&#xff1a…

[Git][认识Git]详细讲解

目录 1.什么是仓库&#xff1f;2.认识工作区、暂存区、版本库3.认识 .git1.index2.HEAD && master3.objects4.总结 1.什么是仓库&#xff1f; 仓库&#xff1a;进⾏版本控制的⼀个⽂件⽬录 2.认识工作区、暂存区、版本库 工作区&#xff1a;在电脑上写代码或⽂件的⽬录…

Java Excel复杂表头,表头合并单元格

Java Excel复杂表头&#xff0c;表头合并单元格 效果预览 一、maven依赖 <!--操作excel --><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>2.1.1</version><scope>test</…

【C++标准模版库】vector的介绍及使用

vector 一.vector的介绍二.vector的使用1.vector 构造函数2.vector 空间增长3.vector 增删查改4.vector 迭代器的使用1.正向迭代器2.反向迭代器 5.victor 迭代器失效问题&#xff08;重点&#xff09; 三.vector不支持 流提取与流插入四.vector存储自定义类型1.存储string2.存储…

大数据环境安装Elasticsearch Kibana可视化

1、用yum安装&#xff0c;配置仓库和镜像。 2、用离线软件包&#xff0c;rpm安装。 服务器环境CentOS7.9 因为云安装&#xff0c;配置镜像版本一直没有成功&#xff0c;改为直接下载软件安装。 官方网址&#xff1a;https://www.elastic.co/cn/downloads/elasticsearch 因为要…