MyBatisPlus SpringBoot入门使用

一、MyBatis Plus 介绍

MyBatis Plus 是国内人员开发的 MyBatis 增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。MybatisX 是一款基于 IDEA 的快速开发插件,为效率而生。

MyBatis Plus 的核心功能有:支持通用的 CRUD、代码生成器与条件构造器。

  • 通用 CRUD:定义好 Mapper 接口后,只需要继承 BaseMapper 接口即可获得通用的增删改查功能,无需编写任何接口方法与配置文件
  • 条件构造器:通过 EntityWrapper (实体包装类),可以用于拼接 SQL 语句,并且支持排序、分组查询等复杂的 SQL
  • 代码生成器:支持一系列的策略配置与全局配置,比 MyBatis的代码生成更好用
/***
 * 通用删除操作 deleteBatchIds 通过多个ID进行删除
 */
@Test
public void testDeleteBatchIds() {
	List idList = new ArrayList();
	idList.add(5);
	idList.add(6);
	int result = employeeMapper.deleteBatchIds(idList);
	System.out.println("*******************" + result);
}

public void selectIn() {
    QueryWrapper wrapper = new QueryWrapper<>();
    wrapper.setSqlSelect(WinAgent.COL_ID);
    wrapper.in(WinAgent.COL_AG_NUM, new String[]{"11","22","33","44"});
    userMapper.selectList(wrapper);
}
/**
 * 根据条件构造器删除
 */
public void testDeleteByWrapper(){
    QueryWrapper wrapper = new QueryWrapper<>();
    // 参数1-字段名,参数2-匹配的值
    wrapper.eq("user_name", "lisi");
    // count代表删除成功的记录数
    int count = userMapper.delete(wrapper);
}
/***
 * 通用更新操作
 */
@Test
public void testUpdateOrInsert() {
	Employee entity = new Employee();
	entity.setId(1);
	entity.setName("更新测试成功");
	int result = employeeMapper.updateById(entity);
	//int result = employeeMapper.insert(entity);
}

public void testUpdate() {
	Employee entity = new Employee();
	entity.setName("更新测试成功");
    QueryWrapper queryWrapper = new QueryWrapper<>();
    queryWrapper.eq("id", "1");
	int result = employeeMapper.update(entity, queryWrapper);
}

/**
 * 查询所有数据
 * UserMapper 中的 selectList() 方法的参数
 * 为 MP 内置的条件封装器 Wrapper,所以不填写就是无任何条件(条件构造器)
 */
@Test
public void selectList() {
    List list = userMapper.selectList(null);
    list.forEach(System.out::println);
}

/**
 * 根据 entity 条件,查询一条记录
 * 其实 QueryWrapper 条件构造器(相当于给SQL的条件语句)
 * selectOne() 方法查询必须有且只能查询一条记录,多一条会报错。
 */
@Test
public void selectOne() {
    QueryWrapper queryWrapper = new QueryWrapper<>();
    //查询名字为 Tom 的一条记录
    queryWrapper.eq("name", "Tom");
    User user = userMapper.selectOne(queryWrapper);
    System.out.println(user);
}

/**
 * 根据主键ID查询数据
 * 查询主键id=2 的一条数据,只能查询一个主键的数据不能多个
 */
@Test
public void selectById() {
    User user = userMapper.selectById(2);
    System.out.println(user);
}

/**
 * 根据 List 的 ID 集合 查询对应的用户list
 */
@Test
public void selectBatchIds() {
    List list = userMapper.selectBatchIds(Arrays.asList(5, 3, 1));
    list.forEach(System.out::println);
}

