Mybatis源码分析(一)Mybatis 基本使用

news2024/11/28 12:52:32

目录

  • 一 知识回顾
    • 1.1 简介
    • 1.2 其他
  • 二 基本使用

  • 官网:mybatis – MyBatis 3 | 简介

一 知识回顾

1.1 简介

  • MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。
  • MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。
  • MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
  • 简单来学,就是一个保存数据的工具,就像我们存钱一样,总要有个介质来帮助我们来存钱,不用过多理解。
  • 最重要的一点,在于融汇贯通,你不可能就只学这一个持久层框架,当然基本且扎实的sql功底是企业开发的必备技能。

1.2 其他

优点:

  • 简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。
  • 灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。 sql写在xml里,便于统一管理和优化。通过sql基本上可以实现我们不使用数据访问框架可以实现的所有功能,或许更多。
  • 解除sql与程序代码的耦合:通过提供DAL层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。
  • 提供映射标签,支持对象与数据库的orm字段关系映射。
  • 提供对象关系映射标签,支持对象关系组建维护。
  • 提供xml标签,支持编写动态sql。

缺点:

  • 编写SQL语句时工作量很大,尤其是字段多、关联表多时,更是如此。
  • SQL语句依赖于数据库,导致数据库移植性差,不能更换数据库。
  • 框架还是比较简陋,功能尚有缺失,虽然简化了数据绑定代码,但是整个底层数据库查询实际还是要自己写的,工作量也比较大,而且不太容易适应快速数据库修改。
  • 二级缓存机制不佳。

二 基本使用

  • sql 文件
/*
 Navicat Premium Data Transfer

 Source Server         : LocalHostMysql
 Source Server Type    : MySQL
 Source Server Version : 80022
 Source Host           : localhost:3306
 Source Schema         : mybatis

 Target Server Type    : MySQL
 Target Server Version : 80022
 File Encoding         : 65001

 Date: 14/12/2022 15:30:24
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for task
-- ----------------------------
DROP TABLE IF EXISTS `task`;
CREATE TABLE `task`  (
  `id` int NOT NULL AUTO_INCREMENT,
  `userId` int NOT NULL,
  `taskName` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 35 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of task
-- ----------------------------
INSERT INTO `task` VALUES (1, 1, 'Clean classroom.');
INSERT INTO `task` VALUES (2, 1, 'Open the door.');
INSERT INTO `task` VALUES (3, 2, 'Open windows.');
INSERT INTO `task` VALUES (4, 3, 'Clean the blackboard.');
INSERT INTO `task` VALUES (5, 2, 'Buy some boos.');
INSERT INTO `task` VALUES (6, 3, 'Buy some pens.');
INSERT INTO `task` VALUES (7, 4, 'Buy some flowers.');

-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
  `email` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `age` int NULL DEFAULT NULL,
  `sex` int NULL DEFAULT NULL,
  `schoolName` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 14 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (1, '易哥', 'yeecode@sample.com', 18, 0, 'Sunny School');
INSERT INTO `user` VALUES (2, '莉莉', 'lili@sample.com', 15, 1, 'Garden School');
INSERT INTO `user` VALUES (3, '杰克', 'jack@sample.com', 25, 0, 'Sunny School');
INSERT INTO `user` VALUES (4, '张大壮', 'zdazhaung@sample.com', 16, 0, 'Garden School');
INSERT INTO `user` VALUES (5, '王小壮', 'wxiaozhuang@sample.com', 27, 0, 'Sunny School');
INSERT INTO `user` VALUES (6, '露西', 'lucy@sample.com', 14, 1, 'Garden School');
INSERT INTO `user` VALUES (7, '李二壮', 'lerzhuang@sample.com', 9, 0, 'Sunny School');

SET FOREIGN_KEY_CHECKS = 1;

  • 依赖
<dependency>
  <groupId>org.mybatis.spring.boot</groupId>
  <artifactId>mybatis-spring-boot-starter</artifactId>
  <version>2.1.0</version>
</dependency>


<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>8.0.26</version>
</dependency>


<dependency>
  <groupId>org.projectlombok</groupId>
  <artifactId>lombok</artifactId>
  <optional>true</optional>
</dependency>
  • 编写Mapper
package com.shu;

import com.shu.model.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;

import java.awt.print.Pageable;
import java.util.List;

/**
 * @description:
 * @author: shu
 * @createDate: 2022/12/13 19:43
 * @version: 1.0
 */
