mybatis-plus笔记

mybatis-plus笔记,第1张

mybatis-plus笔记


文章目录

简介:注意事项图示

配置文件配置类查找插入更新(修改)自动填充赋值(createTime和updateTime)乐观锁批量ID查找条件查询分页查询(基于Page)删除

物理删除逻辑删除(黑名单等) 性能分析插件(SQL分析)

application配置全局文件配置类(configuration)自动注入处理类(Handler)mapper文件实体类乐观锁SQL分析复杂条件查询(基于QueryWrapper)

ge---大于等于(>=)eq---等于ne---不等于between---区间查询like---模糊查询orderByDesc---降序排序last---拼接SQL语句select---指定要查询的列注意:代码 mybatis-plus代码生成器

简介:

mybatis

mybatis-plus=hibernate(优点)+mybatis(优点)

将使用mybatis过程中那些常用且固定的简单CRUD套路进行进一步封装(baseMapper,page等等)
并且由于service也就是调用mapper进行服务的,所以自然mp也将service进行了封装,只需要传参(实体类)继承配置就可以使用。

mp提供的baseMapper接口包含了常用且固定的简单CRUD,还提供了对应接口方法的SQL语句。 只需要简单配置传参,继承就可以进行单表 *** 作。

注意事项

记住一件事(无论mybatis或者mp还是hibernate):实体类名和数据库表名,实体类变量名和列名都要一致相同。
注意:createTime(驼峰式命名)----create_time(数据库列命名)
mapper文件用到方法名时也要和接口方法名一致,绝对不会出错。
反之则可能出错。

mp错误示范:
cause:com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Table
‘student.users1’ doesn’t exist(实体类名与表名未对应)
Cause:com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown
column ‘id1’ in ‘field list’(实体类变量名与列名未对应)

图示 配置文件
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/student
spring.datasource.username=root
spring.datasource.password=
#mybatis日志,可以查看使用的SQL语句
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
#逻辑删除
mybatis-plus.global-config.db-config.logic-delete-value=1
mybatis-plus.global-config.db-config.logic-not-delete-value=0

配置类
package com.example.mp.conf;

import com.baomidou.mybatisplus.core.injector.ISqlInjector;
import com.baomidou.mybatisplus.extension.injector.LogicSqlInjector;
import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;

//声明为配置类,专门用于配置环境
@Configuration

//配置mapper扫描的映射文件
@MapperScan("com.example.mp.mapper")
public class MPConfig {
    //配置乐观锁插件
    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor(){
        return new OptimisticLockerInterceptor();
    }
    //配置分页查询插件
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }
    //配置逻辑删除插件
    @Bean
    public ISqlInjector iSqlInjector(){
        return new LogicSqlInjector();
    }
    
    @Bean
    @Profile({"dev","test"})// 设置 dev test 环境开启
    public PerformanceInterceptor performanceInterceptor() {
        PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
        performanceInterceptor.setMaxTime(500);//ms,超过此处设置的ms则sql不执行
        performanceInterceptor.setFormat(true);
        return performanceInterceptor;
    }
}



查找

实体类(entity):
lombok用于简化实体类,提供get,set,有参/无参构造方法。

mp提供的baseMapper接口包含了常用且固定的简单CRUD,还提供了对应接口方法的SQL语句。
只需要简单配置继承传参就可以进行单表 *** 作。


插入

MyBatis-Plus(自带)默认的主键策略是: ID_WORKER/ID_WORKER_STR 全局唯一 ID(64位二进制=19位十进制)

snowflake(雪花)算法 其核心思想是: 使用41bit作为毫秒数,10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID),
12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个 ID), 最后还有一个符号位,永远是0。
具体实现的代码可以参看https://github.com/twitter/snowflake。
雪花算法支持的TPS可以达到419万左右(2^22*1000)。
一共41+10+12+1=64位二进制

雪花算法在工程实现上有单机版本和分布式版本。单机版本如下,分布式版本可以参看美团leaf算法:https://github.com/Meituan-Dianping/Leaf


AUTO使用方法

更新(修改)

错误示范:

自动填充赋值(createTime和updateTime)

实体类
实现插入时间和更新时间的自动填充