/**
 * 查询(根据 columnMap 条件),查询年龄为20岁的所有记录
 * 

* 注意:建议尽量减少使用map这种方式。 * 因为可能字段名可能存在修改的情况, * 如果,项目开发一段时间后,再修改,影响太大 */ @Test public void selectByMap() { Map map = new HashMap<>(); map.put("age", "20"); List list = userMapper.selectByMap(map); list.forEach(System.out::println); } /** * 查询大于20岁的学生,名称中包含“J”的人,带条件判断的,可以采用这种方式 * SELECT * FROM user WHERE (name LIKE ? AND age > ?) * gt()方法 相当于:大于 > 但没有等于= */ @Test public void selectListWrapper() { QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.like("name", "J");//格式:(字段,值) queryWrapper.gt("age", "19"); //查询不小于20岁 List list = userMapper.selectList(queryWrapper); list.forEach(System.out::println); } /** * 根据 Wrapper 条件,查询全部记录。 * 查询名字含有 a 的,且年龄大于等于20。 * ge()方法 相当于: 大于等于 >= 。 * like()方法 相当于: NOT LIKE '%值%' 。 */ @Test public void selectMaps() { QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.like("name", "a"); queryWrapper.ge("age", "20"); List> maps = userMapper.selectMaps(queryWrapper); maps.forEach(System.out::println); } /** * 根据 entity 条件,查询全部记录(并翻页)。 * 查询年龄大于 18 且 小于等于30 岁的所有记录,分 3 条数记录为一页 * gt()方法 相当于: 大于 > 。 * le()方法 相当于: 小于等于 <= 。 */ @Test public void selectPage() { QueryWrapper queryWrapper = new QueryWrapper<>(); queryWrapper.gt("age", "18"); queryWrapper.le("age", "30"); //第一个参数表示当前页 //第二个参数表示当前页显示多少条 //第三个参数是否查询count Page page = new Page<>(1, 3); Page userIPage = userMapper.selectPage(page, queryWrapper); List records = userIPage.getRecords(); records.forEach(System.out::println); } /** * 根据 Wrapper 条件,查询全部记录(并翻页) */ @Test public void selectMapsPage() { QueryWrapper query = new QueryWrapper(); //第一个参数表示当前页 //第二个参数表示当前页显示多少条 Page> page = new Page<>(2, 3); Page> maps = userMapper.selectMapsPage(page, query); maps.getRecords().forEach(System.out::println); } /** * 根据 Wrapper 条件,查询总记录数 * 查询一共有多少条数据记录 */ @Test public void selectCount() { QueryWrapper queryWrapper = new QueryWrapper<>(); Integer count = userMapper.selectCount(queryWrapper); System.out.printf("一共有" + String.valueOf(count) + "条记录"); }

queryWrapper是mybatis plus中实现查询的对象封装操作类.。注意这是因为我的mybatisplus的版本是3.2版本,只有3.x的版本才有QueryWrapper而如果是2.x版本,是没有QueryWrapper的,如果找不到QueryWrapper,可以在配置里将mybatisplus的版本改为3.x

2.2.0

或者使用EntityWrapper,两者的功能其实差不多。 

条件参数说明

MyBatisPlus SpringBoot入门使用_第1张图片

MyBatisPlus SpringBoot入门使用_第2张图片

MyBatisPlus SpringBoot入门使用_第3张图片


二、MyBatis Plus 集成 Spring

数据表结构

CREATE TABLE user
(
    id BIGINT(20) NOT NULL COMMENT '主键ID',
    name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
    age INT(11) NULL DEFAULT NULL COMMENT '年龄',
    email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
    PRIMARY KEY (id)
);

INSERT INTO user (id, name, age, email) VALUES
(1, 'Jone', 18, '[email protected]'),
(2, 'Jack', 20, '[email protected]'),
(3, 'Tom', 28, '[email protected]'),
(4, 'Sandy', 21, '[email protected]'),
(5, 'Billie', 24, '[email protected]');

创建一个 SpringBoot 项目。
  方式一:去官网 https://start.spring.io/ 初始化一个,然后导入 IDE 工具即可。
  方式二:直接使用 IDE 工具创建一个。 Spring Initializer。

MyBatisPlus SpringBoot入门使用_第4张图片

添加 MyBatis-Plus 依赖(mybatis-plus-boot-starter)


    com.baomidou
    mybatis-plus-boot-starter
    3.3.1

使用 mysql,需要引入 mysql 相关依赖。为了简化代码,引入 lombok 依赖


    mysql
    mysql-connector-java


    org.projectlombok
    lombok
    1.18.10




    org.mapstruct
    mapstruct 


    org.mapstruct
    mapstruct-jdk8




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

完整pom.xml 文件



    4.0.0
    
        org.springframework.boot
        spring-boot-starter-parent
        2.2.6.RELEASE
         
    
    com.lyh.test
    test-mybatis-plus
    0.0.1-SNAPSHOT
    test-mybatis-plus
    测试 -- 测试 MyBatis-Plus 功能

    
        1.8
    

    
        
            com.baomidou
            mybatis-plus-boot-starter
        
        
            mysql
            mysql-connector-java
        
        
            org.projectlombok
            lombok
            1.18.10
        

        
            org.springframework.boot
            spring-boot-starter
            3.3.1
        

        
            org.springframework.boot
            spring-boot-starter-test
            test
            
                
                    org.junit.vintage
                    junit-vintage-engine
                
            
        
    

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    

在 resources/application.yml 文件中配置 mysql 数据源信息。

server:
  port: 2525

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

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

三、快速体验 MyBatis Plus

实体类

package entity;

import lombok.Data;

@Data
public class User {
    private Long id;
    private String name;
    private int age;
    private String email;
}

mapper 接口,这是 mybatis-plus 封装好的类。

package mapper;

import entity.User;

import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.Constants;

import java.util.List;

public interface UserMapper extends BaseMapper {
    //@Select("SELECT * FROM user where name = #{name}")
    //List selectByName(@Param("name") String name);
    
    //传入对象参数xml方式
    //List selectAllUsers(@Param("user") User user, @Param("bm") String bm);
}

实体类、Mapper 类都写好了,就可以使用了。接口绑定有两种实现方式,一种是通过注解绑定,就是在接口的方法上面加上@Select@Update 等注解里面包含 Sql 语句来绑定,另外一种就是通过xml 里面写 SQL 来绑定,在这种情况下,要指定 xml 映射文件里面的namespace 必须为接口的全路径名。当 Sql 语句比较简单时候,用注解绑定;当 SQL 语句比较复杂时候,用 xml 绑定,一般用 xml 绑定的比较多

添加UserMapper.xml文件(可省略) 

对于$和#的用法区别

简单来说 #{} 会在将参数加上引号,而${}并不会在给参数加上引号。mybatis对参数没有进行任何的处理。通常${}用于GROUP BY,ORDER BY,IN等的后面
但是,实际应用中,并不提倡使用 ${},因为使用 #{} 写法,除了可以防止sql注入以外,还能在参数里含有单引号的时候自动转义





    
    

resultType返回基本类型 java.lang.String

ServiceImpl层

@Service
public class UserServiceImpl extends ServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    public Integer getUserNum() {
        return userMapper.findUserCount();
    }

    // 增
    @Override
    public int insertUser(User user) {
        return baseMapper.insert(user);
    }
    
    // 改
    @Override
    public int updateUser(User user) {
        return baseMapper.updateById(user);
    }
    
    // 删
    @Override
    public int deleteUser(User user) {
        return baseMapper.deleteById(user.getUserId());
    }
    
    // 查
    @Override
    public User findUserByName(String userName) {
        return baseMapper.getUserByName(userName);
    }

    // 分页查
    @Override
    public IPage getUserPage(Page page, User user) {
        return baseMapper.getUsersPage( page, user );
    }
}

