【精选】框架初探篇之——MyBatis入门必知【面试常问】

什么是MyBatis?

在这里插入图片描述

MyBatis是一个半自动的ORM框架,其本质是对JDBC的封装。使用MyBatis不需要写JDBC代码,但需要程序员编写SQL语句。之前是apache的一个开源项目iBatis,2010年改名为MyBatis。

补充:

Hibernate也是一款持久层ORM框架,多年前的市场占有率很高,但近年来市场占有率越来越低。

MyBatis与Hibernate的比较:

  • MyBatis是一个半自动的ORM框架,需要手写SQL语句。
  • Hibernate是一个全自动的ORM框架,不需要手写SQL语句。
  • 使用MyBatis的开发量要大于Hibernate。

为什么Hibernate市场占有率越来越低:

  • 对于新手学习Hibernate时间成本比MyBatis大很多,MyBatis上手很快。
  • Hibernate不需要写SQL语句是因为框架来生成SQL语句。对于复杂查询,开发者很难控制生成的SQL语句,这就导致SQL调优很难进行。
  • 之前的项目功能简单,数据量小,所以使用Hibernate可以快速完成开发。而近年来项目的数据量越来越大,而互联网项目对查询速度要求也很高,这就要求我们一定要精细化的调整SQL语句。此时灵活性更强,手动编写SQL语句的MyBatis慢慢代替了Hibernate使用。
  • 在高并发、大数据、高性能、高响应的互联网项目中,MyBatis是首选的持久框架。而对于对性能要求不高的比如内部管理系统等可以使用Hibernate。

MyBatis入门

环境搭建

  1. 将SQL文件导入数据库

  2. 创建maven工程,引入依赖

    <dependencies>
      <!--  mybatis  -->
      <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.7</version>
      </dependency>
      <!--  mysql驱动包  -->
      <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.26</version>
      </dependency>
    
    
      <!--  junit  -->
      <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.10</version>
      </dependency>
      <!--  log4j  -->
      <dependency>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
        <version>1.2.12</version>
      </dependency>
    </dependencies>
    
    
  3. 创建mybatis核心配置文件SqlMapConfig.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="mysql">
        <environment id="mysql">
          <!--  事务类型  -->
          <transactionManager type="JDBC"></transactionManager>
          <!--  数据源  -->
          <dataSource type="POOLED">
            <property name="driver" value="com.mysql.jdbc.Driver"/>
            <property name="url" value="jdbc:mysql:///mybatis"/>
            <property name="username" value="root"/>
            <property name="password" value="root"/>
          </dataSource>
        </environment>
      </environments>
    </configuration>
    
    
  4. 将log4j.properties文件放入resources中,让控制台打印SQL语句。

  5. 创建实体类

    public class User {
      private int id;
      private String username;
      private String sex;
      private String address;
        // 省略getter/setter/构造方法/toString方法
    }
    
    

创建持久层接口和映射文件

  1. 在java目录创建持久层接口

    public interface UserMapper {
      List<User> findAll();
    }
    
    
  2. 在resource目录创建映射文件

    <?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.java.mapper.UserMapper">
      <select id="findAll" resultType="com.java.pojo.User">
         select * from user
      </select>
    </mapper>
    
    
  3. 将映射文件配置到mybatis核心配置文件中

    <!--  注册映射文件  -->
    <mappers>
      <mapper resource="com/java/mapper/UserMapper.xml">     </mapper>
    </mappers>
    
    

映射文件注意事项:

  • 映射文件要和接口名称相同。

  • 映射文件要和接口的目录结构相同。

  • 映射文件中namespace属性要写接口的全名。

  • 映射文件中标签的id属性是接口方法的方法名。

  • 映射文件中标签的resultType属性是接口方法的返回值类型。

  • 映射文件中标签的parameterType属性是接口方法的参数类型。

  • 映射文件中resultTypeparameterType属性要写全类名,如果是集合类型,则写其泛型的全类名。

测试持久层接口方法

@Test
public void testFindAll() throws Exception {
  // (1)读取核心配置文件
  InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
  // (2)创建SqlSessionFactoryBuilder对象
  SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
  // (3)SqlSessionFactoryBuilder对象获取SqlSessionFactory对象
  SqlSessionFactory factory = builder.build(is);
  // (4)SqlSessionFactory对象获取SqlSession对象
  SqlSession session = factory.openSession();
  // (5)SqlSession对象获取代理对象
  UserMapper userMapper = session.getMapper(UserMapper.class);
  // (6)代理对象执行方法
  List<User> all = userMapper.findAll();
  all.forEach(System.out::println);


  // (7)释放资源
  session.close();
  is.close();
}

MyBatis核心对象及工作流程

在这里插入图片描述

