MyBatis-Plus基础教程


MyBatis-Plus

只讲解基础部分,深入了解mybatis-plus可前往mybatis-plus 官网

1、简介

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 操作智能分析阻断,也可自定义拦截规则,预防误操作

1.2、框架结构

framework

2、快速入门

2.1、mybatis实现查询

项目结构

image

maven依赖


    
    
        com.baomidou
        mybatis-plus
        3.3.2
    
    
    
        mysql
        mysql-connector-java
        8.0.16
    
    
    
        com.alibaba
        druid
        1.1.22
    
    
    
        org.projectlombok
        lombok
        1.18.12
        provided
    
    
        junit
        junit
        4.12
        test
    

User.java

package com.example.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author admin
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {

    private int id;
    private String userName;
    private String password;
    private String name;
    private Integer age;
    private String email;
}

UserMapper.java

package com.example.mapper;

import com.example.pojo.User;

import java.util.List;

/**
 * @author admin
 */
public interface UserMapper {

    /**
     * 获取全部用户
     * @return
     */
    List getAllUser();
}

db.properties

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test?characterEncoding=utf8&useSSL=true&serverTimezone=UTC
jdbc.username=root
jdbc.password=123456

mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>


    
    
        
    
    
        
    
    
        
            
            
                
                
                
                
            
        
    
    
        
    

UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>


    

测试

package com.example.mapper;

