mybatis源码阅读系列(一)

news2024/11/18 18:25:19

源码下载

mybatis

初识mybatis

MyBatis 是一个优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解用于配置和原始映射,将接口和 Java 的 POJOs(Plain Old Java Objects)映射成数据库中的记录。
MyBatis 的几个主要特点:

  1. 支持定制化 SQL、存储过程和高级映射:MyBatis 主要管理 SQL 语句的运行,让开发者可以专注于 SQL 语句本身,而不是花费精力处理 JDBC 等数据库连接相关的代码。
  2. 灵活的映射规则:MyBatis 提供了很多灵活的映射规则,比如一对一、一对多、多对多等复杂关系都可以通过简单的 XML 配置实现。
  3. 松耦合:MyBatis 不会像一些传统的 ORM 框架那样强迫你使用某种编程模型,它允许你使用简单的 XML 或注解来配置 SQL 语句和映射关系,不会强制你抽象出 POJOs。
  4. 易于上手和集成:MyBatis 易于理解和实施,它可以很容易地集成到各种应用之中。
  5. 动态 SQL:MyBatis 提供了强大的动态 SQL 功能,可以方便地实现复杂的查询和操作。
  6. 可定制 SQL 执行:MyBatis 允许自定义 SQL 执行语句,提供了包括插件在内的多种方式来优化 SQL 的执行。
  7. 丰富的映射标签:MyBatis 提供了丰富的映射标签,使得数据库操作更加灵活、方便。
  8. 良好的支持性:MyBatis 支持多种数据库,如 MySQL、Oracle、SQL Server、H2、Sqlite 等。
    MyBatis 的使用步骤大致如下:
  9. 配置 MyBatis:通过 SQL 映射文件或注解来配置 SQL 语句。
  10. 创建会话工厂(SqlSessionFactory):通过配置文件或代码来创建 SqlSessionFactory。
  11. 创建 SQL 会话(SqlSession):利用 SqlSessionFactory 来创建 SQL 会话。
  12. 执行操作:通过 SQL 会话执行定义好的 SQL 语句。
  13. 处理结果:根据执行的 SQL 语句处理结果集。
  14. 关闭会话:操作完成后关闭 SQL 会话。
    MyBatis 框架在国内外都有广泛的应用,是 Java 开发中常用的一种数据库操作框架。

原生jdbc操作数据库

原生 JDBC(Java Database Connectivity)是指 Java 数据库连接,它是一个用于 Java 程序和各种数据库之间进行交互的 API。JDBC 提供了一种标准方法来访问数据库,允许 Java 应用程序以一种统一的方式与不同的数据库进行通信。

package com.wyl.mybatis.service;

import java.sql.*;

/**
 * @Description
 * @Author WuYiLong
 * @Date 2024/2/26 11:36
 */
public class JdbcService {

    /**
     * 数据库链接
     */
    private static final String url = "jdbc:mysql://localhost:3306/blog?zeroDateTimeBehavior=CONVERT_TO_NULL&useUnicode=true&characterEncoding=utf-8&autoReconnect=true&serverTimezone=GMT%2B8";

    /**
     * 用户名
     */
    private static final String username = "root";

    /**
     * 密码
     */
    private static final String  password = "123456";

    public static void main(String[] args) {
        try {
            // 加载所需的 JDBC 驱动,这通常是通过调用 Class.forName() 方法来完成的
            Class.forName("com.mysql.cj.jdbc.Driver");
            // 使用 DriverManager.getConnection() 方法建立与数据库的连接。
            Connection connection = DriverManager.getConnection(url, username, password);
            // 创建一个 Statement 或 PreparedStatement 对象来执行 SQL 语句。
            String sql = "SELECT * FROM `b_expert` limit 10;";
            PreparedStatement preparedStatement = connection.prepareStatement(sql);
            preparedStatement.executeQuery(sql);
            // 如果是查询操作,执行 executeQuery() 方法,并处理返回的 ResultSet。
            ResultSet resultSet = preparedStatement.executeQuery(sql);
            // 通过遍历,输出数据
            while (resultSet.next()) {
                System.out.println("专家名称:"+resultSet.getString("name"));
            }
            // 关闭 ResultSet、Statement 和 Connection,以释放数据库资源。
            resultSet.close();
            preparedStatement.close();
            connection.close();
        } catch (SQLException | ClassNotFoundException throwables) {
            System.out.println(throwables.getMessage());
        }
    }
}

image.png

mybatis操作数据库

数据表设计

