springboot如何整合mybatisPlus

springboot整合mybatis-plus、logback、druid、MySQL

入门案例

  1. 新建一个快速初始化springboot项目
  2. 添加依赖
        <!--数据库驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!---->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
		</dependency>
        <!--单元测试-->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
        <!--mybatis-plus开发必须的依赖,作用:Lombok通过增加一些“处理程序”,可以让java变得简洁、快速。-->
		<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.2</version>
		</dependency>
  1. 配置文件
spring:
 datasource:
  driverClassName: com.mysql.cj.jdbc.Driver
  url: jdbc:mysql://127.0.0.1:3306/easyapp?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC
  username: root
  password: root
  1. 目录结构

入门案例的目录结构是手动创建的,后面的项目实际开发中我们采用代码生成的方式。
在这里插入图片描述

  • TestUser.java
package com.example.demo.entity;

import lombok.Data;

@Data
public class TestUser {
    private Long id;
    private String username;
    private Integer age;
 //   private String email;
}
  • UserMapper.java
package com.example.demo.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.demo.entity.TestUser;

public interface UserMapper extends BaseMapper<TestUser> {

}
  • DemoApplication.java
package com.example.demo;

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

@SpringBootApplication
@MapperScan("com.example.demo.mapper")  //必须定义扫描包路径
public class DemoApplication {

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

}

DemoApplicationTests.java

package com.example.demo;

import com.example.demo.entity.TestUser;
import com.example.demo.mapper.UserMapper;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;
import java.util.List;

@RunWith(SpringRunner.class)
@SpringBootTest
public class DemoApplicationTests {

	@Resource
	private UserMapper userMapper;

	@Test
	public void testSelect() {
		System.out.println(("----- selectAll method test ------"));
		List<TestUser> userList = userMapper.selectList(null);
		Assert.assertEquals(2, userList.size());
		userList.forEach(System.out::println);
	}
}
  1. 思考
  • mybatis和mybatis-plus与springboot整合的区别在哪?
  1. 最直接的区别:导入的依赖不同。
    2. mybatis需要在配置文件里面指定mapper与mapper.xml的映射路径,mybatis-plus不需要指定路径。
    3. mybatis需要在各个应用类和mapper.xml中写代码,mybatis-plus对其进行了封装,只需要调用接口即可。
  • 你会发现service层、service实现层、mapper层都没有注解。mybatis有@service、@Mapper注解。
  • lombok使用方法

此处只讲好处,具体使用方式去网上找:Lombok能以简单的注解形式来简化java代码,提高开发人员的开发效率。例如开发中经常需要写的javabean,都需要花时间去添加相应的getter/setter,也许还要去写构造器、equals等方法,而且需要维护,当属性多时会出现大量的getter/setter方法,这些显得很冗长也没有太多技术含量,一旦修改属性,就容易出现忘记修改对应方法的失误。
Lombok能通过注解的方式,在编译时自动为属性生成构造器、getter/setter、equals、hashcode、toString方法。出现的神奇就是在源码中没有getter和setter方法,但是在编译生成的字节码文件中有getter和setter方法。这样就省去了手动重建这些代码的麻烦,使代码看起来更简洁些。

  • 注意的地方
  1. pom文件导入mybatis-plus与springboot的依赖就行了,千万不要再去导入mybatis和springboot的依赖,会产生冲 突的(耗费了我半下午的时间认识到这个教训)。
    2. 导入mybatis-plus和springboot的依赖注意:你导入的是 mybatis-plus-spring-boot-starter而不是mybatisplus-spring-boot-starter。后者少了一个“-”,但是系统不会报错,因为缺少也存在mybatisplus-spring-boot-starter这个依赖,但是不是我们需要的那个依赖(被百度坑死了,给我的整合依赖就是后者,后来看官方文档才发现不对劲的)。

springboot整合mybatis-plus到我们的真实项目中

1. 添加依赖