注解实现自动填充
也可以使用set不使用注解

注解方式
@TableField注解需要放在对应注入变量上方(规范化)

乐观锁

乐观锁
乐观锁原理
乐观锁笔记

mp乐观锁实现方式:

取出记录时,获取当前version(查)更新时,带上这个version执行更新时, set version = newVersion where version = oldVersion如果version不对,就更新失败(改)
(先查后改)

乐观锁SQL语句

 UPDATE user
 	SET money=#{money},version=#{version+1} 
 	WHERe id=#{id} and version=#{version}


mp中乐观锁插件使用时:必须先查(得到oldVersion)才可以(比较version值)后改。

如以下SQL语句所示,需知oldVersion值

   UPDATE
        user 
    SET
        name='gclgg',
        pass='355985',
        create_time='2022-01-25 09:44:35',
        update_time='2022-01-25 19:57:49.908',
        version=4 
    WHERe
        id=1485790668226932737 
        AND version=3
批量ID查找
//    批量查询
    @Test
    public void findIds(){
        List users=usersMapper.selectBatchIds(Arrays.asList(1485790477566349314L,1485790668226932737L));
        System.out.println(users);
    }

条件查询

注意条件查询中HashMap的设置键为String,值为对应实体类类型

//    条件查询
    @Test
    public void findByMap(){
        HashMaphp=new HashMap<>();
        hp.put("name","gclgg");
        hp.put("pass",123456);
        List users=usersMapper.selectByMap(hp);
        System.out.println(users);
    }

分页查询(基于Page)

配置类中配置分页插件

   //配置分页查询插件
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }


删除 物理删除

批量删除

条件删除

逻辑删除(黑名单等)


配置为deleted=1为删除,deleted=0为未删除


mp其他时也会考虑逻辑删除变量deleted。
因为在application.properties文件中的配置在全局都适应。

性能分析插件(SQL分析)

例如:可以看到mp插件中乐观锁SQL语句

application配置全局文件

该全局配置文件是配置全局,所以针对全部 *** 作生效。

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/student
spring.datasource.username=root
spring.datasource.password=
#mybatis日志,可以查看使用的SQL语句
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
#逻辑删除
mybatis-plus.global-config.db-config.logic-delete-value=1
mybatis-plus.global-config.db-config.logic-not-delete-value=0

#环境设置:dev、test、prod
spring.profiles.active=dev

配置类(configuration)
package com.example.mp.conf;

import com.baomidou.mybatisplus.core.injector.ISqlInjector;
import com.baomidou.mybatisplus.extension.injector.LogicSqlInjector;
import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PerformanceInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;

//声明为配置类,专门引入配置
@Configuration

//配置mapper扫描的映射文件
@MapperScan("com.example.mp.mapper")
public class MPConfig {
    //配置乐观锁插件
    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor(){
        return new OptimisticLockerInterceptor();
    }
    //配置分页查询插件
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }
    //配置逻辑删除插件
    @Bean
    public ISqlInjector iSqlInjector(){
        return new LogicSqlInjector();
    }

    
    @Bean
    @Profile({"dev","test"})// 设置 dev test 环境开启
    public PerformanceInterceptor performanceInterceptor() {
        PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
        performanceInterceptor.setMaxTime(500);//ms,超过此处设置的ms则sql不执行
        performanceInterceptor.setFormat(true);
        return performanceInterceptor;
    }
}

自动注入处理类(Handler)
package com.example.mp.handler;

import com.baomidou.mybatisplus.core.handlers.metaObjectHandler;
import org.apache.ibatis.reflection.metaObject;
import org.springframework.stereotype.Component;

import java.util.Date;

@Component
public class mymetaObjectHandler implements metaObjectHandler {
    @Override
    public void insertFill(metaObject metaObject) {
        this.setFieldValByName("createTime",new Date(), metaObject);
        this.setFieldValByName("updateTime",new Date(), metaObject);
        this.setFieldValByName("version",1,metaObject);
    }

    @Override
    public void updateFill(metaObject metaObject) {
        this.setFieldValByName("updateTime",new Date(), metaObject);
    }
}

mapper文件
 package com.example.mp.mapper;


