IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> Mybatis-Plus -> 正文阅读

[Java知识库]Mybatis-Plus

目录

1 、Mybatis-Plus简介

2 、快速入门

2.1、 创建数据库及表

2.2 工程搭建

2.2.1 创建springBoot工程

?

2.2.2 导入依赖

2.2.3 配置application.yml

2.2.4 启动类

2.2.4 编写pojo

2.2.5 编写mapper接口和配置文件

2.2.6?编写测试用例,加入junit的依赖,测试类不能使用Test类名,测试类的包目录和启动类的路径一致

3 通用CRUD

3.1插入操作

3.1.1、方法定义:

3.1.2、测试用例:?

3.1.4、@TableField

3.2、更新操作?

3.2.1、根据id更新

3.2.2、根据条件更新

3.3、删除操作?

3.3.1、deleteById

3.3.2、deleteByMap ?

?3.3.3、delete

3.3.4、deleteBatchIds ?

?3.4、查询操作

3.4.1、selectById单个查询

3.4.2、selectBatchIds ?批量查询

3.4.3、selectOne ?根据条件查询一条数据

3.4.4、selectCount ?根据条件,查询总条数

?3.4.5、selectList 根据条件查询全部记录

?3.4.6、selectPage 根据条件查询全部并分页

?3.5、SQL注入的原理

4、配置

4.1、基本配置

4.1.1、confifigLocation

4.1.2、mapperLocations

4.1.3、typeAliasesPackage

4.2、进阶配置

4.2.1、mapUnderscoreToCamelCase 是否自动开启驼峰命名映射

4.3、DB 相关策略配置

4.3.1、idType

4.3.2、tablePrefifix

5、条件构造器

5.1、allEq

?5.2、基本比较操作

5.3、模糊查询 ?

?5.4、排序

?5.5、逻辑查询

5.6、select

5.7、lambda?

6、Mybatisplus的service的封装

6.1、com.baomidou.mybatisplus.extension.service.IService接口

6. 2、com.baomidou.mybatisplus.extension.service.impl.ServiceImpl类

6.3、测试用例

6.3.1、 自定义业务层接口,继承IService

6.3.2、自定义业务层实现类,继承ServiceImpl:

6.3.3、测试类:

7、代码生成器

7.1、 代码生成说明

7.2、 代码生成

7.2.1、导入依赖

7.2.2、代码生成是基于模板做的,这里采用的freemark模块来生成,把template文件夹放到resources ?

7.2.3、编写生产代码的类CodeGenerator

7.2.4、生成代码

8、MybatisX 快速开发插件



1 、Mybatis-Plus简介

MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。该框架由baomidou(苞米豆)组织开发并且开源的。官网:mybatis.plushttps://mp.baomidou.com/,码云地址:baomidou: 苞米豆,为提高生产率而生!

2 、快速入门

2.1、 创建数据库及表

?

-- 创建测试表
CREATE TABLE `tb_user` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `user_name` varchar(20) NOT NULL COMMENT '用户名',
  `password` varchar(20) NOT NULL COMMENT '密码',
  `name` varchar(30) DEFAULT NULL COMMENT '姓名',
  `age` int(11) DEFAULT NULL COMMENT '年龄',
  `email` varchar(50) DEFAULT NULL COMMENT '邮箱',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

-- 插入测试数据
INSERT INTO `tb_user` (`id`, `user_name`, `password`, `name`, `age`, `email`) VALUES ('1', 'zhangsan', '123456', '张三', '18', 'test1@chen.cn');
INSERT INTO `tb_user` (`id`, `user_name`, `password`, `name`, `age`, `email`) VALUES ('2', 'lisi', '123456', '李四', '20', 'test2@chen.cn');
INSERT INTO `tb_user` (`id`, `user_name`, `password`, `name`, `age`, `email`) VALUES ('3', 'wangwu', '123456', '王五', '28', 'test3@chen.cn');
INSERT INTO `tb_user` (`id`, `user_name`, `password`, `name`, `age`, `email`) VALUES ('4', 'zhaoliu', '123456', '赵六', '21', 'test4@chen.cn');
INSERT INTO `tb_user` (`id`, `user_name`, `password`, `name`, `age`, `email`) VALUES ('5', 'sunqi', '123456', '孙七', '24', 'test5@chen.cn');

2.2 工程搭建

2.2.1 创建springBoot工程

2.2.2 导入依赖

 <!-- 继承Spring boot工程 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.5.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!--简化代码的工具包-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <!--mybatis-plus的springboot支持-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.1.1</version>
        </dependency>
        <!--mysql驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.1.2</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