MyBatis核心对象

  • SqlSessionFactoryBuilder

    SqlSession 工厂构建者对象,使用构造者模式创建SqlSession工厂对象。

  • SqlSessionFactory

    SqlSession工厂,使用工厂模式创建SqlSession对象。

  • SqlSession

    该对象可以操作数据库,也可以使用动态代理模式创建持久层接口的代理对象操作数据库。

  • Mapper

    持久层接口的代理对象,他具体实现了持久层接口,用来操作数据库。

MyBatis工作流程

  1. 创建SqlSessionFactoryBuilder对象
  2. SqlSessionFactoryBuilder对象构建了SqlSessionFactory对象:构造者模式
  3. SqlSessionFactory对象生产了SqlSession对象:工厂模式
  4. SqlSession对象创建了持久层接口的代理对象:动态代理模式
  5. 代理对象操作数据库

使用SqlSession操作数据库

除了代理对象能够操作数据库,SqlSession也能操作数据库。只是这种方式在开发中使用的较少,接下来我们使用SqlSession操作数据库:

@Test
public void testFindAll2() throws Exception {
  // (1)读取核心配置文件
  InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
  // (2)创建SqlSessionFactoryBuilder对象
  SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
  // (3)SqlSessionFactoryBuilder对象获取SqlSessionFactory对象
  SqlSessionFactory factory = builder.build(is);
  // (4)SqlSessionFactory对象获取SqlSession对象
  SqlSession session = factory.openSession();
  // (5)SqlSession直接操作数据库
  List<User> users = session.selectList("com.java.mapper.UserMapper.findAll");
  users.forEach(System.out::println);
  // (6)关闭资源
  session.close();
  is.close();
}

Mapper动态代理原理

Mapper动态代理:

  • SqlSession的getMapper方法,最终是调用的是JDK动态代理方法,生成一个代理对象,类型就是传入的接口类型。
  • MapperProxy对象通过调用MapperMethod的execute方法定义了代理方式,该方法的底层调用的是SqlSession的方法。

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

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

相关文章

文章解读与仿真程序复现思路——电工技术学报EI\CSCD\北大核心《面向差异化电源成本结构的容量市场机制设计》

这个文章标题涉及到容量市场机制设计&#xff0c;着重考虑了电源成本结构的差异性。下面对标题中的关键词进行解读&#xff1a; 面向&#xff08;Facing&#xff09;&#xff1a; 表示该容量市场机制设计是以某种方向、取向或目标为基础的。在这里&#xff0c;可能指的是设计是…

第五天 用Python批量处理Excel文件,实现自动化办公

用Python批量处理Excel文件&#xff0c;实现自动化办公 一、具体需求 有以下N个表&#xff0c;每个表的结构一样&#xff0c;如下&#xff1a; 需要把所有表数据汇总&#xff0c;把每个人的得分、积分分别加起来&#xff0c;然后按总积分排名&#xff0c;总积分一致时&#xff…

Flutter学习(四)如何取消listview的越界效果

背景 在flutter的开发过程中&#xff0c;ListView是很常见的一个组件&#xff0c;但是&#xff0c;由于ListView的某些自带的体验&#xff0c;导致不太好的用户体验。例如ListView中&#xff0c;滑动到顶部或者底部的时候&#xff0c;再次滑动&#xff0c;会有越界的效果&…

Keil工程打开发现目标芯片无法选择解决方案

买了一个开发板&#xff0c;配套有一些底层驱动的例程&#xff0c;打开后发现目标芯片无法选择&#xff0c;对应的下载Flash FLM文件也无法选择。从提示框中可以知道所提供的例程是Keil4的例程&#xff0c;我电脑上安装的Keil版本是Keil版本&#xff0c;估计是这个原因导致工程…

机器人制作开源方案 | 智能图书搬运机器人

作者&#xff1a;张宸豪 戚益凡 陈世达 高梓钦 谭清 单位&#xff1a;华北科技学院 指导老师&#xff1a;罗建国 韩红利 阅读对于学生的重要性毋庸置疑&#xff0c;因此图书馆是一个校园非常重要的组成部分&#xff0c;图书馆的书籍借阅&#xff0c;能为学生提供非常大的…

人工智能对网络安全的影响越来越大

如果问当前IT行业最热门的话题是什么&#xff0c;很少有人会回答除了人工智能&#xff08;AI&#xff09;之外的任何话题。 在不到 12 个月的时间里&#xff0c;人工智能已经从一项只有 IT 专业人员才能理解的技术发展成为从小学生到作家、程序员和艺术家的每个人都使用的工具…

基于单片机设计的大气气压检测装置(STC89C52+BMP180实现)

一、前言 本项目设计一个大气气压检测装置&#xff0c;该装置以单片机为基础&#xff0c;采用STC89C52作为核心控制芯片&#xff0c;结合BMP180模块作为气压传感器。大气气压&#xff0c;也就是由气体重力在大气层中产生的压力&#xff0c;其变化与天气预报、气象观测以及高度…

Python Pyvis库详解:创建交互式网络图