@Mapper
@Repository
public interface UserMapper {
  /**
     * 通过ID查询单条数据
     *
     * @param id 主键
     * @return 实例对象
     */
  User queryById(Integer id);
  /**
     * 分页查询指定行数据
     *
     * @param user 查询条件
     * @param pageable 分页对象
     * @return 对象列表
     */
  List<User> queryAllByLimit(User user, @Param("pageable") Pageable pageable);
  /**
     * 统计总行数
     *
     * @param user 查询条件
     * @return 总行数
     */
  long count(User user);
  /**
     * 新增数据
     *
     * @param user 实例对象
     * @return 影响行数
     */
  int insert(User user);
  /**
     * 批量新增数据
     *
     * @param entities List<User> 实例对象列表
     * @return 影响行数
     */
  int insertBatch(@Param("entities") List<User> entities);
  /**
     * 批量新增或按主键更新数据
     *
     * @param entities List<User> 实例对象列表
     * @return 影响行数
     */
  int insertOrUpdateBatch(@Param("entities") List<User> entities);
  /**
     * 更新数据
     *
     * @param user 实例对象
     * @return 影响行数
     */
  int update(User user);
  /**
     * 通过主键删除数据
     *
     * @param id 主键
     * @return 影响行数
     */
  int deleteById(Integer id);
}

  • 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.shu.UserMapper">
  <resultMap type="com.shu.model.User" id="UserMap">
    <result property="id" column="id" jdbcType="INTEGER"/>
    <result property="name" column="name" jdbcType="VARCHAR"/>
    <result property="email" column="email" jdbcType="VARCHAR"/>
    <result property="age" column="age" jdbcType="INTEGER"/>
    <result property="sex" column="sex" jdbcType="INTEGER"/>
    <result property="schoolName" column="schoolName" jdbcType="VARCHAR"/>
  </resultMap>

  <!-- 通过ID查询单条数据 -->
  <select id="queryById" resultMap="UserMap">
    select
    id,name,email,age,sex,schoolName
    from user
    where id = #{id}
  </select>

  <!--分页查询指定行数据-->
  <select id="queryAllByLimit" resultMap="UserMap">
    select
    id,name,email,age,sex,schoolName
    from user
    <where>
      <if test="id != null and id != ''">
        and id = #{id}
      </if>
      <if test="name != null and name != ''">
        and name = #{name}
      </if>
      <if test="email != null and email != ''">
        and email = #{email}
      </if>
      <if test="age != null and age != ''">
        and age = #{age}
      </if>
      <if test="sex != null and sex != ''">
        and sex = #{sex}
      </if>
      <if test="schoolname != null and schoolname != ''">
        and schoolName = #{schoolname}
      </if>
    </where>
    limit #{pageable.offset}, #{pageable.pageSize}
  </select>

  <!--统计总行数-->
  <select id="count" resultType="java.lang.Long">
    select count(1)
    from user
    <where>
      <if test="id != null and id != ''">
        and id = #{id}
      </if>
      <if test="name != null and name != ''">
        and name = #{name}
      </if>
      <if test="email != null and email != ''">
        and email = #{email}
      </if>
      <if test="age != null and age != ''">
        and age = #{age}
      </if>
      <if test="sex != null and sex != ''">
        and sex = #{sex}
      </if>
      <if test="schoolname != null and schoolname != ''">
        and schoolName = #{schoolname}
      </if>
    </where>
  </select>

  <!--新增数据-->
  <insert id="insert" keyProperty="id" useGeneratedKeys="true">
    insert into user(id,name,email,age,sex,schoolName)
    values (#{id},#{name},#{email},#{age},#{sex},#{schoolname})
  </insert>

  <!-- 批量新增数据 -->
  <insert id="insertBatch" keyProperty="id" useGeneratedKeys="true">
    insert into user(id,name,email,age,sex,schoolName)
    values
    <foreach collection="entities" item="entity" separator=",">
      (#{entity.id},#{entity.name},#{entity.email},#{entity.age},#{entity.sex},#{entity.schoolname})
      </foreach>
      </insert>

      <!-- 批量新增或按主键更新数据 -->
      <insert id="insertOrUpdateBatch" keyProperty="id" useGeneratedKeys="true">
      insert into user(id,name,email,age,sex,schoolName)
      values
      <foreach collection="entities" item="entity" separator=",">
      (#{entity.id},#{entity.name},#{entity.email},#{entity.age},#{entity.sex},#{entity.schoolname})
      </foreach>
      on duplicate key update
      id=values(id),
      name=values(name),
      email=values(email),
      age=values(age),
      sex=values(sex),
      schoolName=values(schoolName)
      </insert>

      <!-- 更新数据 -->
      <update id="update">
      update user
      <set>
      <if test="id != null and id != ''">
      id = #{id},
      </if>
      <if test="name != null and name != ''">
      name = #{name},
      </if>
      <if test="email != null and email != ''">
      email = #{email},
      </if>
      <if test="age != null and age != ''">
      age = #{age},
      </if>
      <if test="sex != null and sex != ''">
      sex = #{sex},
      </if>
      <if test="schoolname != null and schoolname != ''">
      schoolName = #{schoolname},
      </if>
      </set>
      where id = #{id}
      </update>

      <!--通过主键删除-->
      <delete id="deleteById">
      delete from user where id = #{id}
      </delete>
      </mapper>
  • 配置文件
spring:
# mysql配置
datasource:
username: root
password: 123456
# 如果时区报错就需要添加 serverTimezone=UTC
url: jdbc:mysql://127.0.0.1:3306/mybatis?useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC&useSSL=false
driver-class-name: com.mysql.cj.jdbc.Driver


#mybatis的相关配置
mybatis:
#mapper配置文件
mapper-locations: classpath:mapper/*.xml
#指定包的别名
type-aliases-package: com.mapper
#开启驼峰命名
configuration:
map-underscore-to-camel-case: true


#日志打印
logging:
level:
com:
shu:
mapper: debug
  • 测试用例
package com.shu;


import com.shu.model.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;



@SpringBootTest
class MybatisDemo01ApplicationTests {

  @Autowired
  UserMapper userMapper;

  @Test
  void contextLoads() {

  }

  @Test
  public void UserTest(){
    User user = userMapper.queryById(1);
    System.out.println(user);
  }

}

  • 结果

image.png
到这我们一个基本的环就搭建完毕了,记住我们在使用中配置了那些东西,等下我们看源码回来看,就会恍然大悟

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

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

相关文章

图片怎么转换成excel文档?

当我们创建excel文档中&#xff0c;里面无疑是需要各种表格内容&#xff0c;而如果是我们一个一个编辑起来&#xff0c;这就会比较繁琐。而现在许多需求可以通过网络很容易地得到满足。比如有把图片转换成excel表格的需求。下载一个小工具&#xff0c;这就相当方便了&#xff0…

不愧是阿里资深架构师,这本“分布式架构笔记”写得如此透彻明了

前言&#xff1a; Mybatis 是一款优秀的持久层框架。其封装了 JDBC 操作&#xff0c; 免去了开发人员编写 JDBC 代码以及设置参数和获取结果集的重复性工作。通过编写简单的 XML 或 Java 注解即可映射数据库 CRUD 操作。本文介绍的是阿里资深架构师十年经验整理&#xff0c;My…

JAVA 中的注解可以继承吗?

前言 注解想必大家都用过&#xff0c;也叫元数据&#xff0c;是一种代码级别的注释&#xff0c;可以对类或者方法等元素做标记说明&#xff0c;比如 Spring 框架中的Service&#xff0c;Component等。那么今天我想问大家的是类被继承了&#xff0c;注解能否继承呢&#xff1f;…

基于springboot在线答疑系统

教师权限&#xff1a;首页、个人中心、疑难解答管理、试卷管理、试题管理、考试管理。 学生权限&#xff1b;首页、个人中心、问题发布管理、疑难解答管理、考试管理等功能模块的管理维护等操作&#xff0c;系统结构图如下图4-1所示。 图4-1 系统功能图 截图 目 录 摘 要 I …

[附源码]Node.js计算机毕业设计扶贫产品展销平台小程序Express

项目运行 环境配置&#xff1a; Node.js最新版 Vscode Mysql5.7 HBuilderXNavicat11Vue。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分离等等。 环境需要 1.运行环境&#xff1a;最好是Nodejs最新版&#xff0c;我…

matlab 的help没了

前两天还正常用&#xff0c;今天输入help 关键字 回复是没有相关的内容。 解决办法&#xff1a; 按照如下选择就行了 然后输入 help help 就会有显示了 help - Help for functions in Command Window This MATLAB function displays the help text for the functionalit…

大数据MapReduce学习案例:倒排索引

文章目录一&#xff0c;案例分析&#xff08;一&#xff09;倒排索引介绍&#xff08;二&#xff09;案例需求二&#xff0c;案例实施&#xff08;一&#xff09;准备数据文件&#xff08;1&#xff09;启动hadoop服务&#xff08;2&#xff09;虚拟机上创建文本文件&#xff0…

数据结构双向链表

双向链表也叫双链表&#xff0c;是链表的一种&#xff0c;它的每个数据结点中都有两个指针&#xff0c;分别指向直接后继和直接前驱。所以&#xff0c;从双向链表中的任意一个结点开始&#xff0c;都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表。 那…

WPF入门第三篇 ControlTemplate、Trigger与Storyboard

ControlTemplate、Trigger与Storyboard ControlTemplate通常用在Style中&#xff0c;Trigger通常作为ControlTemplate的一部分&#xff0c;StoryBoard表示动画效果&#xff0c;下面将通过对Button按钮设置这几项来简单说明这几项的用法。 在MainWindow中添加一个Button按钮&am…

Prometheus技术分享——如何监控宿主机和容器

这一期主要来跟大家聊一下&#xff0c;使用node_exporter工具来暴露主机和因公程序上的指标&#xff0c;利用prometheus来监控宿主机&#xff1b;以及通过通过Cadvisor监控docker容器。 一、部署node_exporter监控宿主机 1 下载软件包 wget https://github.com/prometheus/n…

分布式链路追踪SkyWalking

文章目录目录介绍服务端搭建注册中心启动注册中心修改持久化配置UI服务配置启动服务客户端搭建目录介绍 重要的目录结构分析如下&#xff1a; agent&#xff1a;客户端需要指定的目录&#xff0c;其中有一个jar&#xff0c;就是负责和客户端整合收集日志bin&#xff1a;服务端…

深入理解Linux网络技术内幕(十三)——协议处理函数

文章目录前言网络协议栈概论大蓝图Ethernet的链路层的选择&#xff08;LLC和SNAP&#xff09;网络协议栈的操作方式执行正确的协议处理函数特殊媒介封装协议处理函数的组织协议处理函数的注册Ethernet与IEEE 802.3帧设置封包类型设置Ethernet协议及长度逻辑链接控制&#xff08…

python+django球鞋商品竞拍卖网站vue

管理员功能模块 管理员登录&#xff0c;通过填写用户名、密码、角色等信息&#xff0c;输入完成后选择登录即可进入网上球鞋竞拍系统 管理员登录进入网上球鞋竞拍系统可以查看球鞋分类管理、热门竞拍管理、科比展区管理、用户管理、竞拍信息管理、消息通知管理、用户评价管理、…

单人脸的关键点检测

闲暇之余做了一个简单的单人的脸部关键点检测&#xff0c;使用的pytorch框架&#xff0c;别人训练好的现成模型。其中人脸检测模型是YOLOface5&#xff08;onnx格式的权重&#xff09;&#xff0c;关键点检测模型是PFLD&#xff08;能检测98个关键点&#xff09;&#xff0c;是…

计算机网络学习笔记(Ⅳ):网络层

目录 1 网络层内容 1.1 功能概述 1.任务 2.主要功能 1.2 数据交换方式 1.电路交换 2.报文交换 3.分组交换 4.方法对比 1.3 分组交换 1.数据报方式 2.虚电路方式 3.对比 2 路由算法与路由协议 2.1 路由算法 2.2 路由选择协议 3 IPv4 3.1 IP数据报格式 1.TCP/…

快2023年了,还不会性能调优?阿里技术官亲授“Java性能调优技术宝典”看完直接涨薪5K

一、前言 什么是性能调优&#xff1f; 性能调优其实很好理解&#xff0c;就是优化硬件、操作系统、应用之间的一个充分的协作&#xff0c;最大化的发挥出硬件的极致性能&#xff0c;来应对高负载的业务需求。 为什么需要性能优化&#xff1f; 其实说到底就是两个原因&#…

2023年湖北安全员ABC三类人员延期多久一次?甘建二

2023年湖北安全员ABC三类人员延期多久一次&#xff1f; 2023年湖北安全员ABC延期快来找甘建二报名&#xff0c;建设厅指定的 2023年湖北安全员ABC新办快来找甘建二报名&#xff0c;建设厅指定的 首先安全员分为三类&#xff1a;A证、B证、C证&#xff0c;每个证书都有相应的…

Spring源码解析-环境变量(下)

“不积跬步&#xff0c;无以至千里”。 接着聊上一篇文章中遗留的两个重要问题&#xff1a; 如何往Spring环境变量中添加自定义的环境变量&#xff1f;工作原理是什么&#xff1f;PropertyPlaceholderConfigurer这个类是怎么完成bean属性填充时“$”符号解析工作的&#xff1f…

数据库系统概论第2章 关系数据库

易错点1&#xff1a;实体完整性 实体完整性要求主属性不能取空值 而主属性不能取空值≠候选码不为空 因为候选码可以是两个属性的组合&#xff0c;而主属性是候选码的属性 举个例子&#xff1a; SC表中候选码为&#xff08;学号&#xff0c;课程号&#xff09; 主属性为学…

fetch向后端请求数据:get/post/put/patch/delete方式、解决catch不能主动捕获错误问题(超详细笔记)

1、什么是fetch&#xff1a; fetch是ES6出现的&#xff0c;它使用了 ES6 提出的 promise 对象&#xff0c;为了取代XMLHttpRequest而诞生的&#xff1b;提到XMLHttpRequest就不得不提ajax&#xff0c;ajax是一种实现前后端交互的技术&#xff0c;而ajax是基于XMLHttpRequest模块…