mybatis源码阅读系列(一)

源码下载

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提供的抽象和便利可能会更加合适。

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

UE4_调试工具_绘制调试球体

学习笔记&#xff0c;仅供参考&#xff01; 效果&#xff1a; 步骤&#xff1a; 睁开眼睛就是该变量在此蓝图的实例上可公开编辑。 勾选效果&#xff1a;

【小白刷leetcode】第15题

【小白刷leetcode】第15题 动手刷leetcode&#xff0c;正在准备蓝桥&#xff0c;但是本人算法能力一直是硬伤。。。所以做得一直很痛苦。但是不熟练的事情像练吉他一样&#xff0c;就需要慢速&#xff0c;多练。 题目描述 看这个题目&#xff0c;说实在看的不是很懂。索性我们直…

GUROBI建模之非线性约束的处理

官方文档 目录 官方文档&#xff1a;GRBModel.AddGenConstrXxx() - Gurobi Optimization 数学规划的约束类型 基本约束(fundamental constraints)&#xff1a; 通用约束(general constraints): 1. GUROBI求解器有针对这类约束的函数&#xff0c;直接调用这类函数即可 2.…

Python-GIS分析之地理数据空间聚类

地理空间数据聚类是空间分析和地理信息系统(GIS)领域的一项关键技术。这种方法对于理解地理数据固有的空间模式和结构、促进城市规划、环境管理、交通和公共卫生等各个领域的决策过程至关重要。本文探讨了地理空间数据聚类的概念、方法、应用、挑战和未来方向。 当模式出现…

音频切割如何操作?剪辑音乐入门教程

随着数字音乐时代的来临&#xff0c;音频编辑和音乐剪辑成为了越来越多人的必备技能。无论是想要制作个人音乐作品&#xff0c;还是想要为视频添加背景音乐&#xff0c;了解如何切割和剪辑音频都是非常重要的。本文将为你提供一份音频切割和音乐剪辑的入门教程&#xff0c;帮助…

13-操作符(初识)

课前小技巧&#xff1a;VS中&#xff0c;想要复制哪一行&#xff0c;直接把鼠标放在哪一行&#xff0c;CtrlC即可&#xff0c;CtrlV直接自动复制到下一行 C语言非常灵活&#xff1a;C语言提供了非常丰富的操作符&#xff0c;使用起来比较灵活 13-1 算术操作符 - * / % 这…

WXML 模板语法

数据绑定 1. 数据绑定的基本原则 ① 在 data 中定义数据 在页面对应的 .js 文件中&#xff0c;把数据定义到 data 对象中即可 ② 在 WXML 中使用数据 2. Mustache 语法的格式 把 data 中的数据绑定到页面中渲染&#xff0c;使用 Mustache 语法&#xff08;双大括号&#x…

快速了解JavaScript

1.1 javaScript 历史 创始人 布兰登 艾奇 生于1961年 在1995设计LiveScript后改名为JavaScript 1.2 javaScript 是什么类型的语言 JavaScript是一种在客户端运行的脚本语言&#xff08;不需要编译&#xff0c;由js引擎逐行解释执行&#xff09; 1.3 JavaScript可以做什么 …

ts版本微信小程序在wxml保存文件不刷新页面的解决办法

将project.config.json中的skylineRenderEnable改为false "skylineRenderEnable": false

【理解机器学习算法】之岭回归Ridge - L2 Rgularization

Ridge 回归&#xff08;Ridge Regression&#xff09;也称作岭回归或脊回归&#xff0c;是一种专用于共线性数据分析的有偏估计回归方法。在多元线性回归中&#xff0c;如果数据集中的特征&#xff08;自变量&#xff09;高度相关&#xff0c;也就是说存在共线性(Multicollinea…

Kotlin 中List,Set,Map的创建与使用

目录 1. List 的使用 1.1 不可变 List 1.2 可变 List 2. Set 的使用 2.1 不可变 Set 2.2 可变 Set 3. Map 的使用 3.1 不可变Map 3.2 可变Map 本篇主要为已经有Java基础的同学展示Kotlin语言中的List&#xff0c;Set&#xff0c;Map的创建和使用&#xff0c;所以Java代…

STM32CubeMX与HAL库开发教程八(串口应用/轮询/中断/DMA/不定长数据收发)

目录 前言 初识串口-轮询模式 串口中断模式收发 串口DMA模式 蓝牙模块与数据包解析 前言 前面我们简单介绍过串口的原理和初步的使用方式&#xff0c;例如怎么配置和简单的收发&#xff0c;同时我们对串口有了一个初步的了解&#xff0c;这里我们来深入的来使用一下串口 …

基于高德地图JS API实现Vue地图选点组件

基于高德地图JS API2.0实现一个搜索选择地点后返回给父组件位置信息的功能&#xff0c;同时可以进行回显 目录 1 创建key和秘钥1.1 登录高德地图开放平台1.2 创建应用1.3 绑定服务创建秘钥 2 使用组件前准备2.1 导入loader2.2 在对应的组件设置秘钥2.3 引入css样式 3 功能实现…

记录dockers中Ubuntu安装python3.11

参考&#xff1a; docker-ubuntu 安装python3.8,pip3_dockerfile ubuntu22 python3.8-CSDN博客

揭示数据在内存中存储的秘密!

** ** 悟已往之不谏&#xff0c;知来者犹可追 ** ** 创作不易&#xff0c;宝子们&#xff01;如果这篇文章对你们有帮助的话&#xff0c;别忘了给个免费的赞哟~ 整数在内存中的存储 整数的表达方式有三种&#xff1a;原码、反码、补码。 三种表示方法均有符号位和数值位两部分…

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

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

matlab 平面桁架有限元受力分析计算

1、内容简介 略 62-可以交流、咨询、答疑 平面桁架有限元受力分析计算 2、内容说明 略 3、仿真分析 略 4、参考论文 略

宿主环境

1. 什么是宿主环境 宿主环境&#xff08; host environment &#xff09;指的是程序运行所必须的依赖环境。例如&#xff1a; Android 系统和 iOS 系统是两个不同的宿主环境。安卓版的微信 App 是不能在 iOS 环境下运行的&#xff0c;所以&#xff0c; Android 是安卓软件的宿…

“import ... =“ 只能在 TypeScript 文件中使用

当你遇到这个问题很苦恼。 可以按照以下解决办法 使用ctrlshiftP 修改"javascript.validate.enable": false

php中 0 == ‘’(0等于任意字符串) 判断是否成立 返回true

php中不同类型变量之间比较大小 一、背景二、探究0是为什么&#xff1f;三、探究 0all是为什么&#xff1f;四、程序中如何判断0是否等于指定字符串 一、背景 最近在项目实际开发中&#xff0c;我需要判断前端传来的参数值是否等于一个字符串&#xff1b;然后发现当参数值是0时…