import com.baomidou.mybatisplus.core.mapper.baseMapper;
import com.example.mp.User;
import org.springframework.stereotype.Repository;

@Repository
public interface UsersMapper extends baseMapper{
}

实体类
package com.example.mp;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.Version;
import lombok.Data;
import java.util.Date;
@Data
public class User {
    private Long  id;
    private String name;
    private String pass;
    //实体类:驼峰式命名createTime-对应-列名:create_time
    @TableField(fill = FieldFill.INSERT)//插入时赋值
    private Date createTime;
    @TableField(fill = FieldFill.INSERT_UPDATE)//插入,更新时赋值
    private Date updateTime;
    @Version//乐观锁:更新时判断再更新
    @TableField(fill = FieldFill.INSERT)//插入时赋值
    private Integer version;
    @TableLogic
    private Integer deleted;
}

乐观锁SQL分析

复杂条件查询(基于QueryWrapper)
  //创建QueryWrapper对象进行复杂条件查询的SQL语句设置
        QueryWrapper wrapper = new QueryWrapper<>();
//使用wrapper进行查询
        List users = usersMapper.selectList(wrapper);
        System.out.println(users);
ge—大于等于(>=)

eq—等于

ne—不等于

between—区间查询

like—模糊查询

orderByDesc—降序排序

last—拼接SQL语句

select—指定要查询的列

注意:

可以基于SQL进行多重复杂条件查询。

代码
package com.example.mp;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.mp.mapper.UsersMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;


import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
//作用:用于标识声明一个springboot框架容器。
@SpringBootTest
class MpApplicationTests {
    @Autowired
    private UsersMapper usersMapper;
    @Test
   public void findAll() {
        List users=usersMapper.selectList(null);
        System.out.println(users);
    }
    @Test
    public void insert(){
        User users=new User();
        users.setName("gclgg");
        users.setPass("123456");
//        users.setCreateTime(new Date());
//        users.setUpdateTime(new Date());
        int result=usersMapper.insert(users);
        System.out.println(result);
    }
    @Test
    public void update(){
        User user=new User();
        user.setId(1485790668226932737L);
        user.setPass("355985");
//        user.setUpdateTime(new Date());
//      更新除ID以外修改过默认值(0,null)的属性
        int result=usersMapper.updateById(user);
        System.out.println(result);
    }
//    测试乐观锁,必须先查后改才生效
    @Test
    public void testOpt(){
        User user;
        user=usersMapper.selectById(1485790668226932737L);
        user.setPass("355985");
//        user.setUpdateTime(new Date());
//      更新除ID以外修改过默认值(0,null)的属性
        int result=usersMapper.updateById(user);
        System.out.println(result);
    }
//    批量查询
    @Test
    public void findIds(){
        List users=usersMapper.selectBatchIds(Arrays.asList(1485790477566349314L,1485790668226932737L));
        System.out.println(users);
    }
//    条件查询
    @Test
    public void findByMap(){
        HashMaphp=new HashMap<>();
        hp.put("name","gclgg");
        hp.put("pass",123456);
        List users=usersMapper.selectByMap(hp);
        System.out.println(users);
    }
//     分页查询
    @Test
    public void page(){
        //1 创建page对象
        //传入两个参数:               当前页 和 每页显示记录数
        Page page = new Page<>(1,3);
        //调用mp分页查询的方法
        //调用mp分页查询过程中,底层封装
        //把分页所有数据封装到page对象里面
        usersMapper.selectPage(page,null);

        //通过page对象获取分页数据
        System.out.println("当前页"+page.getCurrent());//当前页
        System.out.println("每页数据list集合"+page.getRecords());//每页数据list集合
        System.out.println("每页显示记录数"+page.getSize());//每页显示记录数
        System.out.println("总记录数"+page.getTotal()); //总记录数
        System.out.println("总页数"+page.getPages()); //总页数

        System.out.println("是否有下一页"+page.hasNext()); //下一页
        System.out.println("是否有上一页"+page.hasPrevious()); //上一页
    }
    //删除 *** 作 物理删除
    @Test
    public void testDeleteById(){
        int result = usersMapper.deleteById(1485918452676915201L);
        System.out.println(result);
    }