<!--==============mybatisplus与springboot整合依赖-============-->
   	<!-- mybatisplus与springboot整合 。。这个依赖根本就不能用,根本做不到和我们的springboot2.x整合,以后必须去官方文档上面找整合的依赖,那一定是正确的-->
   	<!--<dependency>
   		<groupId>com.baomidou</groupId>
   		<artifactId>mybatisplus-spring-boot-starter</artifactId>
   		<version>1.0.5</version>
   	</dependency>-->
   	<!--官方依赖-->
   	<dependency>
   		<groupId>com.baomidou</groupId>
   		<artifactId>mybatis-plus-boot-starter</artifactId>
   		<version>3.1.2</version>
   	</dependency>
   	<!-- MyBatis Plus 核心库   。。。。 官方文档表示不需要添加这个依赖,我们的springboot和mybatis-plus就可以满足了 -->
   	<!--<dependency>
   		<groupId>com.baomidou</groupId>
   		<artifactId>mybatis-plus</artifactId>
   		<version>3.1.2</version>
   	</dependency>-->
   	<groupId>org.springframework.boot</groupId>
   		<artifactId>spring-boot-starter-test</artifactId>
   		<scope>test</scope>
   	</dependency>
   	<!--mybatis-plus代码生成器依赖-->
   	<dependency>
   		<groupId>org.projectlombok</groupId>
   		<artifactId>lombok</artifactId>
   		<optional>true</optional>
   	</dependency>
   	<!--添加 模板引擎 依赖,MyBatis-Plus 支持 Velocity(默认)、Freemarker、Beetl,,如果都不满足您的要求,可以采用自定义模板引擎。-->
       <dependency>
           <groupId>org.apache.velocity</groupId>
           <artifactId>velocity-engine-core</artifactId>
           <version>2.1</version>
       </dependency>
   	<!--Freemarker模板依赖-->
   	<dependency>
   		<groupId>org.freemarker</groupId>
   		<artifactId>freemarker</artifactId>
   		<version>2.3.28</version>
   	</dependency>
   	<!--mybatisplus的代码生成器依赖-->
   	<dependency>
   		<groupId>com.baomidou</groupId>
   		<artifactId>mybatis-plus-generator</artifactId>
   		<version>3.1.2</version>
   	</dependency>
<!--最操蛋的:下面的这个依赖是绝对绝对绝对绝对绝度不能加上的,会和mybatis-plus依赖打架。把下午毁在了这个依赖上面了,就是因为多加了这个依赖
   我是怎么找到这个依赖的?
    误信了网友,他的文档里面就包含这个mybatis整合springboot依赖。
    没有重视官方文档,官方文档根本就没有提及mybatis整合springboot这个依赖。
-->
   <!--	<dependency>
   		<groupId>org.mybatis.spring.boot</groupId>
   		<artifactId>mybatis-spring-boot-starter</artifactId>
   		<version>1.3.1</version>
   	</dependency>-->

其实归根到底:自己走了一下午的弯路就是因为自己在看官方文档之前就从网上瞎折腾,找了那几个最不该引入进来的依赖(mybatis整合springboot依赖和那个该死的mybatisplus-springboot-start依赖),然后和官方的依赖打架。
如果自己最开始的时候就按照官方文档来,就不会出这个乱子了。 -----------官方才是最靠谱的。

2. 配置文件

保持之前的那个配置文件即可。

3. 使用代码生成器

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

代码生成器位置

在这里插入图片描述

因为我们主程序位置不可乱动,所以我们选择在这里新建main方法。

代码生成器
package com.hdeasy;

