1.MyBatis

image.png
官网:https://mybatis.org/mybatis-3/zh/index.html

1.1 什么是MyBatis?

MyBatis 本是apache的一个开源项目iBatis,2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。

MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。实际上它对jdbc的操作数据库的过程进行封装,使开发者只需要关注SQL本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。

Mybatis通过xml或注解的方式将要执行的各种statement(statement、preparedStatemnt)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。

总之,Mybatis对JDBC访问数据库的过程进行了封装,简化了JDBC代码,解决JDBC将结果集封装为Java对象的麻烦。

image.png
(1)mybatis-config.xml是Mybatis的核心配置文件,通过其中的配置可以生成SqlSessionFactory,也就是SqlSession工厂
(2)基于SqlSessionFactory可以生成SqlSession对象
(3)SqlSession是一个既可以发送SQL去执行,并返回结果,类似于JDBC中的Connection对象,也是Mybatis中至关重要的一个对象。
(4)Executor是SqlSession底层的对象,用于执行SQL语句
(5)MapperStatement对象也是SqlSession底层的对象,用于接收输入映射(SQL语句中的参数),以及做输出映射(即将SQL查询的结果映射成相应的结果)

1.2 为什么要适应MyBatis

场景:如何通过JDBC查询User表中的所有记录,并封装到一个List<User>集合中返回。

1.2.1 传统方式访问数据库

1.会有大量的重复性代码(注册驱动,获取连接,获取传输器,释放资源)。
2.传统的JDBC对于数据库的操作中没有连接池,需要不断地创建连接,断开连接,每次对连接的初始化会花费很长的时间,使得效率极为低下,
3.传统方式中的SQL语句是写死在程序中的,一旦修改SQL需要重新编译。
4.需要对执行结果进行繁琐的操作。

1.2.2 通过MyBatis访问数据库

1.自定义了存储过程,即对于传统方式中访问数据库的操作进行了封装,简化了JDBC代码。
2.MyBatis支持链接池(也可以自己配置),提高了程序开发效率。
3.自定义了SQL语句,即将SQL配置在Mapper文件中,修改SQL语句,类不需要重新编译。
4.SQL执行后返回的ResultSet对象,Mybatis会帮我们处理,转换成Java对象。

总结:MyBatis中的自定义SQL,存储过程和高级映射的特性直接解决和优化了JDBC中一系列耗时繁琐的过程,大大提高了程序操作数据库的效率

1.3 MyBatis快速入门

1.3.1 准备数据,创建库和表

-- 1、创建数据库 mbdb 数据库
create database if not exists mbdb charset utf8;
use mbdb; -- 选择mbdb据库
-- 2、删除emp表(如果存在)
drop table if exists student;
-- 3、在 mbdb 库中创建 student 表
create table student(
    id int primary key auto_increment,
    name varchar(50),
    age int
);
-- 4、往 sstudent 表中, 插入若干条记录
insert into student values(null, 'MTingCat', 20);
insert into student values(null, 'Tom', 30);
insert into student values(null, 'Cat', 40);

1.3.2 创建工程,导入Jar包依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<!--parent标签作用: 定义了SpringBoot中所有关联项目的版本号信息.-->
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.3.3.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<!--定义项目的坐标 指定该jar包在maven仓库中的位置.-->
<groupId>com.mybatis</groupId>
<artifactId>testmybatis</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>testmybatis</name>
<description>SpringBoot 整合MyBatis</description>

<properties>
    <java.version>1.8</java.version>
    <!--项目打包时,跳过测试类打包-->
    <skipTests>true</skipTests>
</properties>


<!--开箱即用:SpringBoot项目只需要引入少量的jar包及配置,即可拥有其功能.
    spring-boot-starter 拥有开箱即用的能力.
    maven项目中依赖具有传递性.
        A 依赖  B  依赖 C项目   导入A bc会自动依赖
-->
<dependencies>

    <!--直接依赖web springMVC配置-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <!--springBoot-start SpringBoot启动项  -->
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.junit.platform</groupId>
        <artifactId>junit-platform-launcher</artifactId>
        <version>1.6.2</version>
        <scope>test</scope>
    </dependency>

    <!--SpringBoot重构了测试方式 可以在测试类中 直接引入依赖对象-->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
        <exclusions>
            <exclusion>
                <groupId>org.junit.vintage</groupId>
                <artifactId>junit-vintage-engine</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <!--引入插件lombok 自动的set/get/构造方法插件  -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
    </dependency>
    <!--引入数据库驱动 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
        <version>8.0.15</version>
    </dependency>

    <!--springBoot数据库连接  -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>



    <!--spring整合mybatis  暂时  -->
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>1.3.2</version>
    </dependency>