import com.example.pojo.User;
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 org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class UserMapperTest {

    @Test
    public void testGetAllUser() throws IOException {
        InputStream stream = Resources.getResourceAsStream("mybatis-config.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(stream);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        List userList = mapper.getAllUser();
        for (User user : userList) {
            System.out.println(user);
        }
        sqlSession.close();
    }
}

结果

image

2.2、mybatis-plus实现查询

User.java

package com.example.pojo;

import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @TableName 指定该实体在数据库中映射的表
 * @author admin
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("tb_user")
public class User {

    private int id;
    private String userName;
    private String password;
    private String name;
    private Integer age;
    private String email;
}

UserMapper.java

package com.example.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.pojo.User;

import java.util.List;

/**
 * @author admin
 */
public interface UserMapper extends BaseMapper {

    /**
     * 获取全部用户
     * @return
     */
    List getAllUser();
}

测试

@Test
public void testGetAllUserByMybatisPlus() throws IOException {
    InputStream stream = Resources.getResourceAsStream("mybatis-config.xml");
    SqlSessionFactory sqlSessionFactory = new MybatisSqlSessionFactoryBuilder().build(stream);
    SqlSession sqlSession = sqlSessionFactory.openSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    List userList = mapper.selectList(null);
    for (User user : userList) {
        System.out.println(user);
    }
    sqlSession.close();
}

结果

image

2.3、spring + mybatis-plus 实现查询

User.java

package com.example.pojo;

import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author admin
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("tb_user")
public class User {
    private int id;
    private String userName;
    private String password;
    private String name;
    private Integer age;
    private String email;
}

UserMapper.java

package com.example.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.pojo.User;

/**
 * @author admin
 */
public interface UserMapper extends BaseMapper {
}

jdbc.properties

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test?characterEncoding=utf8&useSSL=true&serverTimezone=UTC
jdbc.username=root
jdbc.password=123456

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>


    

    
        
        
        
        
        
        
    

    
        
    

    
    
        
    


测试

package com.example.mapper;

import com.example.pojo.User;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import java.util.List;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class UserMapperTest {

    @Autowired
    private SqlSessionFactory sqlSessionFactory;

    @Test
    public void testGetAllUser(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        List userList = mapper.selectList(null);
        for (User user : userList) {
            System.out.println(user);
        }
        sqlSession.close();
    }
}

结果

image

2.4、springboot + mybatis-plus 实现查询

项目结构

image

maven依赖


    
    
        com.baomidou
        mybatis-plus-boot-starter
        3.3.2
    

    
    
        org.springframework.boot
        spring-boot-starter-test
    
    
        org.springframework.boot
        spring-boot-starter
    

    
        mysql
        mysql-connector-java
        runtime
    
    
        org.projectlombok
        lombok
        true
    
    
        org.springframework.boot
        spring-boot-starter-test
        test
    

application.properties

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test?characterEncoding=utf8&useSSL=true&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=123456

User.java

package com.example.pojo;

import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author admin
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("tb_user")
public class User {
    private int id;
    private String userName;
    private String password;
    private String name;
    private Integer age;
    private String email;
}

UserMapper.java

package com.example.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.pojo.User;
import org.apache.ibatis.annotations.Mapper;

/**
 * @author admin
 */
public interface UserMapper extends BaseMapper {
}

SpringBoot启动类

package com.example;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @author admin
 */
@SpringBootApplication
@MapperScan("com.example.mapper")
public class MybatisPlusSpringbootApplication {

    public static void main(String[] args) {
        SpringApplication.run(MybatisPlusSpringbootApplication.class, args);
    }

}

测试

package com.example;

import com.example.mapper.UserMapper;
import com.example.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;

@SpringBootTest
class MybatisPlusSpringbootApplicationTests {

    @Autowired(required = false)
    private UserMapper userMapper;

    @Test
    void contextLoads() {
        List userList = userMapper.selectList(null);
        for (User user : userList) {
            System.out.println(user);
        }
    }

}

结果

image

3、通用CRUD

3.1、插入

User.java

package com.example.pojo;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author admin
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("tb_user")
public class User {
    @TableId(type = IdType.AUTO)
    private int id;
    private String userName;
    private String password;
    private String name;
    private Integer age;
    private String email;
}

测试

@Test
public void testInsert(){
    User user = new User();
    user.setUserName("simayi");
    user.setPassword("666666");
    user.setName("司马懿");
    user.setAge(31);
    user.setEmail("simayi@test.com");
    int row = userMapper.insert(user);
    System.out.println("数据库中受影响的行数: "+row);
    //自增后的id会回填到对象中
    int id = user.getId();
    System.out.println("自增长后的id值: "+id);
}

3.2、@TableField

在mybatis-plus中通过@TableField注解可以指定字段的一些属性,常常解决的问题有2个:

  1. 对象中的属性名和字段名不一致的问题(非驼峰)
  2. 对象中的属性字段在表中不存在的问题

数据库中的tb_user表

image

实体映射User

解决问题1:

package com.example.pojo;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author admin
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("tb_user")
public class User {
    @TableId(type = IdType.AUTO)
    private int id;
    private String userName;
    private String password;
    private String name;
    private Integer age;
    //指定数据库中的字段
    @TableField("email")
    private String mail;
}

解决问题2:

package com.example.pojo;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author admin
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("tb_user")
public class User {
    @TableId(type = IdType.AUTO)
    private int id;
    private String userName;
    private String password;
    private String name;
    private Integer age;
    private String email;

    /**
     * 表明该属性在数据库中不存在
     */
    @TableField(exist = false)
    private String address;
}

查询时不返回指定字段的值

package com.example.pojo;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author admin
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("tb_user")
public class User {
    @TableId(type = IdType.AUTO)
    private int id;
    private String userName;
    
    /**
     * 查询时不返回该字段的值
     */
    @TableField(select = false)
    private String password;
    private String name;
    private Integer age;
    private String email;
}

3.3、更新

3.3.1、根据id更新

测试

@Test
public void testUpdateById(){
    User user = new User();
    user.setId(7);
    user.setPassword("777777");
    int row = userMapper.updateById(user);
    System.out.println("数据库中受影响的行数: "+row);
    testSelectById();
}

@Test
public void testSelectById(){
    User user = userMapper.selectById(7);
    System.out.println(user);
}

结果

image

3.3.2、根据条件更新

测试

方法一:

@Test
public void testUpdateByCondition_1(){
    User user = new User();
    user.setAge(18);
    QueryWrapper wrapper = new QueryWrapper<>();
    //匹配user_name等于zhangsan的用户数据
    wrapper.eq("user_name","zhangsan");
    int row = userMapper.update(user, wrapper);
    System.out.println("数据库中受影响的行数: "+row);
}

方法二:

@Test
public void testUpdateByCondition_2(){
    UpdateWrapper wrapper = new UpdateWrapper<>();
    wrapper.set("age",18).eq("user_name","zhangsan");
    int row = userMapper.update(null, wrapper);
    System.out.println("数据库中受影响的行数: "+row);
}

3.4、删除

3.4.1、根据id删除

测试

@Test
public void testDeleteById(){
    int row = userMapper.deleteById(100);
    System.out.println("数据库中受影响的行数: "+row);
}

3.4.2、根据条件删除

测试

方法一:

@Test
public void testDeleteByMap(){
    Map map=new HashMap<>();
    map.put("user_name","zhangsan");
    map.put("password","999999");
    //根据map删除数据,多条件之间是and关系
    int row = userMapper.deleteByMap(map);
    System.out.println("数据库中受影响的行数: "+row);
}

方法二:

@Test
public void testDelete_1(){
    QueryWrapper wrapper = new QueryWrapper<>();
    wrapper.eq("user_name","zhangsan").eq("password","999999");
    int row = userMapper.delete(wrapper);
    System.out.println("数据库中受影响的行数: "+row);
}

方法三:

@Test
public void testDelete_2(){
    User user = new User();
    user.setUserName("zhangsan");
    user.setPassword("000000");
    QueryWrapper wrapper = new QueryWrapper<>(user);
    int row = userMapper.delete(wrapper);
    System.out.println("数据库中受影响的行数: "+row);
}

3.4.3、根据id批量删除

测试

@Test
public void testDeleteBatchIds(){
    //根据id批量删除记录
    int row = userMapper.deleteBatchIds(Arrays.asList(100, 200, 300, 400, 500));
    System.out.println("数据库中受影响的行数: "+row);
}

3.5、查询

3.5.1、根据id查询

测试

@Test
public void testSelectById(){
    User user = userMapper.selectById(7);
    System.out.println(user);
}

3.5.2、根据id批量查询

测试

@Test
public void testSelectBatchIds(){
    List userList = userMapper.selectBatchIds(Arrays.asList(1, 2, 3, 100));
    for (User user : userList) {
        System.out.println(user);
    }
}

3.5.3、根据条件查询

根据条件查询单条记录

@Test
public void testSelectOne(){
    QueryWrapper wrapper = new QueryWrapper<>();
    wrapper.eq("user_name","zhaoliu");
    User user = userMapper.selectOne(wrapper);
    System.out.println(user);
}

注意:若查询结果包含多条记录则报错

根据条件查询多条记录

@Test
public void testSelectList(){
    QueryWrapper wrapper = new QueryWrapper<>();
    //wrapper.gt("age",25);
    //查询邮箱中包含z的用户
    wrapper.like("email","z");
    List userList = userMapper.selectList(wrapper);
    for (User user : userList) {
        System.out.println(user);
    }
}

3.5.4、查询记录的条数

测试

@Test
public void testSelectCount(){
    QueryWrapper wrapper = new QueryWrapper<>();
    //查询年龄大于20岁的用户
    wrapper.gt("age",20);
    Integer count = userMapper.selectCount(wrapper);
    System.out.println("年龄大于20岁的用户有"+count+"个");
}

3.5.5、分页查询

MybatisPlusConfig.java

package com.example;

import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author admin
 */
@Configuration
@MapperScan("com.example.mapper")
public class MybatisPlusConfig {

    /**
     * 配置分页插件
     * @return
     */
    @Bean
    public PaginationInterceptor paginationInterceptor(){
        return new PaginationInterceptor();
    }
}

测试

@Test
public void testSelectPage(){
    //查询第一页,每页3条数据
    Page page = new Page<>(1,3);
    QueryWrapper wrapper = new QueryWrapper<>();
    wrapper.gt("age","20");
    Page userPage = userMapper.selectPage(page, wrapper);
    System.out.println("数据总条数: "+userPage.getTotal());
    System.out.println("数据总页数: "+userPage.getPages());
    System.out.println("当前页数: "+userPage.getCurrent());
    List userList = userPage.getRecords();
    for (User user : userList) {
        System.out.println(user);
    }
}

4、配置

4.1、configLocation

springboot:

mybatis-plus.config-location=classpath:mybatis-config.xml

springmvc:


	

4.2、mapperLocations

springboot:

mybatis-plus.mapper-locations=classpath:mybatis/*.xml

springmvc:


	

4.3、typeAliasesPackage

springboot:

mybatis-plus.type-aliases-package=com.example.pojo

springmvc:


	

4.4、mapUnderscoreToCamelCase

  • 类型:boolean
  • 默认值:true

是否开启自动驼峰命名规则映射,即从经典数据库列名a_column(下划线命名)到经典Java属性名aColumn(驼峰命名)的类似映射。

注意:

此属性在MyBatis中原默认值为false,在MyBatis-Plus中,此属性也将用于生成最终的sql的select body

如果你的数据库命名符合规则则无需使用@TableField注解指定数据库字段名

mybatis-plus.configuration.*和mybatis-plus.config-location不能同时出现在配置文件中

springboot:

mybatis-plus.configuration.map-underscore-to-camel-case=false

4.5、cacheEnabled

  • 类型:boolean
  • 默认值:true

全局地开启或关闭配置文件中的所有映射器已经配置的任何缓存,默认为true。

springboot:

mybatis-plus.configuration.cache-enabled=false

4.6、idType

  • 类型:com.baomidou.mybatisplus.annotation.IdType
  • 默认值:ID_WORKER

全局默认主键类型,设置后,即可省略实体对象中的@TableId(type = IdType.AUTO)配置

springboot:

mybatis-plus.global-config.db-config.id-type=auto

springmvc:


	
    	
        	
            	
                	
                
            
        
    

4.7、tablePrefix

  • 类型:String
  • 默认值:null

表名前缀,全局配置后可省略@TableName()配置

springboot:

mybatis-plus.global-config.db-config.table-prefix=tb_

springmvc:


	
    	
        	
            	
                	
                
            
        
    

5、条件构造器

说明:

  • 以下出现的第一个入参boolean condition表示该条件是否加入最后生成的sql中,例如:query.like(StringUtils.isNotBlank(name), Entity::getName, name) .eq(age!=null && age >= 0, Entity::getAge, age)
  • 以下代码块内的多个方法均为从上往下补全个别boolean类型的入参,默认为true
  • 以下出现的泛型Param均为Wrapper的子类实例(均具有AbstractWrapper的所有方法)
  • 以下方法在入参中出现的R为泛型,在普通wrapper中是String,在LambdaWrapper中是函数(例:Entity::getId,Entity为实体类,getId为字段idgetMethod)
  • 以下方法入参中的R column均表示数据库字段,当R具体类型为String时则为数据库字段名(字段名是数据库关键字的自己用转义符包裹!)!而不是实体类数据字段名!!!,另当R具体类型为SFunction时项目runtime不支持eclipse自家的编译器!!!
  • 以下举例均为使用普通wrapper,入参为MapList的均以json形式表现!
  • 使用中如果入参的Map或者List,则不会加入最后生成的sql中!!!
  • 有任何疑问就点开源码看,看不懂函数的点击我学习新知识(opens new window)

警告:

不支持以及不赞成在 RPC 调用中把 Wrapper 进行传输

  1. wrapper 很重
  2. 传输 wrapper 可以类比为你的 controller 用 map 接收值(开发一时爽,维护火葬场)
  3. 正确的 RPC 调用姿势是写一个 DTO 进行传输,被调用方再根据 DTO 执行相应的操作
  4. 我们拒绝接受任何关于 RPC 传输 Wrapper 报错相关的 issue 甚至 pr

AbstractWrapper

说明:

QueryWrapper(LambdaQueryWrapper) 和 UpdateWrapper(LambdaUpdateWrapper) 的父类
用于生成 sql 的 where 条件, entity 属性也用于生成 sql 的 where 条件
注意: entity 生成的 where 条件与 使用各个 api 生成的 where 条件没有任何关联行为

5.1、allEq

测试

@Test
public void testAllEq(){
    Map map=new HashMap<>();
    map.put("name","李四");
    map.put("age",20);
    map.put("password",null);
    QueryWrapper wrapper = new QueryWrapper<>();
    //null值作为查询条件:SELECT id,user_name,password,name,age,email FROM tb_user WHERE (password IS NULL AND name = ? AND age = ?)
    //wrapper.allEq(map);
    //null值不作为查询条件:SELECT id,user_name,password,name,age,email FROM tb_user WHERE (name = ? AND age = ?)
    //wrapper.allEq(map,false);
    //SELECT id,user_name,password,name,age,email FROM tb_user WHERE (age = ?) 
    wrapper.allEq((k,v)->(k.equals("age") || k.equals("id")), map);
    List userList = userMapper.selectList(wrapper);
    for (User user : userList) {
        System.out.println(user);
    }
}

5.2、基本比较操作

  • eq:等于 =
  • ne:不等于 <>
  • gt:大于 >
  • ge:大于等于 >=
  • lt:小于 <
  • le:小于等于 <=
  • between:between 值1 and 值2
  • notBetween:not between 值1 and 值2
  • in:字段 in (value.get(0), value.get(1), ...)
  • notIn:字段 not in (v0, v1, ...)

测试

@Test
public void testBasicConditionStructure(){
    QueryWrapper wrapper = new QueryWrapper<>();
    //SELECT id,user_name,password,name,age,email FROM tb_user WHERE (password = ? AND age >= ? AND name IN (?,?,?)) 
    wrapper.eq("password","222222")
            .ge("age",20)
            .in("name","张三","李四","王五");
    List userList = userMapper.selectList(wrapper);
    for (User user : userList) {
        System.out.println(user);
    }
}

5.3、模糊查询

  • like
    • like '%值%'
    • 例:like("name", "王") ---> name like '%王%'
  • notLike
    • not like '%值%'
    • 例:notLike("name", "王") ---> name not like '%王%'
  • likeLeft
    • like '%值'
    • 例:likeLeft("name", "王") ---> name like '%王'
  • likeRight
    • like '值%'
    • 例:likeRight("name", "王") ---> name like '王%'

测试

@Test
public void testLike(){
    QueryWrapper wrapper = new QueryWrapper<>();
    wrapper.likeLeft("name","五");
    List userList = userMapper.selectList(wrapper);
    for (User user : userList) {
        System.out.println(user);
    }
}

5.4、排序

  • orderBy
    • 排序:order by 字段, ...
    • 例:orderBy(true, true, "id", "name") ---> order by id ASC,name ASC
  • orderByAsc
    • 排序:order by 字段, ... ASC
    • 例:orderByAsc("id", "name") ---> order by id ASC,name ASC
  • orderByDesc
    • 排序:order by 字段, ... desc
    • 例:orderByDesc("id", "name") ---> order by id desc,name desc

测试

@Test
public void testOrderByDesc(){
    QueryWrapper wrapper = new QueryWrapper<>();
    //按照年龄倒序排序:SELECT id,user_name,password,name,age,email FROM tb_user ORDER BY age DESC 
    wrapper.orderByDesc("age");
    List userList = userMapper.selectList(wrapper);
    for (User user : userList) {
        System.out.println(user);
    }
}

5.5、逻辑查询

  • or
    • 拼接 or
    • 主动调用or表示紧接着下一个方法不是用and连接!(不调用or则默认为使用and连接)
  • and
    • and 嵌套
    • 例:and(i -> i.eq("name", "张三").gt("age", 20)) ---> and (name = '张三' and age > 20)

测试

@Test
public void testOr(){
    QueryWrapper wrapper = new QueryWrapper<>();
    //SELECT id,user_name,password,name,age,email FROM tb_user WHERE (name = ? OR age = ?) 
    wrapper.eq("name","王五").or().eq("age",21);
    List userList = userMapper.selectList(wrapper);
    for (User user : userList) {
        System.out.println(user);
    }
}

5.6、select

在mybatis-plus查询中,默认查询所有的字段,如果有需要也可以通过select方法进行指定字段。

测试

@Test
public void testSelect(){
    QueryWrapper wrapper = new QueryWrapper<>();
    //SELECT id,name,age FROM tb_user 
    wrapper.select("id","name","age");
    List userList = userMapper.selectList(wrapper);
    for (User user : userList) {
        System.out.println(user);
    }
}

6、ActiveRecord

ActiveRecord(简称AR)一直广受动态语言(PHP、Ruby等)的喜爱,而Java作为准静态语言,对于ActiveRecord往往只能感叹其优雅,所以我们也在AR道路上进行了一定的探索。

什么是ActiveRecord?

ActiveRecord也属于ORM(对象关系映射)层,由Reils最早提出,遵循标准的ORM模型:表映射到记录,记录映射到对象,字段映射到对象属性。配合遵循的命名和配置惯例,能够很大程度的快速实现模型的操作,而且简洁易懂。

ActiveRecord的主要思想是:

  • 每一个数据库表对应创建一个类,类的每一个对象实例对应于数据库中表的一行记录;通常表的每个字段在类中都有相应的Field;
  • ActiveRecord同时负责把自己持久化,在ActiveRecord中封装了对数据库的访问,即CURD;
  • ActiveRecord是一种领域模型(Domain Model),封装了部分业务逻辑;

6.1、根据主键查询

User.java

package com.example.pojo;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author admin
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("tb_user")
public class User extends Model {
    @TableId(type = IdType.AUTO)
    private int id;
    private String userName;
    private String password;
    private String name;
    private Integer age;
    private String email;
}

测试

package com.example;

import com.example.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class UserTest {

    @Test
    public void testSelectById(){
        User user = new User();
        user.setId(3);
        User userById = user.selectById();
        System.out.println(userById);
    }
}

结果

image

6.2、插入

User.java

package com.example.pojo;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.activerecord.Model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @author admin
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("tb_user")
public class User extends Model {
    @TableId(type = IdType.AUTO)
    private int id;
    private String userName;
    private String password;
    private String name;
    private Integer age;
    private String email;
}

测试

@Test
public void testInsert(){
    User user = new User();
    user.setUserName("pangtong");
    user.setPassword("888888");
    user.setName("庞统");
    user.setAge(36);
    user.setEmail("pangtong@test.com");
    boolean isInsert = user.insert();
    System.out.println("插入是否成功: "+isInsert);
}

6.3、更新

6.3.1、根据id更新

@Test
public void testUpdateById(){
    User user = new User();
    //查询条件
    user.setId(10);
    //更新的数据
    user.setAge(100);
    boolean isUpdate = user.updateById();
    System.out.println("更新是否成功: "+isUpdate);
}

6.3.2、根据条件更新

@Test
public void testUpdate(){
    User user = new User();
    UpdateWrapper wrapper = new UpdateWrapper<>();
    wrapper.eq("name","太史特").set("age",100);
    boolean isUpdate = user.update(wrapper);
    System.out.println("更新是否成功: "+isUpdate);
}

6.4、删除

6.4.1、根据id删除

@Test
public void testDeleteById(){
    User user = new User();
    boolean isDelete = user.deleteById(100);
    System.out.println("删除是否成功: "+isDelete);
}

6.4.2、根据条件删除

@Test
public void testDelete(){
    User user = new User();
    QueryWrapper wrapper = new QueryWrapper<>();
    wrapper.eq("name","太史特");
    boolean isDelete = user.delete(wrapper);
    System.out.println("删除是否成功: "+isDelete);
}

6.5、根据条件查询

@Test
public void testSelectList(){
    User user = new User();
    QueryWrapper wrapper = new QueryWrapper<>();
    //查询年龄大于等于30岁的用户
    wrapper.ge("age",30);
    List userList = user.selectList(wrapper);
    for (User user1 : userList) {
        System.out.println(user1);
    }
}