import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
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.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class MpGenerator {
    /**
     * <p>
     * 读取控制台内容
     * </p>
     */
    public static String scanner(String tip) {
        Scanner scanner = new Scanner(System.in);
        StringBuilder help = new StringBuilder();
        help.append("请输入" + tip + ":");
        System.out.println(help.toString());
        if (scanner.hasNext()) {
            String ipt = scanner.next();
            if (StringUtils.isNotEmpty(ipt)) {
                return ipt;
            }
        }
        throw new MybatisPlusException("请输入正确的" + tip + "!");
    }
    public static void main(String[] args) {
        // 代码生成器
        AutoGenerator mpg = new AutoGenerator();

        // 全局配置
        GlobalConfig gc = new GlobalConfig();
        String projectPath = System.getProperty("user.dir");
        gc.setOutputDir(projectPath + "/src/main/java");
        //设置作者
        gc.setAuthor("易适培训");
        gc.setOpen(false);
        // gc.setSwagger2(true); 实体属性 Swagger2 注解
        mpg.setGlobalConfig(gc);

        // 数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://localhost:3306/easyapp?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=UTC&nullCatalogMeansCurrent=true");
        // dsc.setSchemaName("public");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("root");
        mpg.setDataSource(dsc);

        // 包配置
        PackageConfig pc = new PackageConfig();
        pc.setModuleName(scanner("模块名"));//会把你在控制器输出的模块名赋值给modulename
        pc.setParent("com.hdeasy");
        /*下面的我没有配置,而是采用模板默认的名称*/
//        pc.setParent("com");
//        pc.setModuleName("warrior");
//        pc.setController("controler");
//        pc.setEntity("entity");
//        pc.setMapper("mapper");
//        pc.setService("service");
//        pc.setServiceImpl("serviceImpl");
//        pc.setXml("mapperXml");
        mpg.setPackageInfo(pc); //com.hdeasy.模板名

        // 自定义配置
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() {
                // to do nothing
            }
        };

        // 如果模板引擎是 freemarker
        String templatePath = "/templates/mapper.xml.ftl";
        // 如果模板引擎是 velocity---->这个模板不要用,会报错。2
         //String templatePath = "/templates/mapper.xml.vm";

        // 自定义输出配置
        List<FileOutConfig> focList = new ArrayList<>();
        // 自定义配置会被优先输出
        focList.add(new FileOutConfig(templatePath) {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
                return projectPath + "/src/main/resources/mybatis/" + pc.getModuleName()
                        + "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
            }
        });
        /*
        cfg.setFileCreate(new IFileCreate() {
            @Override
            public boolean isCreate(ConfigBuilder configBuilder, FileType fileType, String filePath) {
                // 判断自定义文件夹是否需要创建
                checkDir("调用默认方法创建的目录");
                return false;
            }
        });
        */
        cfg.setFileOutConfigList(focList);
        mpg.setCfg(cfg);

        // 配置模板
        TemplateConfig templateConfig = new TemplateConfig();

        // 配置自定义输出模板
        //指定自定义模板路径,注意不要带上.ftl/.vm, 会根据使用的模板引擎自动识别
        // templateConfig.setEntity("templates/entity2.java");
        // templateConfig.setService();
        // templateConfig.setController();

        templateConfig.setXml(null);
        mpg.setTemplate(templateConfig);

        // 策略配置
        StrategyConfig strategy = new StrategyConfig();
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);

        //这是默认继承一个父类entity
       // strategy.setSuperEntityClass("com.baomidou.ant.common.BaseEntity");

        strategy.setEntityLombokModel(true);
        strategy.setRestControllerStyle(true);

        // 公共父类,这是默认继承一个父类control
       // strategy.setSuperControllerClass("com.baomidou.ant.common.BaseController");

        // 写于父类中的公共字段。 因为我们没有采用继承父类,所以这一行代码必须注释掉,要不然生成的entity代码里面没有主键属性。
        //strategy.setSuperEntityColumns("id");
        strategy.setInclude(scanner("表名,多个英文逗号分割").split(","));
        // Controller驼峰连字符,如开启,则requestMapping由 helloWorld 变为 hello-world 默认false
        strategy.setControllerMappingHyphenStyle(true);
        strategy.setTablePrefix(pc.getModuleName() + "_");
        mpg.setStrategy(strategy);
        mpg.setTemplateEngine(new FreemarkerTemplateEngine());
        mpg.execute();
    }

}


生成的目录结构

在这里插入图片描述

4. 主程序中定义mapper扫描路径