CREATE TABLE `d_full_city` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `name` varchar(255) DEFAULT NULL COMMENT '名称',
  `code` varchar(255) DEFAULT NULL COMMENT '区域码',
  `full_name` varchar(255) DEFAULT NULL COMMENT '全名称',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=46476 DEFAULT CHARSET=utf8mb4 COMMENT='省市区-字典';

实体类

package com.wyl.mybatis.entity;

/**
 * @Description 省市区-字典
 * @Author wuyilong
 * @Date 2024-02-26
 */
public class FullCity {

    private static final long serialVersionUID = 1L;

    /**
     * 主键ID
     */
    private Long id;

    /**
     * 名称
     */
    private String name;

    /**
     * 区域码
     */
    private String code;

    /**
     * 全名称
     */
    private String fullName;

    public static long getSerialVersionUID() {
        return serialVersionUID;
    }

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getCode() {
        return code;
    }

    public void setCode(String code) {
        this.code = code;
    }

    public String getFullName() {
        return fullName;
    }

    public void setFullName(String fullName) {
        this.fullName = fullName;
    }
}

mapper接口

package com.wyl.mybatis.mapper;

import com.wyl.mybatis.entity.FullCity;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

/**
* @Description 省市区-字典
* @Author wuyilong
* @Date 2024-02-26
*/
@Mapper
public interface FullCityMapper {

    /**
     * 根据名称查询
     * @param name
     * @return
     */
    FullCity selectByName(@Param("name") String name);
}

mapper.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="com.wyl.mybatis.mapper.FullCityMapper">

  <!-- 通用查询映射结果 -->
  <resultMap id="BaseResultMap" type="com.wyl.mybatis.entity.FullCity">
    <id column="id" property="id"/>
    <result column="name" property="name"/>
    <result column="code" property="code"/>
    <result column="full_name" property="fullName"/>
  </resultMap>

  <select id="selectByName" resultType="com.wyl.mybatis.entity.FullCity">
    select * from d_full_city where name = #{name}
  </select>


</mapper>

mybatis的配置文件

<?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>
    <!-- 属性:定义配置外在化 -->

    <properties resource="mybatis-mysql.properties">
        <property name="username" value="root"/>
        <property name="password" value="root"/>
        <property name="driver" value=""/>
        <property name="url" value=""/>
    </properties>
    <!-- 设置:定义mybatis的一些全局性设置 -->
    <settings>
        <!-- 具体的参数名和参数值 -->
        <setting name="cacheEnabled" value="true"/>
<!--        <setting name="lazyLoadingEnabled" value="true"/>-->
<!--        <setting name="multipleResultSetsEnabled" value="true"/>-->
<!--        <setting name="useColumnLabel" value="true"/>-->
<!--        <setting name="useGeneratedKeys" value="false"/>-->
<!--        <setting name="autoMappingBehavior" value="PARTIAL"/>-->
<!--        <setting name="defaultExecutorType" value="SIMPLE"/>-->
<!--        <setting name="defaultStatementTimeout" value="25"/>-->
<!--        <setting name="defaultFetchSize" value="100"/>-->
<!--        <setting name="safeRowBoundsEnabled" value="false"/>-->
<!--        <setting name="mapUnderscoreToCamelCase" value="false"/>-->
<!--        <setting name="localCacheScope" value="SESSION"/>-->
<!--        <setting name="jdbcTypeForNull" value="OTHER"/>-->
<!--        <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>-->
    </settings>

    <!-- 环境:配置mybatis的环境 -->
    <environments default="development">
        <!-- 环境变量:可以配置多个环境变量,比如使用多数据源时,就需要配置多个环境变量 -->
        <environment id="development">
            <!-- 事务管理器 -->
            <transactionManager type="jdbc"></transactionManager>
            <!-- 数据源 -->
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <mapper resource="./mapper/ExpertMapper.xml"  />
    </mappers>
</configuration>

mybatis的数据库配置文件

username=root
password=123456
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/blog?zeroDateTimeBehavior=CONVERT_TO_NULL&useUnicode=true&characterEncoding=utf-8&autoReconnect=true&serverTimezone=GMT%2B8

执行过程

package com.wyl.mybatis.service;

import com.wyl.mybatis.entity.FullCity;
import com.wyl.mybatis.mapper.FullCityMapper;
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;

/**
 * @Description
 * @Author WuYiLong
 * @Date 2024/2/26 16:04
 */
public class MybatisService {

    public static void main(String[] args) throws IOException {
        InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();

        FullCityMapper mapper = sqlSession.getMapper(FullCityMapper.class);
        FullCity fullCity = mapper.selectByName("广东省");
        System.out.println("城市的名称:"+fullCity.getName());

    }
}

在这里插入图片描述