Service层

public interface UserService extends IService {
  
   Integer getUserNum();

   int insertUser( User user );
   int updateUser( User user );
   int deleteUser( User user );
   User findUserByName( String userName );
   IPage getUserPage( Page page, User user );

Step1:先得在启动类里扫描 Mapper 类,即添加 @MapperScan 注解

package com.lyh.test.testmybatisplus;

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

@MapperScan("mapper")
//@MapperScan({"com.kfit.*.mapper","org.kfit.*.mapper"})
@SpringBootApplication
public class TestMybatisPlusApplication {

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

}

多module项目扫描失败解决: Consider defining a bean of type 'xxx' in your configuration

@SpringBootApplication(scanBasePackages = {"com.xx.xx.xx.A", "com.xx.xx.common"})

Step2:写一个测试类测试一下。

package com.lyh.test.testmybatisplus;

import entity.User;
import mapper.UserMapper;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
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 TestMybatisPlusApplicationTests {

    @Autowired
    private UserMapper userMapper;

    @Test
    public void testSelect() {
        System.out.println(("----- selectAll method test ------"));
        List userList = userMapper.selectList(null);
        for(User user:userList) {
            System.out.println(user);
        }
    }

    @Test
    public void testSelectBySql() {
        LambdaQueryWrapper wrapper = new LambdaQueryWrapper();
        wrapper.like("name" , "k").lt("age", 40).last("limit 4");

        List userList = userMapper.selectBySql(wrapper);
        userList.forEach(System.out::println);
    }
}

MyBatisPlus SpringBoot入门使用_第5张图片

上面几个例子中,并没有在 UserMapper 接口中定义任何方法,也没有在配置文件中编写 SQL 语句,而是通过继承 BaseMapper 接口获得通用的的增删改查方法,复杂的 SQL 也可以使用条件构造器拼接。通过这两种方式已经能够满足很多的开发需求了,不过复杂的业务需求还是要编写 SQL 语句的,流程和 MyBatis 一样。

想要查看执行的 sql 语句,可以在 application.yml 文件中添加配置信息,如下

mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

若遇到 @Autowired 标记的变量出现 红色下划线,但是不影响 正常运行。可以进入 Settings,找到 Inspection,并选择其中的 Spring Core -> Code -> Autowiring for Bean Class,将 Error 改为 Warning,即可。

MyBatisPlus SpringBoot入门使用_第6张图片

四、代码生成器

package com.example.demo;

import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;

/**
 * MybatisPlus代码生成器
 */
public class MybatisPlusGeneratorRunner {
    public static final String MYSQL_DRIVER = "com.mysql.cj.jdbc.Driver";
    //模块名 如果有模块名,则需在模块名前加. 例:log
    public static final String MODULE_NAME = "";
    public static final String AUTHOR = "danny";
    public static final String MYSQL_URL = "jdbc:mysql://locallhost:3306/test?serverTimezone=UTC";
    public static final String USERNAME = "root";
    public static final String PASSWORD = "0rb!t";
    public static final String[] DB_TABLE_NAMES = {"user", "role"};
    public static final String PACKAGE_NAME = "cn.kerninventory.mybatis";

