mybatis-plus整合笔记

本文详细介绍了如何在SpringBoot项目中整合Mybatis-Plus,包括引入依赖、配置日志、创建项目结构、自动填充处理(数据库级别和代码级别)、乐观锁实现以及各种数据库操作(查询、更新、分页、删除)。此外,还涉及了条件构造器Wrapper的使用和代码生成器的配置。
摘要由CSDN通过智能技术生成

前言

hi,大家好,这里是Ian,欢迎大家一起来学习java,这篇是我通过b站狂神说的mybatis-plus讲解的视频以及mybatis-plus官方文档,并且自己进行调试总结出来的springboot整合mybatis-plus的笔记,虽然可能会有一些遗漏,欢迎大家查看

文章目录


mybatis-plus整合

引入依赖

使用Spring Boot,引入下面这个依赖
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.4.3</version>
</dependency>
使用ssm的,引入下面这个依赖
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus</artifactId>
    <version>3.4.3</version>
</dependency>

配置日志文件

配置日志文件可以让你更直观的查看sql语句
在这里插入图片描述

配置日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

用来显示sql语句,测试时可以使用

创建一个mybatis-plus整合过的springboot项目

mapper类
@Mapper
public interface UserMapper extends BaseMapper<User> {
    //mapper类中不需要有内容,但是需要继承BaseMapper类,并且指定实体类
}
user类
@Component //注册bean
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("user")//表名
public class User {
    @TableId(type = IdType.ASSIGN_ID)
    private int userId;

    private String username;
    private String password;
    private String cellphone;
    private int isRoo;
    private String address;
}
service类
public interface UserService {

    //注册用户
    int registUser(User user);

    //通过用户名查询用户信息
    User queryUserByUsername(String username);

    //给用户添加/修改地址
    int updateUserAddressByID(String address,int id);
}

serviceimpl类
@Service
public class UserServiceImpl implements UserService {
    @Resource
    private UserMapper userMapper;

    public int registUser(User user) {
        return userMapper.insert(user);
    }

    public User queryUserByUsername(String username) {
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username",username);//第一个参数是列名,列名必须与数据库列名完全一致,符号大小写的完全一致
        return userMapper.selectOne(queryWrapper);
    }

    public int updateUserAddressByID(String address, int id) {
        User user=new User();
        user.setUserId(id);
        user.setAddress(address);
        return userMapper.updateById(user);
    }
}
config类
@Configuration
@MapperScan("com.atlizhi.dao")
public class MybatisPlusConfig {
    //乐观锁
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());//乐观锁
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));//分页插件
        return interceptor;
    }
}

自动填充处理

数据库级别的自动填充

在这里插入图片描述

表的默认值为CURRENT_TIMESTAMP,并且勾选上更新的按钮每当更新时,会自动更新更新时间

代码别的自动填充
1、在实体类字段属性上添加注解

在这里插入图片描述
通过注解进行选择
在这里插入图片描述

2、编写一个处理器MyMetaObjectHandler
@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

    @Override
    public void insertFill(MetaObject metaObject) {
        log.info("start insert fill ....");
        //createTime就是想要进行填充的字段
        this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now()); // 起始版本 3.3.0(推荐使用)
        // 或者
        this.strictInsertFill(metaObject, "createTime", () -> LocalDateTime.now(), LocalDateTime.class); // 起始版本 3.3.3(推荐)
        // 或者
        this.fillStrategy(metaObject, "createTime", LocalDateTime.now()); // 也可以使用(3.3.0 该方法有bug)
    }

    @Override
    public void updateFill(MetaObject metaObject) {
        log.info("start update fill ....");
        this.strictUpdateFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); // 起始版本 3.3.0(推荐)
        // 或者
        this.strictUpdateFill(metaObject, "updateTime", () -> LocalDateTime.now(), LocalDateTime.class); // 起始版本 3.3.3(推荐)
        // 或者
        this.fillStrategy(metaObject, "updateTime", LocalDateTime.now()); // 也可以使用(3.3.0 该方法有bug)
    }
}

乐观锁

在这里插入图片描述

在这里插入图片描述

1.配置插件

spring xml方式:

<bean class="com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor" id="optimisticLockerInnerInterceptor"/>

<bean id="mybatisPlusInterceptor" class="com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor">
    <property name="interceptors">
        <list>
            <ref bean="optimisticLockerInnerInterceptor"/>
        </list>
    </property>