?log4j.properties:

log4j.rootLogger=DEBUG,A1

log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=[%t] [%c]-[%p] %m%n

2.2.3 配置application.yml

spring:
  application:
    name: mybatisplusspringboot
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/mybatis_plus?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
    username: root
    password: 123
  # 设置Mapper接口所对应的XML文件位置,如果你在Mapper接口中有自定义方法,需要进行该配置
mybatis-plus:
  mapper-locations: classpath*:mybatis/*.xml
  # 设置别名包扫描路径,通过该属性可以给包中的类注册别名
  type-aliases-package: com.chen.mp.pojo

2.2.4 启动类

package com.chen;

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

/**
 * @Author:CHENFAN
 * @Date:2021/12/1418:54
 */
@SpringBootApplication
@MapperScan(basePackages = "com.chen.mp.mapper")//用于扫描mapper接口文件
public class MpApplication {
    public static void main(String[] args) {
        System.out.println("ss");
        SpringApplication.run(MpApplication.class,args);
    }
}

2.2.4 编写pojo

package com.chen.mp.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.Data;

/**
 * @Author:CHENFAN
 * @Date:2021/12/1419:00
 */
@Data//使用lombok完成get和set
@TableName("tb_user")//对应数据库的表名
public class User {
    @TableId(value = "ID",type = IdType.AUTO)
    private Long id;
    @TableField("USER_NAME")//此属性名称和数据库中字段名称不符合,所以显示的映射
    private String userName;//此属性名称和数据库中字段名称相同,所以隐式的映射
    private String password;
    private String name;
    private Integer age;
    private String email;
}


2.2.5 编写mapper接口和配置文件

package com.chen.mp.mapper;

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

/**
 * @Author:CHENFAN
 * @Date:2021/12/1419:11
 */
@Mapper
public interface UserMapper extends BaseMapper<User> {
}

在resources目录下新建一个文件夹mybatis,专门存放mapper配置文件,用于扩展自定义的sql

<?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.chen.mapper.UserMapper">

</mapper>

2.2.6?编写测试用例,加入junit的依赖,测试类不能使用Test类名,测试类的包目录和启动类的路径一致

package com.chen;



import com.chen.mp.mapper.UserMapper;
import com.chen.mp.pojo.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;

/**
 * @Author:CHENFAN
 * @Date:2021/12/1419:07
 */
@RunWith(SpringRunner.class)//使用springrunner运行器
@SpringBootTest(classes = MpApplication.class)//启用springboot测试,加载Springboot配置文件
public class UserMapperTest {

    @Autowired
    private UserMapper userMapper;
    //查询所有
    @Test
    public void testSelectAll(){
        List<User> userList = userMapper.selectList(null);
        System.out.println(userList);
    }

    //查询一个
    @Test
    public void testSelectOne(){
        User user = userMapper.selectById(1);
        System.out.println(user);
    }

    //保存
    @Test
    public void testSave(){
        User user = new User();
        user.setUserName("xiaozhao");
        user.setAge(40);
        user.setPassword("xiaozhao");
        user.setName("小赵");
        user.setEmail("xiaozhao@email.com");
        userMapper.insert(user);
    }

    //修改
    @Test
    public void testUpdate(){
        User user = new User();
        user.setId(1228242594492923909l);
        user.setName("老赵");
        userMapper.updateById(user);
    }

    //删除
    @Test
    public void testDelete(){
        int i = userMapper.deleteById(1228242594492923909l);
    }


}

3 通用CRUD

完成了demo的搭建,接下来查看我们继承的BaseMapper中的单表操作

3.1插入操作

3.1.1、方法定义:

3.1.2、测试用例:?