总结

JDBC 提供了最底层的访问数据库的方式,直接使用SQL语句,灵活但需要手动管理连接和事务。
MyBatis 是在JDBC之上的一个抽象层,隐藏了如何连接数据库、如何处理事务、如何关闭流、自动提交,通过ORM提供了更高层次的数据库操作,通过编写简单的sql就可以完成增删改查,简化了开发流程,更适合于复杂的SQL操作和动态SQL需求。
所以在选择使用JDBC还是MyBatis时,通常考虑应用的复杂性、性能需求和开发效率等因素。对于简单的数据库操作,JDBC可能更直接高效;而对于复杂的业务逻辑和大量的数据库交互,MyBatis提供的抽象和便利可能会更加合适。

在这里插入图片描述

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

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

相关文章

JDK8和JDK11在Ubuntu18上切换(解决nvvp启动报错)

本文主要介绍JDK8和JDK11在Ubuntu18上切换&#xff0c;以供读者能够理解该技术的定义、原理、应用。 &#x1f3ac;个人简介&#xff1a;一个全栈工程师的升级之路&#xff01; &#x1f4cb;个人专栏&#xff1a;计算机杂记 &#x1f380;CSDN主页 发狂的小花 &#x1f304;人…

docker login 阿里云失败??

docker login 阿里云失败&#xff1f;&#xff1f; 首先参考 阿里云官方文档《Docker登录、推送和拉取失败常见问题》 看看是否是下面提到的情况&#xff1a; 我遇到的情况是超时: [rootk8snode1 software]# sudo docker login --usernametyleryun registry.cn-hangzhou.ali…

sqllab第十八关通关笔记

知识点&#xff1a; UA注入 不进行url解析&#xff0c;不能使用 %20 编码等操作出现在User-agent字段中一般为insert语句 insert 表名(字段1&#xff0c;字段2&#xff0c;。。。) values(数据1&#xff0c;数据2&#xff0c;。。。) 通过admin admin进行登录发现页面打印出了…

Oracle数据库:使用 bash脚本 + 定时任务 自动备份数据

Oracle数据库&#xff1a;使用 bash脚本 定时任务 自动备份数据 1、前言2、为什么需要自动化备份&#xff1f;3、编写备份脚本4、备份脚本授权5、添加定时任务6、重启 crond / 检查 crond 服务状态7、备份文件检查 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收…

Golang实现Redis分布式锁(Lua脚本+可重入+自动续期)

Golang实现Redis分布式锁&#xff08;Lua脚本可重入自动续期&#xff09; 1 概念 应用场景 Golang自带的Lock锁单机版OK&#xff08;存储在程序的内存中&#xff09;&#xff0c;分布式不行 分布式锁&#xff1a; 简单版&#xff1a;redis setnx》加锁设置过期时间需要保证原…

3.Redis命令

Redis命令 Redis 根据命令所操作对象的不同&#xff0c; 可以分为三大类&#xff1a; 对 Redis 进行基础性操作的命令&#xff0c;对 Key 的操作命令&#xff0c;对 Value 的操作命令。 1.1 Redis 首先通过 redis-cli 命令进入到 Redis 命令行客户端&#xff0c;然后再运行下…

横向移动 --> PTT(Kerberos)

好不容易到了周末&#xff0c;终于有时间来写自己的东西了&#xff0c;那么就来讲一下PTT吧 目录 1.PTT(Past The Ticket) 2.Golden Ticket 1.Krbtgt的NTLM hash 2.获取域的sid 3.查看要伪造的管理员 4.查看域控名字 5.查看并且清除票据 6.制造黄金票据 3.Sliver Ticke…

Python 基础语法:基本数据类型(字典)

为什么这个基本的数据类型被称作字典呢&#xff1f;这个是因为字典这种基本数据类型的一些行为和我们日常的查字典过程非常相似。 通过汉语字典查找汉字&#xff0c;首先需要确定这个汉字的首字母&#xff0c;然后再通过这个首字母找到我们所想要的汉字。这个过程其实就代表了…

【Algorithms 4】算法(第4版)学习笔记 18 - 4.4 最短路径

文章目录 前言参考目录学习笔记0&#xff1a;引入介绍1&#xff1a;APIs1.1&#xff1a;API&#xff1a;加权有向边1.2&#xff1a;Java 实现&#xff1a;加权有向边1.3&#xff1a;API&#xff1a;加权有向图1.4&#xff1a;Java 实现&#xff1a;加权有向图1.5&#xff1a;AP…

NVidia NX 中 ROS serial软件包的安装