package com.hdeasy;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@MapperScan("com.hdeasy.*.mapper")//扫描指定路径下的mapper
@SpringBootApplication
public class EasyApplication {
	public static void main(String[] args) {
		SpringApplication.run(EasyApplication.class, args);
		System.out.println("===============易适软件APP-启动成功=================");
	}
}

5.测试类


@RunWith(SpringRunner.class)
@SpringBootTest
public class AppApplicationTests {
    @Autowired
	private TestUserMapper testUserMapper;
    @Test
   public void setTestUserMapper(){
		List<TestUser> testUsers =testUserMapper.selectList(null);
		Assert.assertEquals(2,testUsers.size());
		testUsers.forEach(System.out::println);
   }
}

开启自动映射功能

虽然mybatisplus提供了我们大量的crud操作,但是我们可能也需要写自己的crud,这时需要配置我们的mapper接口与mapper.xml的映射路径.

mybatisplus是mybatis的增强,是在mybatis的基础上面做了很多crud接口,满足了我们大部分需求,保留了mybatis原有的功能。

  1. 配置文件配置映射路径
mybatis-plus:
  #除了mybatisplus提供给我们的自定义的crud功能,我们可能也需要写自己的crud,这时需要配置我们的mapper接口与mapper.xml的映射路径
  mapper-locations: mybatis/**/*Mapper.xml
  typeAliasesPackage: com.hdeasy.**.entity
  1. TestUserMapper.java
package com.hdeasy.easytest.mapper;

import com.hdeasy.easytest.entity.TestUser;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;

/**
 * <p>
 *  Mapper 接口
 * </p>
 *
 * @author 易适培训
 * @since 2019-07-24
 */
public interface TestUserMapper extends BaseMapper<TestUser> {

    TestUser get(Long id);

}
  1. TestUserMapper.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.hdeasy.easytest.mapper.TestUserMapper">

    <select id="get" resultType="com.hdeasy.easytest.entity.TestUser">
        select `id`,`username`,`isDelete`,`memo` from test_user where id = #{value}
    </select>
</mapper>
  1. 测试类

    @Autowired
	private TestUserMapper testUserMapper;
     @Test
   public void setTestUserMapper(){
		TestUser testUser = testUserMapper.get((long) 1);
	   System.out.println(testUser);
   }
  1. 注意:
    主程序中不能再去添加扫描包了,要不然会重复:
package com.hdeasy;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
//@MapperScan("com.hdeasy.*.mapper")  //如果是mybatis需要在主程序中扫描,但是mybatisplus不需要扫描(我们的接口继承的basemapper类已经注入到容器里面了,如果还写上扫描就注入两次了)
@SpringBootApplication
public class EasyApplication {
	public static void main(String[] args) {
		SpringApplication.run(EasyApplication.class, args);
		System.out.println("===============易适软件APP-启动成功=================");
	}
}

SpringBoot+MybatisPlus制定事务

  1. 事务概念
    是数据库操作的最小工作单元,是作为单个逻辑工作单元执行的一系列操作;这些操作作为一个整体一起向系统提交,要么都执行、要么都不执行;事务是一组不可再分割的操作集合(工作逻辑单元);
  2. 事务特性
  • 原子性:即不可分割性,事务要么全部被执行,要么就全部不被执行。

  • 一致性或可串性。事务的执行使得数据库从一种正确状态转换成另一种正确状态

  • 隔离性。在事务正确提交之前,不允许把该事务对数据的任何改变提供给任何其他事务,

  • 持久性。事务正确提交后,其结果将永久保存在数据库中,即使在事务提交后有了其他故障,事务的处理结果也会得到保存。

简单理解:在事务里的操作,要么全部成功,要么全部失败。

MybatisPlus逻辑删除

  • application.yml 加入配置(如果你的默认值和mp默认的一样,该配置可无):
