Mybatis-Plus

Mybatis-Plus,第1张

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.plus 或 https://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', '[email protected]');
INSERT INTO `tb_user` (`id`, `user_name`, `password`, `name`, `age`, `email`) VALUES ('2', 'lisi', '123456', '李四', '20', '[email protected]');
INSERT INTO `tb_user` (`id`, `user_name`, `password`, `name`, `age`, `email`) VALUES ('3', 'wangwu', '123456', '王五', '28', '[email protected]');
INSERT INTO `tb_user` (`id`, `user_name`, `password`, `name`, `age`, `email`) VALUES ('4', 'zhaoliu', '123456', '赵六', '21', '[email protected]');
INSERT INTO `tb_user` (`id`, `user_name`, `password`, `name`, `age`, `email`) VALUES ('5', 'sunqi', '123456', '孙七', '24', '[email protected]');

2.2 工程搭建 2.2.1 创建springBoot工程

2.2.2 导入依赖
 
    
        org.springframework.boot
        spring-boot-starter-parent
        2.1.5.RELEASE
    

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

        
        
            org.projectlombok
            lombok
            true
        
        
        
            com.baomidou
            mybatis-plus-boot-starter
            3.1.1
        
        
        
            mysql
            mysql-connector-java
            5.1.47
        
        
            org.slf4j
            slf4j-log4j12
        
        
            com.baomidou
            mybatis-plus-generator
            3.1.2
        

    

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

 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
@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;


@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;


@Mapper
public interface UserMapper extends baseMapper {
}

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





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;


@RunWith(SpringRunner.class)//使用springrunner运行器
@SpringBootTest(classes = MpApplication.class)//启用springboot测试,加载Springboot配置文件
public class UserMapperTest {

    @Autowired
    private UserMapper userMapper;
    //查询所有
    @Test
    public void testSelectAll(){
        List 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("[email protected]");
        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("[email protected]"); 
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 {
     
    AUTO(0), 
     
    NONE(1), 
     
    INPUT(2), 
     
     
    ID_WORKER(3), 
     
    UUID(4),
     
    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 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 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.1、deleteById

方法定义:

 测试用例:

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

方法定义:

测试:

@Autowired 
private UserMapper userMapper; 
@Test 
public void testDeleteByMap() { 
Map 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.3、delete

方法定义:

 测试:

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

方法定义:

测试:

@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.1、selectById单个查询

方法定义:

 测试:

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

方法定义:

 测试:

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

方法定义:

 测试:

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

方法定义:

 测试:

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

方法定义:

 测试:

@Test 
public void testSelectList() { 
QueryWrapper wrapper = new QueryWrapper(); 
//年龄大于23岁
wrapper.gt("age", 23); 
//根据条件查询数据 
List users = this.userMapper.selectList(wrapper); 
for (User user : users) { 
System.out.println("user = " + user); 
    } 
}
 3.4.6、selectPage 根据条件查询全部并分页 配置分页插件(自定义一个类):
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;


@Configurable
@MapperScan("com.chen.mp.mapper") //设置mapper接口的扫描包
public class MybatisPlusConfig {
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor(); }
    }

方法定义:

 测试:

@Test 
public void testSelectPage() { 
QueryWrapper wrapper = new QueryWrapper();
//年龄大于20岁 
wrapper.gt("age", 20);  
//参数:当前页,每页条数
Page page = new Page<>(1,1); 
//根据条件查询数据 
IPage iPage = this.userMapper.selectPage(page, wrapper); 
System.out.println("数据总条数:" + iPage.getTotal()); 
System.out.println("总页数:" + iPage.getPages()); 
List users = iPage.getRecords(); 
for (User user : users) { 
System.out.println("user = " + user); 
    } 
}
 3.5、SQL注入的原理 在 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 mapperRegistryCache = GlobalConfigUtils.getMapperRegistryCache(builderAssistant.getConfiguration()); 
    if (!mapperRegistryCache.contains(className)) { 
        List 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 进行真正的注入:
 
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.1、confifigLocation

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

 Spring MVC:

 
 
4.1.2、mapperLocations

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

MyBatis Mapper 所对应的 XML 文件位置,如果您在 Mapper 中有自定义方法( XML 中有自定义实现),需要进行 该配置,告诉 Mapper 所对应的 XML 文件位置。 Spring Boot :
mybatis-plus.mapper-locations = classpath*:mybatis
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 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

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5671678.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存