@Autowired private UserMapper userMapper; 
@Test 
public void testInsert(){ 
User user = new User(); 
user.setAge(20); 
user.setEmail("test@itcast.cn"); 
user.setName("曹操"); 
user.setUserName("caocao"); 
user.setPassword("123456"); 
//返回的result是受影响的行数,并不是自增后的id
int result = this.userMapper.insert(user);  
System.out.println("result = " + result); 
System.out.println(user.getId()); //自增后的id会回填到对象中

如何设置id的生成策略?,MP支持的id策略(查看IdType类):

package com.baomidou.mybatisplus.annotation;

public enum IdType {
    /**
      * 数据库ID自增 
      */ 
    AUTO(0), 
    /**
      * 该类型为未设置主键类型 
      */ 
    NONE(1), 
    /**
      * 用户输入ID 
      * <p>该类型可以通过自己注册自动填充插件进行填充</p> 
      */ 
    INPUT(2), 
    /* 以下3种类型、只有当插入对象ID 为空,才自动填充。 
     */ 
    /**
      * 全局唯一ID (idWorker) 
      */ 
    ID_WORKER(3), 
    /**
      * 全局唯一ID (UUID) 
      */ 
    UUID(4),
    /**
      * 字符串全局唯一ID (idWorker 的字符串表示) 
      */ 
    ID_WORKER_STR(5);
   
    private final int key;

    private IdType(int key) {
        this.key = key;
    }

    public int getKey() {
        return this.key;
    }
}

3.1.4、@TableField

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

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

3.2、更新操作?

?MP中,更新操作有2种,一种是根据id更新,另一种是根据条件更新。

3.2.1、根据id更新

方法定义:

?测试:

@Autowired 
private UserMapper userMapper; 
@Test 
public void testUpdateById() { 
User user = new User(); 
user.setId(6L); //主键 
user.setAge(21); //更新的字段 
//根据id更新,更新不为null的字段 
userMapper.updateById(user); }

3.2.2、根据条件更新

方法定义:

?测试:

第一种:通过QueryMapper对象

@Autowired private UserMapper userMapper; 
@Test 
public void testUpdate() {
User user = new User(); 
user.setAge(22); //更新的字段 
 
QueryWrapper<User> wrapper = new QueryWrapper<>(); 
//更新的条件
wrapper.eq("id", 6); 
//执行更新操作 
int result = this.userMapper.update(user, wrapper); 
System.out.println("result = " + result);

第二种:?UpdateWrapper对象

@Test 
public void testUpdate() { 
//更新的条件以及字段 
UpdateWrapper<User> wrapper = new UpdateWrapper<>(); 
wrapper.eq("id", 6).set("age", 23); 
//执行更新操作 
int result = this.userMapper.update(null, wrapper); 
System.out.println("result = " + result); 
}

3.3、删除操作?

3.3.1deleteById

方法定义:

?测试用例:

@Autowired 
private UserMapper userMapper; 
@Test 
public void testDeleteById() { 
//执行删除操作 
int result = this.userMapper.deleteById(6L); 
System.out.println("result = " + result); 
}

3.3.2deleteByMap ?

方法定义:

测试:

@Autowired 
private UserMapper userMapper; 
@Test 
public void testDeleteByMap() { 
Map<String, Object> columnMap = new HashMap<>(); 
columnMap.put("age",20); 
columnMap.put("name","张三"); 
//将columnMap中的元素设置为删除的条件,多个之间为and关系 
//执行的sql语句:DELETE FROM tb_user WHERE name = ? AND age = ?
int result = this.userMapper.deleteByMap(columnMap); 
System.out.println("result = " + result); 
}

?3.3.3delete

方法定义:

?测试:

@Test 
public void testDeleteByMap() { 
User user = new User(); 
user.setAge(20); 
user.setName("张三"); //将实体对象进行包装,包装为操作条件 
QueryWrapper<User> wrapper = new QueryWrapper<>(user); 
int result = this.userMapper.delete(wrapper); 
System.out.println("result = " + result); 
}

3.3.4deleteBatchIds ?

方法定义:

测试:

@Test 
public void testDeleteByMap() { 
//根据id集合批量删除 
int result = this.userMapper.deleteBatchIds(Arrays.asList(1L,10L,20L)); System.out.println("result = " + result); 
}

?3.4、查询操作

MP提供了多种查询操作,包括根据id查询、批量查询、查询单条数据、查询列表、分页查询等操作。

3.4.1selectById单个查询

方法定义:

?测试:

@Autowired 
private UserMapper userMapper; 
@Test 
public void testSelectById() { 
//根据id查询数据 
User user = this.userMapper.selectById(2L); 
System.out.println("result = " + user); 
}

3.4.2selectBatchIds ?批量查询

方法定义:

?测试:

@Autowired 
private UserMapper userMapper; 
@Test 
public void testSelectBatchIds() {
//根据id集合批量查询 
List<User> users = this.userMapper.selectBatchIds(Arrays.asList(2L, 3L, 10L)); 
for (User user : users) { 
System.out.println(user); 
    } 
}

3.4.3selectOne ?根据条件查询一条数据

方法定义:

?测试:

@Test 
public void testSelectOne() { 
QueryWrapper<User> wrapper = new QueryWrapper<User>(); 
wrapper.eq("name", "李四"); 
//根据条件查询一条数据,如果结果超过一条会报错 
User user = this.userMapper.selectOne(wrapper);
System.out.println(user); 
}

3.4.4selectCount ?根据条件,查询总条数

方法定义:

?测试:

@Test 
public void testSelectCount() { 
QueryWrapper<User> wrapper = new QueryWrapper<User>(); 
//年龄大于23岁 
wrapper.gt("age", 23); 
//根据条件查询数据条数
Integer count = this.userMapper.selectCount(wrapper); 
System.out.println("count = " + count); 
}

?3.4.5selectList 根据条件查询全部记录

方法定义:

?测试:

@Test 
public void testSelectList() { 
QueryWrapper<User> wrapper = new QueryWrapper<User>(); 
//年龄大于23岁
wrapper.gt("age", 23); 
//根据条件查询数据 
List<User> users = this.userMapper.selectList(wrapper); 
for (User user : users) { 
System.out.println("user = " + user); 
    } 
}

?3.4.6selectPage 根据条件查询全部并分页

配置分页插件(自定义一个类):
package com.chen.mp.config;

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

/**
 * @Author:CHENFAN
 * @Date:2021/12/1518:53
 */
@Configurable
@MapperScan("com.chen.mp.mapper") //设置mapper接口的扫描包
public class MybatisPlusConfig {
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor(); }
    }

方法定义:

?测试:

@Test 
public void testSelectPage() { 
QueryWrapper<User> wrapper = new QueryWrapper<User>();
//年龄大于20岁 
wrapper.gt("age", 20);  
//参数:当前页,每页条数
Page<User> page = new Page<>(1,1); 
//根据条件查询数据 
IPage<User> iPage = this.userMapper.selectPage(page, wrapper); 
System.out.println("数据总条数:" + iPage.getTotal()); 
System.out.println("总页数:" + iPage.getPages()); 
List<User> users = iPage.getRecords(); 
for (User user : users) { 
System.out.println("user = " + user); 
    } 
}

?3.5SQL注入的原理

MP 中, ISqlInjector 负责 SQL 的注入工作,它是一个接口, AbstractSqlInjector 是它的实现类,实现关系如下:

?AbstractSqlInjector中,主要是由inspectInject()方法进行注入的,如下:

@Override 
public void inspectInject(
MapperBuilderAssistant builderAssistant, Class<?> 
mapperClass) { 
    Class<?> modelClass = extractModelClass(mapperClass); 
    if (modelClass != null) { 
        String className = mapperClass.toString(); 
        Set<String> mapperRegistryCache = GlobalConfigUtils.getMapperRegistryCache(builderAssistant.getConfiguration()); 
    if (!mapperRegistryCache.contains(className)) { 
        List<AbstractMethod> methodList = this.getMethodList(); 
        if (CollectionUtils.isNotEmpty(methodList)) { 
            TableInfo tableInfo = TableInfoHelper.initTableInfo(builderAssistant, modelClass); 
            // 循环注入自定义方法 
            methodList.forEach(m -> m.inject(builderAssistant, mapperClass, modelClass, tableInfo)); 
         } else {
                    logger.debug(mapperClass.toString() + ", No effective injection method was found.");
         }
          mapperRegistryCache.add(className); 
       } 
    } 
}
在实现方法中, methodList.forEach(m - > m.inject(builderAssistant, mapperClass, modelClass,
tableInfo)) ; 是关键,循环遍历方法,进行注入。
最终调用抽象方法 injectMappedStatement 进行真正的注入:
/**
  * 注入自定义 MappedStatement 
  ** @param mapperClass mapper 接口 
  * @param modelClass mapper 泛型 
  * @param tableInfo 数据库表反射信息 
  * @return MappedStatement 
  */ 
public abstract MappedStatement injectMappedStatement(Class<?> mapperClass, Class<? > modelClass, TableInfo tableInfo);
查看该方法的实现:

?SelectById为例查看:

public class SelectById extends AbstractMethod { 
    @Override public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) { 
        SqlMethod sqlMethod = SqlMethod.LOGIC_SELECT_BY_ID; 
        SqlSource sqlSource = new RawSqlSource(configuration, String.format(sqlMethod.getSql(), 
                sqlSelectColumns(tableInfo, false), 
                tableInfo.getTableName(), 
                tableInfo.getKeyColumn(), 
                tableInfo.getKeyProperty(), 
                tableInfo.getLogicDeleteSql(true, false)), Object.class); 
        return this.addSelectMappedStatement(mapperClass, sqlMethod.getMethod(), sqlSource, modelClass, tableInfo); 
    }
 }