spring boot注解方式:

@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
    MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
    interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
    interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
    return interceptor;
}
2、数据库中添加 verson int 默认为0 列
3、在实体类上verson字段添加注解
@Version
private Integer version;

说明:

支持的数据类型只有:int,Integer,long,Long,Date,Timestamp,LocalDateTime

整数类型下 newVersion = oldVersion + 1

newVersion 会回写到 entity 中

仅支持 updateById(id) 与 update(entity, wrapper) 方法

在 update(entity, wrapper) 方法下, wrapper 不能复用!!!

4、实例
// Spring Boot 方式
@Configuration
@MapperScan("按需修改")
public class MybatisPlusConfig {
    /**
     * 旧版
     */
    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor() {
        return new OptimisticLockerInterceptor();
    }
    
    /**
     * 新版
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return mybatisPlusInterceptor;
    }
}

数据库操作

1、普通查询&条件查询 DDL

注意:

wrapper.eq(“name”,“kun”);在使用时,左边的参数代表的是列名,右边的参数代表的是你想要进行比较的值,列名必须与数据库中的列名完全保持一致,一个符号大小写都不能出错

查询全部

List<User> lists = userMapper.selectList(null);//这里参数为querywrapper
//可以通过querywrapper来自定义查询条件

查询单个个体

QueryWrapper<User> wrapper= new QueryWrapper<User>();
wrapper.eq("name","kun");
User user=userMapper.selectOne(wrapper);

通过mapper进行条件查询

HashMap<String,Object> map = new HashMap<>();
//自定义条件查询
map.put("name","kun");//列名  内容
map.put("age",3);
List<User> lists = userMapper.selectByMap(map);//这里查询满足name=坤哥,age=3的条件的集合

分页查询

Page<User> page =new Page<>(1,5);//参数1:当前页 参数2:页面大小
userMapper.selectPage(page,null);//第二个参数是wrapper用来添加条件
List<User> lists=page.getRecords();//getRecords获取当前所有的值

between and区间查询

QueryWrapper<User> wrapper= new QueryWrapper<User>();
wrapper.between("age",10,20);//第一个参数是列名,第二个第三参数是区间范围
Integer count = userMapper.selectCount(wrapper);//查询这个区间的数量

模糊查询

QueryWrapper<User> wrapper= new QueryWrapper<User>();
wrapper.notLike("name","e")  //相当于  not like '%e%'
    	.likeRight("email","t");//相当于  like 't%'
List<Map<String,Object>> maps = userMapper.selectMaps(wrapper);

子查询

QueryWrapper<User> wrapper= new QueryWrapper<User>();
//id在子查询中查出来
wrapper.inSql("id","select id from user where id < 3");
List<Object> objcts=userMapper.selectObjs(wrapper);

排序查询

QueryWrapper<User> wrapper= new QueryWrapper<User>();
//通过id进行排序
wrapper.orderByDesc("id");//参照的列名
List<User> lists=userMapper.selectList(wrapper);
2、数据库更新操作 DML
  • 更新操作

通过id进行更新

public int updateUserAddressByID(String address, int id) {
    User user=new User();
    user.setUserId(id);
    user.setAddress(address);//通过id更新地址
    return userMapper.updateById(user);
}

通过条件构造器作为参数更新

//把名字为rhb的用户年龄更新为18,其他属性不变
UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("name","kun");//判断条件 name=rhb
User user = new User();
user.setAge(18);//设置想要更新的属性的新值
userMapper.update(user, updateWrapper);

假设只更新一个字段在使用updateWrapper 的构造器中也需要构造一个实体对象,这样比较麻烦。可以使用updateWrapper的set方法

//只更新一个属性,把名字为rhb的用户年龄更新为18,其他属性不变
UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("name","kun").set("age", 18);
userMapper.update(null, updateWrapper);

以上三种更新操作会将实体类的所有属性进行更新,如果有的值是int值且不为null,则会默认改为0.

为此我们可以采用一下更新手段,来进行指定列更新。

public int updateAcq(String eNum, int eAcq, int rid,String eFirstTime) {
    UpdateWrapper<EntrustMess> wrapper=new UpdateWrapper<EntrustMess>();
    wrapper.eq("e_num",eNum);
    wrapper.set("e_acq",eAcq);
    wrapper.set("rid",rid);
    wrapper.set("e_first_time",eFirstTime);

    return entrustMessMapper.update(null,wrapper);
}
3、分页查询的具体操作

1、首先在mybatisPlusConfig中注册分页插件的bean对象

/**
 * 分页插件
 */
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
    MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
    interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
    return interceptor;
}