mybatis-plus:
 #除了mybatisplus提供给我们的自定义的crud功能,我们可能也需要写自己的crud,这时需要配置我们的mapper接口与mapper.xml的映射路径
 mapper-locations: mybatis/**/*Mapper.xml
 typeAliasesPackage: com.hdeasy.**.entity
 #配置mybatis-plus全局逻辑删除
 global-config:
   db-config:
     logic-delete-value: 1 # 逻辑已删除值(默认为 1)
     logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
  • 数据库表字段结构
    在这里插入图片描述

idDelete是我们设置的逻辑删除字段

  • 实体类添加逻辑删除注解 @TableLogic
package com.hdeasy.easytest.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableField;
import java.io.Serializable;

import com.baomidou.mybatisplus.annotation.TableLogic;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;

/**
 * <p>
 * 
 * </p>
 *
 * @author 易适培训
 * @since 2019-07-24
 */
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
public class TestUser implements Serializable {

    private static final long serialVersionUID = 1L;

    /**
     * 主键
     */
    @TableId(value = "id", type = IdType.AUTO)
    private Long id;

    /**
     * 用户名
     */
    private String username;     

    /**
     * 年龄
     */
    private Integer age;

    /**
     * 逻辑删除
     */
    @TableLogic                 //表示该字段为逻辑删除字段
    @TableField("isDelete")     //表字段标识,驼峰命名
    private Integer isDelete;

    /**
     * 备注
     */
    private String memo;


}

  • 测试类进行测试
  @Autowired
	private TestUserMapper testUserMapper;
@Test
   public void setTestUserMapper(){
		List<TestUser> testUsers =testUserMapper.selectList(null);
		if(testUsers.size()>0) {
			Assert.assertEquals(2, testUsers.size());
			testUsers.forEach(System.out::println);
		}
   }

查询的最终结果为0。因为我们的表中的isDelete字段为1,表示的是逻辑删除

扩展

  1. 安装MybatisX
    MybatisX呢是用于Java 与 XML 调回跳转、Mapper 方法自动生成 XML 。以前我们在写mapper的时候呢,都是在mapper.java中定义好方法,然后手动跳转到mapper.xml中去写sql。那么在使用了MybatisX之后呢,我们在编写mapper.java的时候呢,在左侧可以看到Mybatis的小鸟标志。点击就可以进入到对应的方法中,也可以使用control+鼠标左键进行跳转了。并且它会像接口与实现类的关系,自动为你生成代码,非常方便。
  2. 安装Lombok
    使用Lombok还需要插件的配合,我使用开发工具为idea,这里只讲解idea中安装lombok插件,打开idea的设置,点击Plugins,点击Browse repositories,在弹出的窗口中搜索lombok,然后安装即可。

我们代码生成器生成的实体类使用的就是lombok,必须安装他的插件才能更好的使用他的功能(否则你连get、set方法都调不出来)。

使用mybatis-plus简单介绍

场景:根据用户名查到这条数据(用户名唯一):

        //QueryWrapper:参数封装类
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        //使用条件构造器
        queryWrapper.eq("username",username);
        //使用mybatis-plus提供的crud
         SysUser user = sysUserMapper.selectOne(queryWrapper);

到对应的方法中,也可以使用control+鼠标左键进行跳转了。并且它会像接口与实现类的关系,自动为你生成代码,非常方便。
2. 安装Lombok
使用Lombok还需要插件的配合,我使用开发工具为idea,这里只讲解idea中安装lombok插件,打开idea的设置,点击Plugins,点击Browse repositories,在弹出的窗口中搜索lombok,然后安装即可。

我们代码生成器生成的实体类使用的就是lombok,必须安装他的插件才能更好的使用他的功能(否则你连get、set方法都调不出来)。

使用mybatis-plus简单介绍

场景:根据用户名查到这条数据(用户名唯一):

        //QueryWrapper:参数封装类
        QueryWrapper<SysUser> queryWrapper = new QueryWrapper<>();
        //使用条件构造器
        queryWrapper.eq("username",username);
        //使用mybatis-plus提供的crud
         SysUser user = sysUserMapper.selectOne(queryWrapper);
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@来杯咖啡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值