可以看到,生成了 SqlSource 对象,再将 SQL 通过 addSelectMappedStatement方法添加到 MappedStatement 中。

4、配置

MP 中有大量的配置,其中有一部分是 Mybatis 原生的配置,另一部分是 MP 的配置,详情: https://mybatis.plus/c onfifig/
下面我们对常用的配置做讲解

4.1、基本配置

4.1.1confifigLocation

MyBatis 配置文件位置,如果您有单独的 MyBatis 配置,请将其路径配置到 confifigLocation 中。 MyBatis
Confifiguration 的具体内容请参考 MyBatis 官方文档
Spring Boot
mybatis-plus.config-location = classpath:mybatis-config.xml

?Spring MVC

<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean"> 
<property name="configLocation" value="classpath:mybatis-config.xml"/> 
</bean>

4.1.2mapperLocations

Maven 多模块项目的扫描路径需以 classpath*: 开头 (即加载多个 jar 包下的 XML 文件)

MyBatis Mapper 所对应的 XML 文件位置,如果您在 Mapper 中有自定义方法( XML 中有自定义实现),需要进行
该配置,告诉 Mapper 所对应的 XML 文件位置。
Spring Boot
mybatis-plus.mapper-locations = classpath*:mybatis/*.xml
Spring MVC
<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean"> 
<property name="mapperLocations" value="classpath*:mybatis/*.xml"/> 
</bean>

4.1.3typeAliasesPackage

MyBaits 别名包扫描路径,通过该属性可以给包中的类注册别名,注册后在 Mapper 对应的 XML 文件中可以直接使
用类名,而不用使用全限定的类名(即 XML 中调用的时候不用包含包名)。
Spring Boot
mybatis-plus.type-aliases-package = com.chen.mp.pojo
Spring MVC
<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean"> 
<property name="typeAliasesPackage" value="com.baomidou.mybatisplus.samples.quickstart.entity"/> 
</bean>

4.2、进阶配置

本部分( Confifiguration )的配置大都为 MyBatis 原生支持的配置,这意味着您可以通过 MyBatis XML 配置文件的形
式进行配置。

4.2.1mapUnderscoreToCamelCase 是否自动开启驼峰命名映射

  • 类型: boolean
  • 默认值: true
是否开启自动驼峰命名规则( camel case )映射,即从数据库列名 A_COLUMN (下划线命名) 到?Java 属 性名 aColumn (驼峰命名)的类似映射。
注意:
此属性在 MyBatis 中原默认值为 false ,在 MyBatis-Plus 中,此属性也将用于生成最终的 SQL select body
如果您的数据库命名符合规则无需使用 @TableField 注解指定数据库字段名

示例(SpringBoot): ?

#关闭自动驼峰映射,该参数不能和mybatis-plus.config-location同时存在 mybatis-plus.configuration.map-underscore-to-camel-case=false

  • 类型: boolean
  • 默认值: true
全局地开启或关闭配置文件中的所有映射器已经配置的任何缓存,默认为 true
示例:
mybatis-plus.configuration.cache-enabled=false 1

4.3DB 相关策略配置

4.3.1idType

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

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

示例:
SpringBoot
mybatis-plus.global-config.db-config.id-type=auto
SpringMVC
<!--这里使用MP提供的sqlSessionFactory,完成了Spring与MP的整合--> 
<bean id="sqlSessionFactory" 
class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean"> 
    <property name="dataSource" ref="dataSource"/> 
    <property name="globalConfig"> 
        <bean class="com.baomidou.mybatisplus.core.config.GlobalConfig"> 
            <property name="dbConfig"> 
                <bean class="com.baomidou.mybatisplus.core.config.GlobalConfig$DbConfig"> 
                    <property name="idType" value="AUTO"/> 
                </bean> 
            </property> 
         </bean> 
     </property> 
</bean>

4.3.2tablePrefifix

  • 类型: String
  • 默认值: null
表名前缀,全局配置后可省略 @TableName() 配置。
SpringBoot
mybatis-plus.global-config.db-config.table-prefix=tb_
SpringMVC
<bean id="sqlSessionFactory" class="com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean"> 
    <property name="dataSource" ref="dataSource"/> 
    <property name="globalConfig"> 
        <bean class="com.baomidou.mybatisplus.core.config.GlobalConfig"> 
            <property name="dbConfig"> 
                <bean class="com.baomidou.mybatisplus.core.config.GlobalConfig$DbConfig">                     
                     <property name="idType" value="AUTO"/> 
                      <property name="tablePrefix" value="tb_"/> 
                    </bean> </property> 
                </bean> 
            </property> 
        </bean>

5、条件构造器

MP中,Wrapper接口的实现类关系如下:

可以看到, AbstractWrapper AbstractChainWrapper 是重点实现,接下来我们重点学习 AbstractWrapper 以及其子类。
说明 :
QueryWrapper(LambdaQueryWrapper) UpdateWrapper(LambdaUpdateWrapper) 的父类 用于生成 sql
where 条件 , entity 属性也用于生成 sql where 条件 注意 : entity 生成的 where 条件与 使用各个 api 生成
where 条件 没有任何关联行为

5.1allEq

方法重载1:

allEq(Map<R, V> params) 
allEq(Map<R, V> params, boolean null2IsNull) 
allEq(boolean condition, Map<R, V> params, boolean null2IsNull)
  • 全部eq(或个别isNull)
个别参数说明 : params : key 为数据库字段名 , value 为字段值 null2IsNull : true 则在 map value
null 时调用 isNull 方法 , false 时则忽略 value null
1: allEq({id:1,name:" 老王 ",age:null}) ---> id = 1 and name = ' 老王 ' and age is null
2: allEq({id:1,name:" 老王 ",age:null}, false) ---> id = 1 and name = ' 老王 '

?实例1:

QueryWrapper<User> wrapper = new QueryWrapper<>();
        //设置条件
        Map<String,Object> params = new HashMap<>();
        params.put("name", "曹操");
        params.put("age", "20");
        params.put("password", null);
        wrapper.allEq(params);
        userMapper.selectList(wrapper);

结果:?

实例2:

 QueryWrapper<User> wrapper = new QueryWrapper<>();
        //设置条件
        Map<String,Object> params = new HashMap<>();
        params.put("name", "曹操");
        params.put("age", "20");
        params.put("password", null);
        wrapper.allEq(params,false);
        userMapper.selectList(wrapper);

结果:?

?方法重载2:

allEq(BiPredicate<R, V> filter, Map<R, V> params) 
allEq(BiPredicate<R, V> filter, Map<R, V> params, boolean null2IsNull) 
allEq(boolean condition, BiPredicate<R, V> filter, Map<R, V> params, boolean null2IsNull)
个别参数说明 : filter : 过滤函数 ,为true时 允许设置的字段条件传入
params null2IsNull : 同上
1: allEq((k,v) - > k.indexOf("a") > 0, {id:1,name:" 老王 ",age:null}) ---> name = ' 老王 '
and age is null
2: allEq((k,v) - > k.indexOf("a") > 0, {id:1,name:" 老王 ",age:null}, false) ---> name =
' 老王 '

过滤条件为false的实例:

 QueryWrapper<User> wrapper = new QueryWrapper<>();
        //设置条件
        Map<String,Object> params = new HashMap<>();
        params.put("name", "曹操");
        params.put("age", "20");
        params.put("password", null);
        //SELECT ID,USER_NAME,password,name,age,email FROM tb_user
        //此时filter结果为false,不传入比对条件
        wrapper.allEq((k, v) -> (k.equals("na") || k.equals("ag")),params);

?结果:

?过滤条件为true的实例:

QueryWrapper<User> wrapper = new QueryWrapper<>();
        //设置条件
        Map<String,Object> params = new HashMap<>();
        params.put("name", "曹操");
        params.put("age", "20");
        params.put("password", null);
        //SELECT ID,USER_NAME,password,name,age,email FROM tb_user WHERE name = ? AND age = ?
        wrapper.allEq((k, v) -> (k.equals("name") || k.equals("age")),params);
        userMapper.selectList(wrapper);

结果:

?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, ...)??

测试用例:?

   QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("password", "123456") .ge("age", 20) .in("name", "李四", "王五", "赵六");
        List<User> users = this.userMapper.selectList(wrapper);
        for (User user : users) { 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 ' %'

测试实例:

QueryWrapper<User> wrapper = new QueryWrapper<>(); 
//SELECT id,user_name,password,name,age,email FROM tb_user WHERE name LIKE ? 
//Parameters: %陈%(String) wrapper.like("name", "c陈"); 
List<User> users = this.userMapper.selectList(wrapper); 
for (User user : users) { 
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

测试用例:

QueryWrapper<User> wrapper = new QueryWrapper<>(); 
//SELECT id,user_name,password,name,age,email FROM tb_user ORDER BY age DESC wrapper.orderByDesc("age"); 
List<User> users = this.userMapper.selectList(wrapper); 
for (User user : users) { System.out.println(user); 
}

?5.5、逻辑查询

or
????????拼接 OR
????????主动调用 or 表示紧接着下一个 方法 不是用 and 连接 !( 不调用 or 则默认为使用 and 连接 )
and
????????AND 嵌套
????????例: and(i - > i.eq("name", " 李白 ").ne("status", " 活着 ")) ---> and (name = ' 李白 ' and status
<> ' 活着 ')

?测试用例:

QueryWrapper<User> wrapper = new QueryWrapper<>(); 
//SELECT id,user_name,password,name,age,email FROM tb_user WHERE name = ? OR age = ? 
wrapper.eq("name","李四").or().eq("age", 24); 
List<User> users = this.userMapper.selectList(wrapper); 
for (User user : users) { System.out.println(user); 
}

5.6select

MP 查询中,默认查询所有的字段,如果有需要也可以通过 select 方法进行指定字段。
测试用例:
//SELECT id,name,age FROM tb_user WHERE name = ? OR age = ? 
wrapper.eq("name", "李四") .or() .eq("age", 24) 
.select("id", "name", "age"); 
List<User> users = this.userMapper.selectList(wrapper); for (User user : users) { System.out.println(user); 
}

5.7、lambda?

MP 对于查询 Wrapper API 提供了 LambdaQueryWrapper 来很好的解决此问题。通过 Lambda 方法引用,获得实体类属性和表的对应映射关系,再做表的字段查询。

测试用例:

//构建 LambdaQueryWrapper 
        LambdaQueryWrapper<User> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        //使用 LambdaQueryWrapper 构建查询条件
        lambdaQueryWrapper.eq(User::getName, "李四")
                .or()
                .eq(User::getAge, 24);

        //进行信息查询
        List<User> users = this.customerMapper.selectList(lambdaQueryWrapper);
        for (User user : users) {
            System.out.println(user);
        }

6、Mybatisplus的service的封装

Mybatis-Plus为了开发更加快捷,对业务层也进行了封装,直接提供了相关的接口和实现类。我们在进行业务层开发时,可以继承它提供的接口和实现类,使得编码更加高效。

6.1、com.baomidou.mybatisplus.extension.service.IService接口

该接口是一个泛型接口,里面提供了很多方法,包括基本的增删改查。

6. 2、com.baomidou.mybatisplus.extension.service.impl.ServiceImpl类

该类实现了上面接口中的所有方法。

6.3、测试用例

6.3.1、 自定义业务层接口,继承IService

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper,User> implements UserService {

}

6.3.2、自定义业务层实现类,继承ServiceImpl:

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper,User> implements UserService {

}

6.3.3、测试类:

 @Autowired
    private UserService userService;

    @Test
    public void testInsert() {
        User user = new User();
        user.setEmail("123@chen.cn");
        user.setAge(301);
        user.setUserName("caocao1");
        user.setName("曹操1");
        user.setPassword("123456");

        userService.save(user);

        //获取自增长后的id值, 自增长后的id值会回填到user对象中
        System.out.println("id => " + user.getId());
    }

7、代码生成器

7.1、 代码生成说明

当有一个新的业务实现时,对接口的功能实现上,我们通常来说需要构建下面的信息:

  • PO类

    数据库表和实体类的映射 Java Bean。

  • DAO层

    需要编写接口 Mapper ,接口 Mapper 需要去继承 MP 中的 BaseMapper 接口。

  • Service层

    编写 Service 层接口和实现类。业务接口需要去继承 MP 中的 IService,业务实现类需要继承 MP 中的 ServiceImpl 和 实现业务接口。

  • Controller层

    编写 Controller 并标注 Spring MVC 中的相关注解。

从上面的各类代码中可以放下,代码都是模板性的,如果用手工copy、修改的方式来实现,太烦人也没效率,而这时就是代码生成器小展身手的时候,使用代码生成器生成模板性的代码,减少手工操作的繁琐,集中精力在业务开发上,提升开发效率。

AutoGenerator 是 MyBatis-Plus 的代码生成器,通过 AutoGenerator 可以快速生成 Mapper接口、Entity实体类、Mapper XML、Service、Controller 等各个模块的代码,极大的提升了开发效率

7.2、 代码生成

7.2.1、导入依赖

<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.30</version>
</dependency>
<dependency>
    <groupId>io.swagger</groupId>
    <artifactId>swagger-annotations</artifactId>
    <version>1.5.20</version>
</dependency>

7.2.2、代码生成是基于模板做的,这里采用的freemark模块来生成,把template文件夹放到resources ?

7.2.3、编写生产代码的类CodeGenerator

package com.chen.mp.generator;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;

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

/**
 * MyBatis-Plus 代码生成类
 */