2、然后可以通过下面的方法进行分页查询

@Resource
private EntrustMessMapper entrustMessMapper;

public List<EntrustMess> getPageEntrust(int a) {
    Page<EntrustMess> page =new Page<EntrustMess>(a,4);//参数1:当前页 参数2:页面大小
    QueryWrapper queryWrapper = new QueryWrapper();
    queryWrapper.eq("e_acq",0);//用来限定条件,如果不需要限定的话,下面这个queryWrapper参数可以填null。
    entrustMessMapper.selectPage(page,queryWrapper);
    List<EntrustMess> lists=page.getRecords();//getRecords获取当前所有的值
    return lists;
}
  • 删除操作

根据id删除记录

int result = userMapper.deleteById(8L);

批量删除

int result = userMapper.deleteBatchIds(Arrays.asList(8, 9, 10));

简单的map条件查询删除

HashMap<String, Object> map = new HashMap<>();
map.put("name", "Helen");
map.put("age", 18);
int result = userMapper.deleteByMap(map);

简单的wrapper条件查询删除

QueryWrapper<User> wrapper= new QueryWrapper<User>();
wrapper.eq("name","kun");
int result=userMapper.delete(wrapper);

逻辑删除

在这里插入图片描述

1、在数据库中添加一个deleted字段 默认值为0

在这里插入图片描述

2、给实体类添加一个deleted字段 并且添加上注解 @TableLogic
@TableLogic
private int deleted;
3、配置com.baomidou.mybatisplus.core.config.GlobalConfig$DbConfig
mybatis-plus:
  global-config:
    db-config:
      logic-delete-field: flag  # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)
      logic-delete-value: 1 # 逻辑已删除值(默认为 1)
      logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)

当我们进行删除时,会执行更新操作,然后将deleted字段变为1

当我们进行查询时,会自动添加一个deleted=0的操作

在这里插入图片描述

条件构造器Wrapper

  • eq 等于 =
  • ne 不等于 <>
  • gt 大于 >
  • ge 大于等于 >=
  • lt 小于 <
  • between between 值1 and 值2
  • notBetween not between 值1 and 值2
  • like like’%值%’
  • notLike not like’%值%’
  • likeLeft like’%值’
  • likeRight like’值%’
  • isNull is null
  • isNotNull is not null
  • in in(“age”,{1,2,3})---->age in (1,2,3)
  • notIn notIn(“age”,{1,2,3})---->age not in (1,2,3)
  • insql inSql(“id”,“select id from table where id ❤️”)–> id in (select id from table where id < 3)
  • groupBy groupBy(“id”,“name”)–>group by (id,name)
  • orderByAsc orederByAsc(“id”,“name”)–>order by id ASC,name ASC
  • orderByDesc orederByDesc(“id”,“name”)–>order by id Desc,name Desc
  • orderBy orderBy(true, true, “id”, “name”)–>order by id ASC,name ASC
  • or 拼接or eq(“id”,1).or().eq(“name”,“kun”);
  • exists exists(“select id from table where age = 1”)–>exists (select id from table where age = 1)
  • notExists notExists(“select id from table where age = 1”)–>not exists (select id from table where age = 1)
  • having having(“sum(age) > 10”)–>having sum(age) > 10
queryWrapper
  • select select(“id”,“name”,“age”)
updateWrapper
  • set set(“name”,“kun”)
  • setSql setSql(“name=‘kun’”)

代码自动生成器

1、引入依赖
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-generator</artifactId>
    <version>3.4.1</version>
</dependency>

引入模板依赖 注意!如果您选择了非默认引擎,需要在 AutoGenerator 中 设置模板引擎。

Velocity(默认)
<dependency>
    <groupId>org.apache.velocity</groupId>
    <artifactId>velocity-engine-core</artifactId>
    <version>2.3</version>
</dependency>
Freemarker:
<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.31</version>
</dependency>
Beetl:
<dependency>
    <groupId>com.ibeetl</groupId>
    <artifactId>beetl</artifactId>
    <version>3.3.2.RELEASE</version>
</dependency>
AutoGenerator generator = new AutoGenerator();

