spring boot集成mybatis-plus——Mybatis Plus 新增数据并返回主键 ID(图文讲解)

Posted 小白龙白龙马

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了spring boot集成mybatis-plus——Mybatis Plus 新增数据并返回主键 ID(图文讲解)相关的知识,希望对你有一定的参考价值。

Mybatis Plus 新增数据并返回主键 ID(图文讲解)

 更新时间 2023-01-10 15:37:37

大家好,我是小哈。

本小节中,我们将学习如何通过 Mybatis Plus 框架给数据库表新增数据,主要内容思维导图如下:

Mybatis Plus 新增数据思维导图

表结构

为了演示新增数据,在前面小节中,我们已经定义好了一个用于测试的用户表, 执行脚本如下:

DROP TABLE IF EXISTS t_user;

CREATE TABLE `t_user` ( `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '主键ID', `name` varchar(30) NOT NULL DEFAULT '' COMMENT '姓名', `age` int(11) NULL DEFAULT NULL COMMENT '年龄', `gender` tinyint(2) NOT NULL DEFAULT 0 COMMENT '性别,0:女 1:男', PRIMARY KEY (`id`) ) COMMENT = '用户表'; 

定义实体类

定义一个名为 User 实体类:

@Data
@TableName("t_user")
public class User 
    /**
     * 主键 ID, @TableId 注解定义字段为表的主键,type 表示主键类型,IdType.AUTO 表示随着数据库 ID 自增
     */
    @TableId(type = IdType.AUTO) private Long id; /** * 姓名 */ private String name; /** * 年龄 */ private Integer age; /** * 性别 */ private Integer gender;  

讲解一下实体类中用到的注解:

@TableName 表名注解

作用:标识实体类对应的表。

TIP :

  • 当实体类名称和实际表名一致时,如实体名为 User, 表名为 user ,可不用添加该注解,Mybatis Plus 会自动识别并映射到该表。
  • 当实体类名称和实际表名不一致时,如实体名为 User, 表名为 t_user,需手动添加该注解,并填写实际表名称。

@TableId 主键注解

作用:声明实体类中的主键对应的字段。

属性类型必须指定默认值描述
valueString""主键字段名
typeEnumIdType.NONE指定主键类型

IdType 主键类型

描述
AUTO数据库 ID 自增
NONE无状态,该类型为未设置主键类型(默认)
INPUT插入数据前,需自行设置主键的值
ASSIGN_ID分配 ID(主键类型为 Number(Long 和 Integer)或 String)(since 3.3.0),使用接口IdentifierGenerator的方法nextId(默认实现类为DefaultIdentifierGenerator雪花算法)
ASSIGN_UUID分配 UUID,主键类型为 String(since 3.3.0),使用接口IdentifierGenerator的方法nextUUID (默认 default 方法)
ID_WORKER分布式全局唯一 ID 长整型类型 (推荐使用 ASSIGN_ID)
UUID32 位 UUID 字符串 (推荐使用 ASSIGN_UUID)
ID_WORKER_STR分布式全局唯一 ID 字符串类型 (推荐使用 ASSIGN_ID)

开始新增数据

测试表准备好后,我们准备开始演示新增数据。实际上,Mybatis Plus 对 Mapper 层和 Service 层都将常见的增删改查操作都封装好了,只需简单的继承,即可轻松搞定对数据的增删改查,本文重点讲解新增数据这块。

Mapper 层

定义一个 UserMapper , 让其继承 BaseMapper :

public interface UserMapper extends BaseMapper<User>   

然后,注入 Mapper :

@Autowired
private UserMapper userMapper;

BaseMapper 提供的新增方法仅一个 insert() 方法:

我们通过它测试一下添加数据,并获取主键 ID :

User user =new User();
user.setName("犬小哈");
user.setAge(30);
user.setGender(1);

userMapper.insert(user);

// 获取插入数据的主键 ID Long id = user.getId(); System.out.println("id:" + id); 

怎么样,是不是非常简单呢!

Service 层

Mybatis Plus 同样也封装了通用的 Service 层 CRUD 操作,并且提供了更丰富的方法。接下来,我们上手看 Service 层的代码结构,如下图:

定义 Service 层

先定义 UserService 接口 ,让其继承自 IService:

public interface UserService extends IService<User>   

再定义实现类 UserServiceImpl,让其继承自 ServiceImpl, 同时实现 UserService 接口,这样就可以让 UserService 拥有了基础通用的 CRUD 功能,当然,实际开发中,业务会更加复杂,就需要向 IService 接口自定义方法并实现:

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

注入 UserService :

@Autowired
private UserService userService;

与 Mapper 层不同的是,Service 层的新增方法均以 save 开头,并且功能更丰富,来看看都提供了哪些方法:

新增数据共有 6 个方法

简单解释下每个方法的作用,以作了解:

// 新增数据
sava(T) : boolean
// 伪批量插入,实际上是通过 for 循环一条一条的插入
savaBatch(Collection<T>) : boolean
// 伪批量插入,int 表示批量提交数,默认为 1000 savaBatch(Collection<T>, int) : boolean // 新增或更新(单条数据) saveOrUpdate(T) : boolean // 批量新增或更新 saveOrUpdateBatch(Collection<T>) : boolean // 批量新增或更新(可指定批量提交数) saveOrUpdateBatch(Collection<T>, int) : boolean 

大致看完后,上手测试一下。

sava(T)

简单的新增数据,示例代码如下:

// 新增数据
// 实际执行 SQL :INSERT INTO user ( name, age, gender ) VALUES ( '小哈 111', 30, 1 ) User user = new User(); user.setName("小哈 111"); user.setAge(30); user.setGender(1); boolean isSuccess = userService.save(user); // 返回主键ID Long id = user.getId(); System.out.println("isSuccess:" + isSuccess); System.out.println("主键 ID: " + id); 

savaBatch(Collection)

伪批量插入,注意,命名虽然包含了批量的意思,但这不是真的批量插入,不信的话,我们来实际测试一下:

// 批量插入
List<User> users = new ArrayList<>();
for (int i = 0; i < 5; i++)  User user = new User(); user.setName("犬小哈" + i); user.setAge(i); user.setGender(1); users.add(user);  boolean isSuccess = userService.saveBatch(users); System.out.println("isSuccess:" + isSuccess); 

执行代码,实际执行的 SQL 如下:

TIP : 如何打印实际执行的 SQL, 可参考之前小节的 《Mybatis Plus 打印 SQL 语句(包含执行耗时)》 

批量插入输入 SQL 打印

可以看到,并不是 insert into user (xxx) values (xxx),(xxx),(xxx) 这种批量形式,还是一条一条插入的。

批量新增源码分析

我们来看下源码, 内部的saveBatch() 方法默认的批量提交阀值参数,数值为 1000, 即达到 1000 条批量提交一次,继续点进去看::

源码分析

public boolean saveBatch(Collection<T> entityList, int batchSize)  // 获取预编译的插入 SQL String sqlStatement = this.getSqlStatement(SqlMethod.INSERT_ONE); // for 循环执行 insert return this.executeBatch(entityList, batchSize, (sqlSession, entity) ->  sqlSession.insert(sqlStatement, entity); );  

再看下 SqlMethod.INSERT_ONE 这个枚举,描述信息为插入一条数据

继续往 executeBatch() 方法里看,瞅瞅它这个批量到底是怎么处理的,具体每行代码的意思,小哈都加了注释:

public static <E> boolean executeBatch(Class<?> entityClass, Log log, Collection<E> list, int batchSize, BiConsumer<SqlSession, E> consumer)  // 断言需要批处理数据集大小不等于1 Assert.isFalse(batchSize < 1, "batchSize must not be less than one", new Object[0]); // 判空数据集,若不为空,则开始执行批量处理 return !CollectionUtils.isEmpty(list) && executeBatch(entityClass, log, (sqlSession) ->  int size = list.size(); // 将批处理大小与传入的操作集合大小进行比较,取最小的那个 int idxLimit = Math.min(batchSize, size); int i = 1; // 迭代器循环 for(Iterator var7 = list.iterator(); var7.hasNext(); ++i)  // 获取当前需要执行的数据库操作 E element = var7.next(); // 回调 sqlSession.insert() 方法 consumer.accept(sqlSession, element); // 判断是否达到需要批处理的阀值 if (i == idxLimit)  // 开始批处理,此方法执行并清除缓存在 JDBC 驱动类中的执行语句 sqlSession.flushStatements(); idxLimit = Math.min(idxLimit + batchSize, size);   );  

看完就明白了,相比较自己手动 for 循环执行插入,Mybatis Plus 这个伪批量插入性能会更好些,内部会将每次的插入语句缓存起来,等到达到 1000 条的时候,才会统一推给数据库,虽然最终在数据库那边还是一条一条的执行 INSERT,但还是在和数据库交互的 IO 上做了优化。

savaBatch(Collection, int)

多了个 batchSize 参数,可以手动指定批处理的大小,即多少 SQL 操作执行一次,默认为 1000。

saveOrUpdate(T)

保存或者更新。即当你需要执行的数据,数据库中不存在时,就执行插入操作:

// 实际执行 SQL :INSERT INTO user ( name, age, gender ) VALUES ( '小小哈', 60, 1 ) User user = new User(); user.setName("小小哈"); user.setAge(60); user.setGender(1); userService.saveOrUpdate(user); 

当你需要执行的数据,数据库中已存在时,就执行更新操作。框架是如何判断该记录是否存在呢? 如设置了主键 ID,因为主键 ID 必须是唯一的,Mybatis Plus 会先执行查询操作,判断数据是否存在,存在即执行更新,否则,执行插入操作:

User user =new User();
// 设置了主键字段
user.setId(21L);
user.setName("小小哈");
user.setAge(60); user.setGender(1); userService.saveOrUpdate(user); 

具体执行 SQL 如下:

saveOrUpdateBatch(Collection)

批量保存或者更新,示例代码如下:

List<User> users =new ArrayList<>();
for (int i = 0; i < 5; i++)  User user = new User(); user.setId(Long.valueOf(i)); user.setName("犬小哈" + i); user.setAge(i+1); user.setGender(1); users.add(user);  userService.saveOrUpdateBatch(users); 

saveOrUpdateBatch(Collection, int)

批量保存或者更新(可手动指定批量大小),示例代码如下:

List<User> users =new ArrayList<>();
for (int i = 0; i < 5; i++)  User user = new User(); user.setId(Long.valueOf(i)); user.setName("犬小哈" + i); user.setAge(i+1); user.setGender(1); users.add(user);  userService.saveOrUpdateBatch(users, 100);

spring boot整合mybatis-plus

spring boot整合mybatis-plus

简介

mybatis 增强工具包,简化 CRUD 操作。 文档
http://mp.baomidou.com
http://mybatis.plus

优点 | Advantages

  • 无侵入:Mybatis-Plus 在 Mybatis 的基础上进行扩展,只做增强不做改变,引入 Mybatis-Plus 不会对您现有的 Mybatis 构架产生任何影响,而且 MP 支持所有 Mybatis 原生的特性
  • 依赖少:仅仅依赖 Mybatis 以及 Mybatis-Spring
  • 损耗小:启动即会自动注入基本CURD,性能基本无损耗,直接面向对象操作
  • 预防Sql注入:内置Sql注入剥离器,有效预防Sql注入***
  • 通用CRUD操作:内置通用Mapper、通用Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
  • 多种主键策略:支持多达4种主键策略(内含分布式唯一ID生成器),可自由配置,完美解决主键问题
  • 支持热加载:Mapper 对应的 XML 支持热加载,对于简单的 CRUD 操作,甚至可以无 XML 启动
  • 支持ActiveRecord:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可实现基本 CRUD 操作
  • 支持代码生成:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用(P.S. 比 Mybatis 官方的 Generator 更加强大!)
  • 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
  • 支持关键词自动转义:支持数据库关键词(order、key......)自动转义,还可自定义关键词
  • 内置分页插件:基于Mybatis物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于写基本List查询
  • 内置性能分析插件:可输出Sql语句以及其执行时间,建议开发测试时启用该功能,能有效解决慢查询
  • 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,预防误操作

前面已经 创建了一个springboot项目,我们直接在该项目上整合mybatis-plus

准备工作

  • pom.xml jar引入: <mybatis-plus.version>3.0.6</mybatis-plus.version>

     <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>${mybatis-plus.version}</version>
        </dependency>
    
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus</artifactId>
            <version>${mybatis-plus.version}</version>
        </dependency>
  • 创建表
    CREATE TABLE `my_info` (
    `id` int(10) NOT NULL AUTO_INCREMENT,
    `name` varchar(255) DEFAULT NULL,
    `age` int(3) DEFAULT NULL,
    PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

    项目结构

    创建基本的项目结构,controller、dao、entity、service(impl)
    如图:
    技术图片

controller :

@RestController
public class MyInfoController {
    @Resource
    MyInfoService myInfoService;

    @GetMapping("myInfo")
    public String myInfo(@RequestParam Integer id) {
        MyInfo myInfo = myInfoService.getById(id);
        return myInfo.toString();
    }
}

dao :

public interface MyInfoMapper extends BaseMapper<MyInfo> {

}

entity :

@Data
@TableName(value = "my_info")
public class MyInfo {
    @TableId(type = IdType.AUTO)
    private Integer id;

    private String name;

    private Integer age;
}

service :

public interface MyInfoService {

     MyInfo getById(int id);
}

impl :

@Service("myInfoService")
public class MyInfoServiceImpl extends ServiceImpl<MyInfoMapper,MyInfo> implements MyInfoService {
    @Override
    public MyInfo getById(int id) {
        return baseMapper.selectById(id);
    }
}

当前,我们也可以在xml中自定义sql( MyInfoMapper.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.honghh.bootfirst.dao.MyInfoMapper">
    <!--自定义SQL-->
</mapper>

application.yml 配置文件内容如下

spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/boot_demo
    username: root
    password: 123456
#mybatis
mybatis-plus:
  mapper-locations: classpath*:mapper/**/*.xml
  #实体扫描,多个package用逗号或者分号分隔
  typeAliasesPackage: com.honghh.bootfirst.entity
  global-config:
    #主键类型  0:"数据库ID自增", 1:"用户输入ID",2:"全局唯一ID (数字类型唯一ID)", 3:"全局唯一ID UUID";
    id-type: 0
    #字段策略 0:"忽略判断",1:"非 NULL 判断"),2:"非空判断"
    field-strategy: 2
    #驼峰下划线转换
    db-column-underline: true
    #刷新mapper 调试神器
    refresh-mapper: true
    #数据库大写下划线转换
    #capital-mode: true
    # Sequence序列接口实现类配置
    #key-generator: com.baomidou.mybatisplus.incrementer.OracleKeyGenerator
    #逻辑删除配置
    #logic-delete-value: -1
    #logic-not-delete-value: 0
    #自定义填充策略接口实现
    #meta-object-handler: com.baomidou.springboot.xxx
    #自定义SQL注入器
    sql-injector: com.baomidou.mybatisplus.mapper.LogicSqlInjector
  configuration:
    map-underscore-to-camel-case: true
    cache-enabled: false
    call-setters-on-nulls: true

启动项目

完成上面的步骤,准备工作将近完成,现在开始启动项目,但是你会发现项目启动不起来,报错如下:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘myInfoController‘: Injection of resource dependencies failed; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘myInfoService‘: Unsatisfied dependency expressed through field ‘baseMapper‘; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type ‘com.honghh.bootfirst.dao.MyInfoMapper‘ available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessProperties(CommonAnnotationBeanPostProcessor.java:324) ~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1395) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:592) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:849) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:877) ~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.__refresh(AbstractApplicationContext.java:549) ~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.jrLockAndRefresh(AbstractApplicationContext.java:40002) ~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:41008) ~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:142) ~[spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775) [spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) [spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:316) [spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260) [spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248) [spring-boot-2.1.3.RELEASE.jar:2.1.3.RELEASE]
    at com.honghh.bootfirst.BootFirstApplication.main(BootFirstApplication.java:11) [classes/:na]
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name ‘myInfoService‘: Unsatisfied dependency expressed through field ‘baseMapper‘; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type ‘com.honghh.bootfirst.dao.MyInfoMapper‘ available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:596) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:374) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1395) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:592) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:204) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.resolveBeanByName(AbstractAutowireCapableBeanFactory.java:452) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:526) ~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:496) ~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:636) ~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:180) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessProperties(CommonAnnotationBeanPostProcessor.java:321) ~[spring-context-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    ... 19 common frames omitted
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type ‘com.honghh.bootfirst.dao.MyInfoMapper‘ available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1654) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1213) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1167) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:593) ~[spring-beans-5.1.5.RELEASE.jar:5.1.5.RELEASE]
    ... 35 common frames omitted

上网查了一下,说一般是下面原因造成的:

  • 1.applicationContext.xml配置中没有扫描包
  • 2.controller层的@controller或者service层的@Service注解没写
  • 3.service注入mapper失败

   仔细看了下代码是mapper层没有注入,mapper注入方法有一下几种方式。

  • 1.直接在mapper上写注解
@Mapper
public interface MyInfoMapper extends BaseMapper<MyInfo> {

}
  • 2.在启动类上添加注解
@EnableTransactionManagement
@SpringBootApplication
@MapperScan("com.honghh.*.dao")

public class BootFirstApplication {

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

}

   mybatis-config中只是会为对应的mapper创建代理类,而想真正包装成bean,注入到spring容器中,还是需要靠AutoConfiguredMapperScannerRegistrar,它会根据扫描@Mapper注释或是@MapperScan指定的包下的接口,将其注册为bean。

  • 3.也可以写一个配置类 MybatisPlusConfig
@Configuration
@MapperScan(basePackages = "com.honghh.*.dao")
public class MybatisPlusConfig {
    /**
     * mybatis-plus 分页插件
     */
    @Bean
    public PerformanceInterceptor performanceInterceptor() {
        return new PerformanceInterceptor();
    }
}

  在浏览器中输入 :http://localhost:8080/myInfo?id=1 显示如下
技术图片
成功!!!此时你已经学会了整合mybatis-plus

参考文本

https://gitee.com/baomidou/mybatisplus-spring-boot

文章来源 : https://blog.csdn.net/qq_35098526/article/details/87782961

以上是关于spring boot集成mybatis-plus——Mybatis Plus 新增数据并返回主键 ID(图文讲解)的主要内容,如果未能解决你的问题,请参考以下文章

「Spring Boot架构」集成Mybatis-Plus的实例详解

spring boot 集成 mybatis-plus 报错 java.lang.TypeNotPresentException: Type [unknown] not present

Spring Boot 2.X:集成 mybatis-plus 高效开发

spring boot集成mybatis-plus——Mybatis Plus 新增数据并返回主键 ID(图文讲解)

MyBatis-Plus 集成动态多数据源

spring boot+mybatis-plus整理