public class CodeGenerator {

	// TODO 修改服务名以及数据表名
	private static final String SERVICE_NAME = "mp";

	private static final String DATA_SOURCE_USER_NAME  = "root";
	private static final String DATA_SOURCE_PASSWORD  = "123";
	private static final String[] TABLE_NAMES = new String[]{
			"tb_user"
	};

	// TODO 默认生成entity,需要生成DTO修改此变量
	// 一般情况下要先生成 DTO类 然后修改此参数再生成 PO 类。
	private static final Boolean IS_DTO = false;

	public static void main(String[] args) {
		// 代码生成器
		AutoGenerator mpg = new AutoGenerator();
		// 选择 freemarker 引擎,默认 Velocity
		mpg.setTemplateEngine(new FreemarkerTemplateEngine());
		// 全局配置
		GlobalConfig gc = new GlobalConfig();
		gc.setFileOverride(true);
		gc.setOutputDir(System.getProperty("user.dir") + "/src/main/java");
		gc.setAuthor("chenfan");
		gc.setOpen(false);
		gc.setSwagger2(false);
		gc.setServiceName("%sService");
        gc.setBaseResultMap(true);
        gc.setBaseColumnList(true);

		if (IS_DTO) {
			gc.setSwagger2(true);
			gc.setEntityName("%sDTO");
		}
		mpg.setGlobalConfig(gc);

		// 数据库配置
		DataSourceConfig dsc = new DataSourceConfig();
		dsc.setDbType(DbType.MYSQL);
		dsc.setUrl("jdbc:mysql://localhost:3306/mybatis_plus?useUnicode=true&useSSL=false&characterEncoding=utf8");
		dsc.setDriverName("com.mysql.jdbc.Driver");
		dsc.setUsername(DATA_SOURCE_USER_NAME);
		dsc.setPassword(DATA_SOURCE_PASSWORD);
		mpg.setDataSource(dsc);

		// 包配置
		PackageConfig pc = new PackageConfig();
		pc.setModuleName(SERVICE_NAME);
		pc.setParent("com.chen");

		pc.setServiceImpl("service.impl");
		pc.setXml("mapper");
		mpg.setPackageInfo(pc);


        // 自定义配置
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() {
                // to do nothing
            }
        };
        List<FileOutConfig> focList = new ArrayList<>();
        focList.add(new FileOutConfig("/templates/mapper.xml.ftl") {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输入文件名称
                return System.getProperty("user.dir") + "/src/main/resources/mapper/" +
                        tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
            }
        });
        cfg.setFileOutConfigList(focList);
        mpg.setCfg(cfg);

		// 设置模板
		TemplateConfig tc = new TemplateConfig();
		mpg.setTemplate(tc);

		// 策略配置
		StrategyConfig strategy = new StrategyConfig();
		strategy.setNaming(NamingStrategy.underline_to_camel);
		strategy.setColumnNaming(NamingStrategy.underline_to_camel);
		strategy.setEntityLombokModel(true);
		strategy.setRestControllerStyle(true);
		strategy.setInclude(TABLE_NAMES);
		strategy.setControllerMappingHyphenStyle(true);
		strategy.setTablePrefix(pc.getModuleName() + "_");
		// Boolean类型字段是否移除is前缀处理
		strategy.setEntityBooleanColumnRemoveIsPrefix(true);
		strategy.setRestControllerStyle(true);
		mpg.setStrategy(strategy);

		mpg.execute();
	}

}

参数说明:

7.2.4、生成代码

执行CodeGenerator类中的main方法,就可以生成文件

8、MybatisX 快速开发插件

MybatisX 是一款基于 IDEA 的快速开发插件,为效率而生。

安装方法:打开 IDEA,进入 File -> Settings -> Plugins ->输入 mybatisx 搜索并安装。

功能:

  • Java 与 XML 调回跳转

  • Mapper 方法自动生成 XML

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-12-16 17:32:20  更:2021-12-16 17:34:08 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/20 22:32:48-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码