</dependencies>

<!--在项目打包部署时生效,如果不添加build,则程序发布时不然会报
    项目中没有main方法.
-->
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

</project>

1.3.3 创建XML/YML全局配置文件

server:
  port: 8090
  servlet:
    context-path: /
spring:
  datasource:
    #driver-class-name: com.mysql.jdbc.Driver 驱动注释采用默认方法
    url: jdbc:mysql://localhost/mbdb?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
    username: root
    password: MTingCat819

#Mybatis整合
mybatis:
  #定义别名包 将实体对象的包路径进行封装.
  type-aliases-package: com.mybatis.pojo
  #添加xml文件的依赖
  mapper-locations: classpath:/mybatis/mappers/*.xml
  #开启驼峰映射
  configuration:
    map-underscore-to-camel-case: true

# 配置数据库日志
logging:
  level:
    #打印哪个包下的日志信息.
    com.jt.mapper: debug

  

1.3.4 创建pojo对象

package com.mybatis.pojo;

import lombok.Data;
import lombok.experimental.Accessors;

@Data
@Accessors(chain=true)
public class Student {
    private Integer id;
    private String name;
    private Integer age;
}

1.3.5 创建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.mybatis.mapper.StudentMapper">

    <select id="findAll" resultType="Student">
        select id,name,age from student
    </select>
</mapper>

1.3.6 创建测试类测试

package com.mybatis.test;

import com.mybatis.mapper.StudentMapper;
import com.mybatis.pojo.Student;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import javax.crypto.spec.PSource;
import java.util.List;

@SpringBootTest
public class TestMyBatis {
    @Autowired
    private StudentMapper studentMapper;

    @Test
    public void Test01(){
        List<Student> studentList = studentMapper.findAll();
        System.out.println("关于MyBatis的测试");
        System.out.println(studentList);

    }
}

2.MyBatis-Plus

官网:https://baomidou.com/

2.1 什么是MyBatis-Plus?

image.png
image.png
我们的愿景是成为 MyBatis 最好的搭档,就像 魂斗罗 中的 1P、2P,基友搭配,效率翻倍。

MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

2.1.1 特性

--

  • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
  • 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
  • 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
  • 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
  • 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
  • 支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
  • 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
  • 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
  • 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
  • 分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
  • 内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
  • 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作

2.1. 框架

image.png

2.2 原理

同MyBatis一样,,MP也是通过自定义 SQL、存储过程以及高级映射,通过对象的形式来访问数据库和接收数据,除此之外MP还简化了SQL语句的编写,形式如下:


例子: 将student对象插入数据库中.
        studentMapper.insert(user对象);  //程序员完成的最后的代码
        sql: insert into 表名(字段.....) values (属性值......); 由mp动态拼接之后交由mybatis执行.

2.3 MyBatis-plus快速入门

2.3.1 准备数据,创建库和表

-- 1、创建数据库 mbdb 数据库
create database if not exists mbdb charset utf8;
use mbdb; -- 选择mbdb据库
-- 2、删除emp表(如果存在)
drop table if exists student;
-- 3、在 mbdb 库中创建 student 表
create table student(
    id int primary key auto_increment,
    name varchar(50),
    age int
);
-- 4、往 sstudent 表中, 插入若干条记录
insert into student values(null, 'MTingCat', 20);
insert into student values(null, 'Tom', 30);
insert into student values(null, 'Cat', 40);

2.3.2 创建工程,导入Jar包依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.mybatisplus</groupId>
    <artifactId>testmybatisplus</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>testmybatisplus</name>
    <description>Spring Boot 整合 MyBatis- Plus</description>

    <properties>
        <java.version>1.8</java.version>
        <!--项目打包时,跳过测试类打包-->
        <skipTests>true</skipTests>
    </properties>


    <!--开箱即用:SpringBoot项目只需要引入少量的jar包及配置,即可拥有其功能.
        spring-boot-starter 拥有开箱即用的能力.
        maven项目中依赖具有传递性.
            A 依赖  B  依赖 C项目   导入A bc会自动依赖
    -->
    <dependencies>

        <!--直接依赖web springMVC配置-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <!--springBoot-start SpringBoot启动项  -->
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.junit.platform</groupId>
            <artifactId>junit-platform-launcher</artifactId>
            <version>1.6.2</version>
            <scope>test</scope>
        </dependency>

        <!--SpringBoot重构了测试方式 可以在测试类中 直接引入依赖对象-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <!--引入插件lombok 自动的set/get/构造方法插件  -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <!--引入数据库驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
            <version>8.0.15</version>
        </dependency>

        <!--springBoot数据库连接  -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>



        <!--&lt;!&ndash;spring整合mybatis  暂时  &ndash;&gt;
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.2</version>
        </dependency>-->

        <!--spring整合mybatis-plus 只导入MP包,删除mybatis包 -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.2.0</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.12</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>

    <!--在项目打包部署时生效,如果不添加build,则程序发布时不然会报
        项目中没有main方法.
    -->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

2.3.3 创建XML/YML全局配置文件

server:
  port: 8090
  servlet:
    context-path: /
spring:
  datasource:
    #driver-class-name: com.mysql.jdbc.Driver 驱动注释采用默认方法
    url: jdbc:mysql://localhost/mbdb?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
    username: root
    password: MTingCat819

#Mybatis-plus整合
mybatis-plus:
  #定义别名包 将实体对象的包路径进行封装.
  type-aliases-package: com.mybatisplus.pojo
  #添加xml文件的依赖
  mapper-locations: classpath:/mybatisplus/mappers/*.xml
  #开启驼峰映射
  configuration:
    map-underscore-to-camel-case: true

# 配置数据库日志
logging:
  level:
    #打印哪个包下的日志信息.
    com.jt.mapper: debug

  

2.3.4 创建pojo对象

package com.mybatisplus.pojo;


import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.experimental.Accessors;
import org.omg.CORBA.IDLType;

import javax.annotation.sql.DataSourceDefinition;
@Data
@Accessors(chain=true)
@TableName("student")    //实现表与对象的关联  如果名称一致(忽略大小写)可以省略表名
public class Student {
    @TableId(type= IdType.AUTO)
    private Integer id;
    private String name;
    private Integer age;
}

2.3.5 创建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.mybatisplus.mapper.StudentMapper">

    <select id="findAll" resultType="Student">
        select id,name,age from student
    </select>
</mapper>

2.3.6 创建测试类测试

package com.mybatisplus.test;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.mybatisplus.mapper.StudentMapper;
import com.mybatisplus.pojo.Student;
import com.sun.media.sound.SoftTuning;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.Arrays;
import java.util.List;

@SpringBootTest
public class TestMyBatisPlus {
    @Autowired
    private StudentMapper studentMapper;

    @Test
    public void Test01(){
        List<Student> studentList = studentMapper.findAll();
        System.out.println(studentList);
    }

    /**
     * 测试插入数据
     * Timi,22
     */
    @Test
    public void insert(){
        Student stu01 = new Student();
        stu01.setId(null).setName("Timi").setAge(22);
        studentMapper.insert(stu01);
    }
    @Test
    public void insert02(){
        Student stu02 = new Student();
        stu02.setId(null).setName(null).setAge(22);
        studentMapper.insert(stu02);
    }

    /**
     * 把name为空的年龄改为100,名字改为Tina
     */
    @Test
    public void update(){
        Student stu02 = new Student();
        stu02.setAge(22).setName("Tina");
        UpdateWrapper<Student> updateWrapper = new UpdateWrapper<>();
        updateWrapper.isNull("name");
        studentMapper.update(stu02,updateWrapper);
    }


    /**
     * 查询id为1 的学生
     */
    @Test
    public void select02(){
        Student stu03 = studentMapper.selectById(1);
        System.out.println(stu03);
        int count = studentMapper.selectCount(null);
        System.out.println(count);
    }

    /**
     * 查询年龄为22的student
     * 条件构造器: 动态拼接where条件的. 多条件中默认的链接符and
     * 常见逻辑运算符
     *  1.eq =   2.gt >   3.lt  <
     *  ge >= ,le  <=
     * */
    @Test
    public void select04(){
        QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("age",22);
        List<Student> stuList = studentMapper.selectList(queryWrapper);
        System.out.println(stuList);
    }

    /**
     * 查询name以MTing开头的
     */
    @Test
    public void select05(){
        QueryWrapper<Student> queryWrapper = new QueryWrapper<>();
        queryWrapper.likeLeft("name","MTing");
        List<Student> studentList = studentMapper.selectList(queryWrapper);
        System.out.println(studentList);
    }

    @Test
    public void select06(){
       Integer[] ids = {1,3};
       List<Integer> idList = Arrays.asList(ids);
       List<Student> studentList = studentMapper.selectBatchIds(idList);
        System.out.println(studentList);

    }


}

MTingCat
12 声望2 粉丝

一路向阳。