自己装的ROS是noetic版本&#xff0c;受限于网络&#xff0c;直接用命令安装串口包不行。于是手动安装了一次。 1 下载源码 git clone https://github.com/wjwwood/serial.git 或者直接在浏览器里面输入 https://github.com/wjwwood/serial.git 2 解压 然后在serial&#xf…

【考研数学】高等数学总结

文章目录 第一章 极限 函数 连续1.1 极限存在准则及两个重要极限1.1.1 夹逼定理1.1.1.1 数列夹逼定理1.1.1.2函数夹逼定理 1.1.2 两个重要极限1.1.2.1 极限公式11.1.2.1.1 证明1.1.2.1.2 数列的单调有界收敛准则1.1.2.1.2.1 二项式定理1.1.2.1.2.2 证明 1.1.2.2 极限公式21.1.2…

未来洞见:亚信安慧AntDB在数据可靠性上的愿景

和国外成熟稳定的商业数据库相比&#xff0c;国产数据库在性能、稳定性、生态等方面存在一定差距&#xff0c;我国数据库的自主可控替换&#xff0c;也不是简单的以库换库&#xff0c;而是用新体系替换旧体系&#xff0c;在架构、研发、上线、运维等方面&#xff0c;全面降低对…

Pyqt5中,QGroupBox组件标题字样(标题和内容样式分开设置)相对于解除继承

Python代码示例&#xff1a; import sys from PyQt5.QtWidgets import QApplication, QWidget, QVBoxLayout, QGroupBox, QLabelclass MyApp(QWidget):def __init__(self):super().__init__()# 创建一个 QVBoxLayout 实例layout QVBoxLayout()# 创建 QGroupBox 实例self.grou…

系统分析与设计作业 --- 酒店管理系统(2~3周)

第二周 作业一&#xff1a; &#xff08;1&#xff09;需求分析NABCD 我们的项目是一个酒店管理系统&#xff0c;所i对应的NABCD描述 NABCD是一种产品描述框架&#xff0c;用于全面阐述产品的各个方面。其中&#xff0c;N代表需求&#xff08;Need&#xff09;&#xff0c;描…

5_springboot_shiro_jwt_多端认证鉴权_禁用Cookie

1. Cookie是什么 ​ Cookie是一种在客户端&#xff08;通常是用户的Web浏览器&#xff09;和服务器之间进行状态管理的技术。当用户访问Web服务器时&#xff0c;服务器可以向用户的浏览器发送一个名为Cookie的小数据块。浏览器会将这个Cookie存储在客户端&#xff0c;为这个Co…

字符串分割(C++)

经常碰到字符串分割的问题&#xff0c;这里总结下&#xff0c;也方便我以后使用。 一、用strtok函数进行字符串分割 原型&#xff1a; char *strtok(char *str, const char *delim); 功能&#xff1a;分解字符串为一组字符串。 参数说明&#xff1a;str为要分解的字符串&am…

LeetCode每日一题 将有序数组转换为二叉搜索树(分治)

题目描述 给你一个整数数组 nums &#xff0c;其中元素已经按 升序 排列&#xff0c;请你将其转换为一棵平衡二叉搜索树。 示例 1&#xff1a; 输入&#xff1a;nums [-10,-3,0,5,9] 输出&#xff1a;[0,-3,9,-10,null,5] 解释&#xff1a;[0,-10,5,null,-3,null,9] 也将被视…

[RAM] RAM 突发传输(Burst ,Burst size, length) | Burst 读写过程与时序 精讲

主页&#xff1a; 元存储博客 文章目录 前言1. Burst 基本概念含义Burst Width &Burst Length 2. CPU Burst mode3. 总线 burst mode总线的仲裁总线突发传输时序 4. Burst Chop (突发终止)5. Burst Mode 应用什么时候用突发模式 总结 前言 在DMA&#xff08;直接内存访问&…

MD5算法:密码学中的传奇

title: MD5算法&#xff1a;密码学中的传奇 date: 2024/3/15 20:08:07 updated: 2024/3/15 20:08:07 tags: MD5起源算法原理安全分析优缺点比较技术改进示例代码应用趋势 MD5算法起源&#xff1a; MD5&#xff08;Message Digest Algorithm 5&#xff09;算法是由MIT的计算机…

Web框架盘点:好用又实用的技术解析

​随着2024年的临近&#xff0c;我们满怀热情地为新的一年制定计划&#xff0c;探索未来一年可以学习或实现的目标。此时是探索未来一年值得学习的框架、理解其功能和特点的最佳时机。我们将以2023年JavaScript新星为指南&#xff0c;力求保持客观公正的态度。对于每个值得关注…