    public static void main(String[] args) {
        AutoGenerator generator = new AutoGenerator();
        //配置数据库连接参数
        DataSourceConfig dataSourceConfig = new DataSourceConfig();
        dataSourceConfig.setDriverName(MYSQL_DRIVER);
        dataSourceConfig.setUrl(MYSQL_URL);
        dataSourceConfig.setUsername(USERNAME);
        dataSourceConfig.setPassword(PASSWORD);
        generator.setDataSource(dataSourceConfig);

        //配置文件生成路径参数
        PackageConfig packageConfig = new PackageConfig();
        packageConfig.setModuleName(MODULE_NAME);
        packageConfig.setParent(PACKAGE_NAME);
        packageConfig.setEntity("entity");
        packageConfig.setXml("xml");
        packageConfig.setMapper("mapper");
        //packageConfig.setServiceImpl("serviceimpl");
        packageConfig.setService("service");
        packageConfig.setController("controller");
        generator.setPackageInfo(packageConfig);

        //策略配置
        StrategyConfig strategyConfig = new StrategyConfig();
        //表名转驼峰
        strategyConfig.setNaming(NamingStrategy.underline_to_camel);
        //字段驼峰命名
        strategyConfig.setColumnNaming(NamingStrategy.underline_to_camel);
        //set方法builder模式
        strategyConfig.setChainModel(true);
        //使用lombok注解
        strategyConfig.setEntityLombokModel(true);
        //不生成serial version uuid
        //strategyConfig.setEntitySerialVersionUID(false);
        //要生成的表名
        strategyConfig.setInclude(DB_TABLE_NAMES);
        //rest风格
        strategyConfig.setRestControllerStyle(true);
        //是否生成字段常量
		strategyConfig.setEntityColumnConstant(true);
        //是否生成实体时,生成字段注解
        strategyConfig.setEntityTableFieldAnnotationEnable(true);
        generator.setStrategy(strategyConfig);

        //全局配置
        GlobalConfig globalConfig = new GlobalConfig();
        globalConfig.setServiceName("%sService");
		globalConfig.setXmlName("mapper");
        globalConfig.setBaseResultMap(true);  //XML中的ResultMap标签
        globalConfig.setBaseColumnList(true); //XML标签
        globalConfig.setOpen(false); //不弹出生成目录
        //输出目录
        globalConfig.setOutputDir(System.getProperty("user.dir") + "/src/main/java");
        globalConfig.setAuthor(AUTHOR);
        generator.setGlobalConfig(globalConfig);
        generator.execute();
    }
}

五、@TableField注解