// set freemarker engine
generator.setTemplateEngine(new FreemarkerTemplateEngine());

// set beetl engine
generator.setTemplateEngine(new BeetlTemplateEngine());

// set custom engine (reference class is your custom engine class)
generator.setTemplateEngine(new CustomTemplateEngine());

// other config
...

在这里插入图片描述

2、配置 GlobalConfig
GlobalConfig globalConfig = new GlobalConfig();
globalConfig.setOutputDir(System.getProperty("user.dir") + "/src/main/java");
globalConfig.setAuthor("jobob");
globalConfig.setOpen(false);
3、配置 DataSourceConfig

在这里插入图片描述

DataSourceConfig dataSourceConfig = new DataSourceConfig();
dataSourceConfig.setUrl("jdbc:mysql://localhost:3306/ant?useUnicode=true&useSSL=false&characterEncoding=utf8");
dataSourceConfig.setDriverName("com.mysql.jdbc.Driver");
dataSourceConfig.setUsername("root");
dataSourceConfig.setPassword("password");
4、包的配置

在这里插入图片描述

5、策略配置

在这里插入图片描述
在这里插入图片描述

自定义模板引擎

请继承类 com.baomidou.mybatisplus.generator.engine.AbstractTemplateEngine

//指定自定义模板路径, 位置:/resources/templates/entity2.java.ftl(或者是.vm)
//注意不要带上.ftl(或者是.vm), 会根据使用的模板引擎自动识别
TemplateConfig templateConfig = new TemplateConfig()
    .setEntity("templates/entity2.java");

AutoGenerator mpg = new AutoGenerator();
//配置自定义模板
mpg.setTemplate(templateConfig);
自定义属性注入
InjectionConfig injectionConfig = new InjectionConfig() {
    //自定义属性注入:abc
    //在.ftl(或者是.vm)模板中,通过${cfg.abc}获取属性
    @Override
    public void initMap() {
        Map<String, Object> map = new HashMap<>();
        map.put("abc", this.getConfig().getGlobalConfig().getAuthor() + "-mp");
        this.setMap(map);
    }
};
AutoGenerator mpg = new AutoGenerator();
//配置自定义属性注入
mpg.setCfg(injectionConfig);
entity2.java.ftl
自定义属性注入abc=${cfg.abc}

entity2.java.vm
自定义属性注入abc=$!{cfg.abc}
整体代码
// 演示例子,执行 main 方法控制台输入模块表名回车自动生成对应项目目录中
public class CodeGenerator {
    public static void main(String[] args) {
        // 代码生成器
        AutoGenerator mpg = new AutoGenerator();
		// set beetl engine//修改模板
        //mpg.setTemplateEngine(new BeetlTemplateEngine());
        
        // 全局配置
        GlobalConfig gc = new GlobalConfig();
        String projectPath = System.getProperty("user.dir");
        gc.setOutputDir(projectPath + "/src/main/java");
        gc.setAuthor("kun");
        gc.setOpen(false);
        gc.setFileOverride(false);
        gc.setServiceName("%sService");//去Service的i前缀
        gc.setIdType(IdType.ID_WORKER);
        gc.setDateType(DateType.ONLY_DATE);
        gc.setSwagger2(true);
        mpg.setGlobalConfig(gc);

        // 数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl("jdbc:mysql://localhost:3306/roo_delivery?useUnicode=true&useSSL=false&characterEncoding=utf8");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername("root");
        dsc.setPassword("111222");
        dsc.setDbType(DbType.MYSQL);
        mpg.setDataSource(dsc);

        // 包配置
        PackageConfig pc = new PackageConfig();
        //pc.setModuleName("blob");//不需要
        pc.setParent("com.atkunge");
        pc.setEntity("entity");
        pc.setMapper("mapper");
        pc.setService("service");
        pc.setController("controller");
        mpg.setPackageInfo(pc);



        // 配置模板
        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.setInclude("user");//可以有多个,与数据库表名相照应
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        strategy.setEntityLombokModel(true);
        strategy.setLogicDeleteFieldName("deleted");
        strategy.setRestControllerStyle(false);
        strategy.setControllerMappingHyphenStyle(true);
        strategy.setTablePrefix(pc.getModuleName() + "_");



        //乐观锁
        strategy.setVersionFieldName("version");


        mpg.setStrategy(strategy);
        mpg.execute();
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值