    //批量删除
    @Test
    public void testDeleteBatchIds() {

        int result = usersMapper.deleteBatchIds(Arrays.asList(1,2));
        System.out.println(result);
    }

    //条件删除
    @Test
    public void testDeleteByMap() {
        HashMap map = new HashMap<>();
        map.put("name", "gclgg");
        map.put("pass", 123456);
        int result = usersMapper.deleteByMap(map);
        System.out.println(result);
    }
    //mp实现复杂查询 *** 作
    @Test
    public void testSelectQuery() {
        //创建QueryWrapper对象
        QueryWrapper wrapper = new QueryWrapper<>();
        //指定要查询的列
        // 通过QueryWrapper设置条件
        wrapper.select("id","name");
        //ge、gt、le、lt
        //查询age>=30记录
        //第一个参数字段名称,第二个参数设置值
        wrapper.ge("pass",12345);

        //eq、ne
//        wrapper.eq("name","lilei");
//        wrapper.ne("name","lilei");

        //between
        //查询密码长度区间 10000-10000000
//         wrapper.between("pass",10000,1000000);

        //like
//        wrapper.like("name","gc");

        //orderByDesc
//         wrapper.orderByDesc("id");

        //last
        wrapper.last("AND pass='123456'");

        List users = usersMapper.selectList(wrapper);
        System.out.println(users);

    }
}

mybatis-plus代码生成器

基于mp的自动生成代码,直接配置传参,继承mp封装简单且固定的crud的mapper,service的代码。
最后我们只需要编写业务逻辑(controller)就行。

package com.createcode;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.IdType;
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.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import org.junit.Test;

public class CodeGenerator {

    @Test
    public void run() {

        // 1、创建代码生成器
        AutoGenerator mpg = new AutoGenerator();

        // 2、全局配置
        GlobalConfig gc = new GlobalConfig();
        String projectPath = System.getProperty("user.dir");
//        projectPath="F:\javaweb项目\edu_parent\service\service_edu"
        gc.setOutputDir("F:\javaweb项目\edu_parent\service\service_edu"+ "/src/main/java");

        gc.setAuthor("testjava");
        gc.setOpen(false); //生成后是否打开资源管理器(就是把右边父文件夹打开,文件夹全部摊开)
        gc.setFileOverride(false); //重新生成时文件是否覆盖
//        否则变为IUserService
        gc.setServiceName("%sService");	//去掉Service接口的首字母I
        gc.setIdType(IdType.ID_WORKER_STR); //主键策略
        gc.setDateType(DateType.ONLY_DATE);//定义生成的实体类中日期类型
        gc.setSwagger2(true);//开启Swagger2模式

        mpg.setGlobalConfig(gc);

        // 3、数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://localhost:3306/education");
        dsc.setDriverName("com.mysql.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("");
        dsc.setDbType(DbType.MYSQL);
        mpg.setDataSource(dsc);

        // 4、包配置:com.qlugcl.eduservice
        PackageConfig pc = new PackageConfig();
        pc.setParent("com.qlugcl");//包名
        pc.setModuleName("eduservice"); //模块名
        pc.setController("controller");
        pc.setEntity("entity");
        pc.setService("service");
        pc.setMapper("mapper");
        mpg.setPackageInfo(pc);

        // 5、策略配置
        StrategyConfig strategy = new StrategyConfig();
//        数据库表
        strategy.setInclude("edu_teacher");
        strategy.setNaming(NamingStrategy.underline_to_camel);//数据库表映射到实体的命名策略
        strategy.setTablePrefix(pc.getModuleName() + "_"); //生成实体时去掉表前缀

        strategy.setColumnNaming(NamingStrategy.underline_to_camel);//数据库表字段映射到实体的命名策略
        strategy.setEntityLombokModel(true); // lombok 模型 @Accessors(chain = true) setter链式 *** 作

        strategy.setRestControllerStyle(true); //restful api风格控制器
        strategy.setControllerMappingHyphenStyle(true); //url中驼峰转连字符

        mpg.setStrategy(strategy);


        // 6、执行
        mpg.execute();
    }
}

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

原文地址: http://outofmemory.cn/zaji/5719735.html

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

发表评论

登录后才能评论

评论列表(0条)

保存