  • @TableField(exist = false) 注解加载bean属性上,表示当前属性不是数据库的字段,但在项目中必须使用,这样在新增等使用bean的时候,mybatis-plus就会忽略这个,不会报错
  • @TableField(.. , update="%s+1") 其中 %s 会填充为字段。输出 SQL 为:update 表 set 字段=字段+1 @TableField(.. , update="now()") 输出 SQL 为:update 表 set 字段=now() where 
  • @TableField(condition = SqlCondition.LIKE) 输出 SQL 为:select 表 where name LIKE CONCAT('%',值,'%')
  • @TableField(fill = FieldFill.INSERT)的字段进行自动填充

其他

Java计时StopWatch的使用方法详解

StopWatch 是位于 org.springframework.util 包下的一个工具类,通过它可方便的对程序部分代码进行计时(ms级别),适用于同步单线程代码块。简单总结一句,Spring提供的计时器StopWatch对于秒、毫秒为单位方便计时的程序,尤其是单线程、顺序执行程序的时间特性的统计输出支持比较好。也就是说假如我们手里面有几个在顺序上前后执行的几个任务,而且我们比较关心几个任务分别执行的时间占用状况,希望能够形成一个不太复杂的日志输出,StopWatch提供了这样的功能。而且Spring的StopWatch基本上也就是仅仅为了这样的功能而实现。

想要使用它,首先你需要在你的 Maven 中引入 Spring 核心包,当然 Spring MVC 和 Spring Boot 都已经自动引入了该包:



    org.springframework
    spring-core
    ${spring.version}

对一切事物的认知,都是从使用开始,那就先来看看它的用法,会如下所示:

public static void main(String[] args) throws InterruptedException {
    StopWatch stopWatch = new StopWatch();

    // 任务一模拟休眠3秒钟
    stopWatch.start("TaskOneName");
    Thread.sleep(1000 * 3);
    System.out.println("当前任务名称:" + stopWatch.currentTaskName());
    stopWatch.stop();

    // 任务一模拟休眠10秒钟
    stopWatch.start("TaskTwoName");
    Thread.sleep(1000 * 10);
    System.out.println("当前任务名称:" + stopWatch.currentTaskName());
    stopWatch.stop();

    // 任务一模拟休眠10秒钟
    stopWatch.start("TaskThreeName");
    Thread.sleep(1000 * 10);
    System.out.println("当前任务名称:" + stopWatch.currentTaskName());
    stopWatch.stop();

    // 打印出耗时
    System.out.println(stopWatch.prettyPrint());
    System.out.println(stopWatch.shortSummary());
    // stop后它的值为null
    System.out.println(stopWatch.currentTaskName()); 
    
    // 最后一个任务的相关信息
    System.out.println(stopWatch.getLastTaskName());
    System.out.println(stopWatch.getLastTaskInfo());
    
    // 任务总的耗时  如果你想获取到每个任务详情(包括它的任务名、耗时等等)可使用
    System.out.println("所有任务总耗时:" + sw.getTotalTimeMillis());
    System.out.println("任务总数:" + sw.getTaskCount());
    System.out.println("所有任务详情:" + sw.getTaskInfo());
}

Hutool工具

Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅。Hutool是对文件、流、加密解密、转码、正则、线程、XML等JDK方法进行封装,组成各种Util工具类。

在项目的pom.xml的dependencies中加入以下内容:


    cn.hutool
    hutool-all
    5.5.2

禁用 netflix-eureka 客户端

  • Spring Cloud Eureka主要负责实现微服务架构中的服务治理功能
  • SpringCloudGateway作为SpringCloud生态系中的网关,为微服务架构提供统一的路由管理,并且根据http请求进行相应的匹配、断言、过滤
eureka.client.enabled=false

你可能感兴趣的:(Java,redis,哈希算法,数据库)