MybatisPlus知识详解以及用十数个例子完成MybatisPlus的入门到进阶

Stella981
• 阅读 1068

1. MybatisPlus

1.1 业务需求

Mybatis缺点:

  • 1.Mybatis操作数据库的过程中,需要编辑大量的sql语句.无论该sql是否复杂或者简单.
  • 2.Mybatis操作时在xml配置文件中需要额外记忆单独的标签.

需求:能否实现单表操作的CRUD的全自动的实现.能否实现真正的ORM映射?

1.2ORM

要求:利用面向对象的方式操作数据库 特点:
   1.操作数据库的面向对象.

      userMapper.insert(user对象); ------->自己编辑sql语句

   2.查询数据库的面向对象.

      userMapper.selectByWhere(user对象); ------>动态的生成Sql------>自动实现结果集封装.

1.3ORM实现单表操作原理

要求:实现单表的自动的CRUD操作 例子:

    User user = new Uesr();
•   user.setId(xx).setName(xx).setAge(xx).setSex(xx);
•   userMapper.insertUser(user);

框架内部实现过程:

     核心:数据库只能识别sql语句.框架需要将对象转化为sql.

核心配置:

     1.User对象与数据库的表 一一映射!

     解决方法: 自定义注解标识表与对象的关系

     2.User对象的属性与数据表中的字段一一映射!

     解决方法:自定义注解完成属性与字段的映射

     3.将CURD的方法进行统一的定义.形成工具API接口

     解决方法:利用公共的mapper接口 BaseMapper,在其中定义几乎所有的单表的CURD操作.

     4.将接口方法按照数据库方式转化为特定的sql语句.

        1.用户的调用 userMapper.insert(user)

        2.拼接特定的sql:

insert into 表名(字段名......) values(属性值......);

     一般利用反射技术,可以通过对象或者有关对象的全部信息(注解,属性,属性值)

1.4 MybatisPlus介绍(MP)

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

1.5 MybatisPlus特性

  • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑

  • 损耗小:启动即会自动注入基本 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 操作智能分析阻断,也可自定义拦截规则,预防误操作

1.6 MybatisPlus的实际入门操作

1.6.1导入jar包

==最主要的jar包==

<!--spring整合mybatis-plus -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.2.0</version>
        </dependency>

==本次所需的其余jar包==

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!--添加属性注入依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>

        <!--引入插件lombok 自动的set/get/构造方法插件 -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <!--支持热部署 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>

        <!--引入数据库驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

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

6.2 编辑POJO文件

注意如果没有lombok插件可以在 https://blog.csdn.net/XING_Gou/article/details/104316560中安装Lombok插件

package com.jt.demo.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;

@Data
@Accessors(chain=true)  //链式加载
@TableName      //标识对象与表之间的关联关系
public class User {
    //简化步骤:如果属性的名称与映射的名称一致,则可以省略不写
    @TableId(type=IdType.AUTO) //定义主键 主键自增
    private Integer id;
    //对象的属性与表中的字段.
    //@TableField(value="name")
    private String name;
    private Integer age;
    private String sex;

}

数据库

DROP DATABASE IF EXISTS `jtdb`;
CREATE DATABASE `jtdb` DEFAULT CHARACTER SET utf8;
USE `jtdb`;

/*Table structure for table `user` */

DROP TABLE IF EXISTS `user`;

CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` char(40) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `sex` char(40) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `cc` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=53 DEFAULT CHARSET=utf8;

/*Data for the table `user` */

insert  into `user`(`id`,`name`,`age`,`sex`) values (1,'黑熊精',4000,'男'),(2,'鲤鱼精',5000,'男'),(3,'金角大王',3000,'男'),(4,'银角大王',4000,'男'),(5,'唐僧',30,'男'),(6,'悟空',501,'男'),(7,'白龙驴',2000,'男'),(8,'八戒',502,'男'),(9,'沙悟净',503,'男'),(11,'小乔',17,'女'),(12,'貂蝉',18,'女'),(16,'黄月英',18,'女'),(17,'孙尚香',18,'女'),(18,'甄姬c',20,'女'),(21,'孙尚香D',18,'女'),(22,'刘备',40,'男'),(23,'陆逊',33,'男'),(24,'陆逊',33,'男'),(25,'关羽',40,'男'),(27,'阿科',20,'女'),(31,'王昭君',19,'女'),(38,'貂蝉',18,'女'),(39,'西施',18,'女'),(40,'严真煌',16,'女'),(41,'白骨精',18,'女'),(43,'小乔',19,'男'),(44,'大乔',19,'女'),(46,'不知火舞',18,'女'),(49,'小兰兰',18,'男'),(50,'柳鹏林',18,'男'),(51,'妲己',18,'男'),(52,'如花',17,'男');

6.3 继承共同的API接口

public interface UserMapper extends BaseMapper<User>{...}

编辑YML配置

server:
  port: 8090  #标识端口号信息
  servlet:
    context-path: /
spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/jtdb?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
    username: root
    password: root

#SpringBoot整合Mybatis-plus配置信息
mybatis-plus:
  #定义别名包  只要定义了别名包,则程序中resultType可以省略包路径
  type-aliases-package: com.jt.demo.pojo
  #配置文件的资源加载路径
  mapper-locations: classpath:/mybatis/mappers/*.xml
  #开启驼峰映射
  configuration:
    map-underscore-to-camel-case: true

6.5 入门案例测试

@RunWith(SpringRunner.class)    //注意测试文件的位置 必须在主文件加载包路径下
@SpringBootTest
public class TestMP {

    //注入mapper接口
    @Autowired
    private UserMapper userMapper;
    /**
     * 1.入门案例
     * 要求:查询全部的用户信息  不需要写where条件
     * 注意事项:利用MP的方法和自己的接口方法 名称不能重复.
     *
     * 参数说明:queryWrapper 动态生成sql语句中的where条件
     */
    @Test
    public void test01() {
        List<User> userList = userMapper.selectList(null);
        System.out.println(userList);
    }
}

1.7Mybatis案例

1.selectBatchIds

    /**
     * 练习1: 查询id信息为1,3,4,5,6用户数据
     * sql: select * from user where id in (1,2,3,4,5,6);
     * 思考:id可以利用数组进行接收 利用数组查询数据
     */

    @Test
    public void test02() {

        List<Integer> idList = new ArrayList<Integer>();
        idList.add(1);
        idList.add(3);
        idList.add(4);
        idList.add(5);
        idList.add(6);
        //以对象的方式进行数据库操作
        List<User> userList = userMapper.selectBatchIds(idList);
        System.out.println(userList);
    }

2. selectByMap

说明:根据字段查询用户信息

    /**
     * 练习2: 根据name="黑熊精"  age="3000"查询数据信息
     * SelectByMap:根据具体的字段查询用户信息.
     * sql语句: select * from user where name="黑熊精" and age=3000
     * 规则:默认使用and连接符.
     */

    @Test
    public void test03() {
        Map<String,Object> map = new HashMap<>();
        //key="字段名称"  value="字段值"
        map.put("name", "黑熊精");
        map.put("age", 3000);
        List<User> userList = userMapper.selectByMap(map);
        System.out.println(userList);

    }

3. 条件构造器查询

/**
     * 4.name属性中包含"精"的数据,并且为女性
     * sql: SELECT * FROM USER WHERE NAME LIKE "%精%" AND sex = "女"
     * queryWrapper: 条件构造器
     *                作用 动态拼接sql的where条件
     * 逻辑运算符:  >gt , <lt, =eq, >=ge, <= le
     */

    @Test
    public void test04() {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.like("name", "精")
        .eq("sex", "女");
        List<User> userList = userMapper.selectList(queryWrapper);
        System.out.println(userList);

    }

4. Between-and

    /**
     * 查询年龄在18-35之间的女性用户.
     * sql: SELECT * FROM USER WHERE age BETWEEN 18 AND 35 AND sex ="女";
     */
    @Test
    public void test05() {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.between("age", 18, 35)
                    .eq("sex", "女");
        List<User> userList = userMapper.selectList(queryWrapper);
        System.out.println(userList);
    }
    

5. order by

/**
     * 条件:  查询年龄大于100岁的,并且按照年龄降序排列,
     *      如果年龄相同按照Id降序排列.
     * sql:SELECT * FROM USER WHERE age > 100 ORDER BY age DESC,id DESC;
     */
    @Test
    public void test06() {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.gt("age", 100)
                    .orderByDesc("age","id");
        List<User> userList = userMapper.selectList(queryWrapper);
        System.out.println(userList);
    }

6. like练习

/**
     * 条件: 查询名称以"乔"结尾的,并且性别为女,并且age小于30岁.按照年龄降序排列.
     * SQL:
     *      SELECT * FROM USER WHERE (NAME LIKE "%乔" AND sex="女"
AND age < 30) ORDER BY age DESC;
     */
    @Test
    public void test07(){
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.likeLeft("name","乔")
                    .eq("sex", "女")
                    .lt("age", 30)
                    .orderByDesc("age");
        List<User> userList = userMapper.selectList(queryWrapper);
        System.out.println(userList);
    }

7.inSql

说明:适用于子查询

/**
     * 查询age < 100岁的用户,并且性别与name="孙尚香"的性别相同的的用户数据.
     * 分析: age<100  sex=男/女
     * sql:SELECT * FROM USER WHERE age < 100 AND
        sex in(
            SELECT sex FROM USER WHERE NAME = "孙尚香"
            )
     */
    @Test
    public void test08(){
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.lt("age",100)
                    .inSql("sex", "select sex from user where name ='孙尚香'");
        List<User> userList = userMapper.selectList(queryWrapper);
        System.out.println(userList);
    }

8.select

/**
     * 需求: 有时可能不需要查询全部的数据库的表字段
     * 查询age为18岁的用户的名称和id.
     * select:挑选字段的属性.
     * 查询结果:User(id=12, name=貂蝉, age=null, sex=null)
     */
    @Test
    public void test09() {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("name","id")
            .eq("age", 18);
        List<User> userList = userMapper.selectList(queryWrapper);
        System.out.println(userList);
    }

9.condition

/**
     * 条件判断
     *         以name和sex不为null的数据当做where条件.
     * condition作用:
     *         判断参数是否拼接为where条件
     *         结果true,    动态拼接参数
     *         结果false,    参数不会动态拼接
     * 应用场景:
     *         接收前台的参数时,参数可能为null或者其他的数值类型时
     *         需要添加判断.
     * 业务需求:
     *         如果age>18时,才能查询年龄
     */
    @Test
    public void test10() {
        String name = null;
        int age = 18;
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        //name属性的值,不为null时,才会拼接where条件
        queryWrapper.eq(!StringUtils.isEmpty(name), "name", name);
        queryWrapper.eq(age>18, "age", age);
        List<User> userList = userMapper.selectList(queryWrapper);
        System.out.println(userList);
    }

10. 根据对象查询

/**
     * 根据对象查询数据库
     * 条件:根据对象中不为null的属性充当where条件
     * 需求:查询age=18的用户信息 性别=女
     * 说明:利用对象的方式查询时,逻辑运算符都是"="号
     */
    @Test
    public void test11() {
        User user = new User();
        user.setAge(18)
            .setSex("女");
        QueryWrapper<User> queryWrapper = new QueryWrapper<>(user);
        List<User> userList = userMapper.selectList(queryWrapper);
        System.out.println(userList);
    }
    

11. selectObjs

说明:只查询主键信息(第一列)数据

/**
     * 需求:只查询主键的信息.  
     * 类比: select
     * sql: SELECT id FROM USER where age >18
     */
    @Test
    public void test12() {
        QueryWrapper<User> queryWrapper2 = new QueryWrapper<User>();
        queryWrapper2.select("id");
        //查询的List<User>对象信息
        userMapper.selectList(queryWrapper2);
        QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
        queryWrapper.gt("age", 18);
        //只查询主键信息
        List<Object> idList = userMapper.selectObjs(queryWrapper);
        System.out.println(idList);
    }
    

12.selectMaps

说明:获取任意字段的数据信息

/**
     * 获取任意的字段信息
     * 需求:查询用户信息 只想获取id和name的值.不想获取age/sex
     * sql:  select id,name from user where age > 18;
     */
    @Test
    public void test13() {
        QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
        queryWrapper.select("id","name")
                    .gt("age", 18);
        //获取全部的对象信息
        List<User> userList = userMapper.selectList(queryWrapper);
        //获取字段的信息
        List<Map<String,Object>> listMap = userMapper.selectMaps(queryWrapper);
        System.out.println(userList);
        System.out.println(listMap);
    }

13. 新增用户

@Test
    public void test14() {
        User user = new User();
        user.setName("外国人永久居住权")
            .setSex("男")
            .setAge(30);
        userMapper.insert(user);
    }

14.删除用户

/**
     * 删除用户信息
     */

    @Test
    public void test15() {
        QueryWrapper<User> queryWrapper = new QueryWrapper<User>();
        queryWrapper.eq("name", "外国人永久居住权");
        //根据多个条件 删除用户数据.
        userMapper.delete(queryWrapper);
        //根据集合中的数据.批量删除用户信息
        Integer[] ids = {2000,2001};
        List<Integer> idList = Arrays.asList(ids);
        userMapper.deleteBatchIds(idList);
        //id 代表主键信息   根据主键进行删除.
        userMapper.deleteById(2000);
        
        //挑选字段和属性进行删除.
        Map<String,Object> columnMap = new HashMap<String, Object>();
        columnMap.put("name", "疫情");
        userMapper.deleteByMap(columnMap);
    }

15. 修改操作

   /**
     * 更新操作
     *  updateById:  根据主键信息修改数据.
     *  主键信息必须添加充当where条件,
     *      根据对象中不为null的数据,充当set条件.
     *  sql: update user set name="xx",age=xxx,sex=xx where id=23
     *  
     *  update方法说明:
     *      参数1:entity   修改后的数据结果
     *      参数2:updateWrapper   修改的条件构造器
     *  案例:
     *      将杨颖改为范冰冰 修改年龄/性别
     *  sql : update user set name="xxxx",age=xxx,sex=xxx
     *        where name = "杨颖";
     *      
     */
    @Test
    public void test16() {
        User user = new User();
        user.setId(23).setName("潘凤").setAge(35).setSex("男");
        userMapper.updateById(user);

        User user2 = new User();
        user2.setName("范冰冰").setAge(40).setSex("女");
        UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("name", "杨颖");
        userMapper.update(user2, updateWrapper);
    }

完结!希望打开了页面就耐心的看完吧,你一定会有收获de

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
4个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
Python3:sqlalchemy对mysql数据库操作,非sql语句
Python3:sqlalchemy对mysql数据库操作,非sql语句python3authorlizmdatetime2018020110:00:00coding:utf8'''
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
Oracle一张表中实现对一个字段不同值和总值的统计(多个count)
需求:统计WAIT\_ORDER表中的工单总数、未处理工单总数、已完成工单总数、未完成工单总数。表结构:为了举例子方便,WAIT\_ORDER表只有两个字段,分别是ID、STATUS,其中STATUS为工单的状态。1表示未处理,2表示已完成,3表示未完成总数。 SQL:  1.SELECT   2
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
10个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这