更多Python学习内容&#xff1a;ipengtao.com 大家好&#xff0c;我是涛哥&#xff0c;今天为大家分享 Python Pyvis库详解&#xff1a;创建交互式网络图&#xff0c;文章4000字&#xff0c;阅读大约15分钟&#xff0c;大家enjoy~~ Pyvis是一个基于JavaScript库NetworkX的Pytho…

【matlab程序】南海土台风画法

【matlab程序】南海土台风画法 图片 往期推荐 图片 【python海洋专题一】查看数据nc文件的属性并输出属性到txt文件 【python海洋专题二】读取水深nc文件并水深地形图 【python海洋专题三】图像修饰之画布和坐标轴 【Python海洋专题四】之水深地图图像修饰 【Python海洋专…

U-boot(四):start_armboot

本文主要探讨210的uboot启动的第二阶段&#xff0c;主要函数为start_armboot。 uboot 一阶段初始化SoC内部部件(看门狗、时钟等),初始化DDR,重定位 二阶段初始化其余硬件(iNand、网卡芯片)以及命令、环境变量等 启动打印硬件信息,进入bootdelay,读秒完后执行bootc…

二十一、文档操作

目录 一、添加文档 1、编写代码 2、运行并查看 二、查询文档 1、编写代码 2、运行并查看 三、删除文档 1、编写代码 2、运行并查看 四、修改文档 方式一&#xff1a;全量修改&#xff0c;会删除旧文档&#xff0c;添加新文档 方式二&#xff1a;局部修改。增量修改&…

nodejs 如何将 Buffer 数据转为 String

问题说明 使用webSocket的时候出现了一个问题&#xff0c;前端小程序和nodejs后端建立websocket连接后&#xff0c;使用send方法发送到后端为buffer格式&#xff0c;以下为我前后端代码 1、前端小程序代码 //创建webSocket连接 const socket uni.connectSocket({url: wss…

工作中死循环害死人

背景&#xff1a;研发的一段代码&#xff0c;循环一直没有跳出&#xff0c;导致其他依赖逻辑有问题&#xff0c;生产事故导致9万左右数据不正常。 这里while&#xff08;true&#xff09;真的不要轻易用 &#xff0c;后来研发改动限制mysql的id切分步长&#xff0c;控制不会有数…

FreeRTOS源码阅读笔记4--semphr.h

信号量是特殊的队列--无法存储消息的队列&#xff0c;相关的接口函数声明在semphr.h中&#xff0c;通过宏定义替换队列函数实现。 4.1创建二值信号量xSemaphoreCreateBinary() 4.1.1函数原型 queueQUEUE_TYPE_BINARY_SEMAPHORE&#xff1a;一个宏&#xff0c;表示创建队列的…

gitt开源项目的意义,公司为什么会对在gitt上有开源项目的人更大机会

Git是一种分布式版本控制系统&#xff0c;它可以帮助程序员管理代码的历史版本和协同工作。同时&#xff0c;Git也成为了开源项目的主要托管平台之一。Git的开源项目意义重大&#xff0c;因为这种开源项目托管平台可以帮助开发者将代码和项目分享给全球的开发者&#xff0c;并且…

node版本管理工具-nvm

1、 下载地址 https://github.com/coreybutler/nvm-windows/releases/tag/1.1.11 2、 选择安装地址不能有空格&#xff0c;中文 3、 使用命令

微服务学习(十二):安装Minio

微服务学习&#xff08;十二&#xff09;&#xff1a;安装Minio 一、简介 MinIO 是一款基于Go语言发开的高性能、分布式的对象存储系统。客户端支持Java,Net,Python,Javacript, Golang语言。MinIO系统&#xff0c;非常适合于存储大容量非结构化的数据&#xff0c;例如图片、视…

linux上的通用拍照程序

最近因为工作需要&#xff0c;在ubuntu上开发了一个拍照程序。 为了找到合适的功能研究了好几种实现方式&#xff0c;在这里记录一下。 目录 太长不看版 探索过程 v4l2 QT opencv4.2 打开摄像头 为什么不直接打开第一个视频节点 获取所有分辨率 切换摄像头 太长不看…

MySQL错误之ONLY_FULL_GROUP_BY

报错信息&#xff1a; 翻译&#xff1a; 对该报错的解释 所以&#xff0c;实际上该报错是由于在SQL查询语句中有group by&#xff0c;而这个包含group by的SQL查询写的并不规范导致的&#xff0c;这个ONLY_FULL_GROUP_BY模式开启之后检查就会很严格&#xff0c;如果select列表…

51单片机IO口的四种工作状态切换

51单片机IO口的四种工作状态切换 1.概述 这篇文章介绍单片机IO引脚的四种工作模式&#xff0c;每个模式都有各自的用武之地&#xff0c;后面在驱动外设硬件时会用它不同的模式。 2.IO口四种工作模式介绍 PnM1PnM0I/O口工作模式00准双向口&#xff1a;灌电流达20mA&#xff…