mybatis plus是一个mybatis的增强工具,在其基础上只做增强不做改变。作为开发中常见的第三方组件,学习并应用在项目中可以节省开发时间,提高开发效率。
官方文档地址:MyBatis-Plus (baomidou.com)
自动注入基本CRUD,性能无损耗,直接面向对象操作(通过BaseMaper<约定的泛型>);
通过lambda表达式的形式,方便编写各类查询条件,无需担心字段出错;
内含分布式唯一ID生成器-Squence,可自行配置主键;
实体类只需继承Model类即可进行CRUD操作;
基于mybatis物理分页,配置好插件后自动将数据分页;
DROP TABLE IF EXISTS user;CREATE TABLE user(
id BIGINT() NOT NULL COMMENT '主键ID',
name VARCHAR() NULL DEFAULT NULL COMMENT '姓名',
age INT() NULL DEFAULT NULL COMMENT '年龄',
email VARCHAR() NULL DEFAULT NULL COMMENT '邮箱', PRIMARY KEY (id)
);
<!--mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.2</version>
</dependency>
#mysql配置#数据库用户名spring.datasource.username=root#登录密码spring.datasource.password=password123#JDBC地址、编码、安全连接spring.datasource.url=jdbc:mysql://localhost:3306/mybatis_plus?useSSL=false&useUnicode=true&characterEncoding=utf-8#数据库驱动spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
@Data@AllArgsConstructor@NoArgsConstructorpublic class User { //用户id
private Long id; //用户名
private String name; //年龄
private Integer age; //邮箱
private String email;
}
@Mapper@Repository//该接口继承BaseMapper类所有方法public interface UserMapper extends BaseMapper<User> {
}
@Autowired
private UserMapper userMapper; //创建条件构造器
QueryWrapper<User> wrapper = new QueryWrapper<>();
userMapper.selectList(wrapper);
#mybatis-plus日志配置,默认控制台输出日志,properties文件mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
void insert(){ User user = new User();
user.setName("Alex");
user.setAge();
user.setEmail("4353435@qq.com"); //受影响的行数
int result = userMapper.insert(user);
System.out.println(result);
System.out.println(user);
}
主键生成策略
实体类声明数据库表名,同时设置主键id为自增。
//数据库表名@TableName("user")public class User implements Serializable { //用户id,主键自增
@TableId(value = "id",type = IdType.AUTO)
private Long id;
}
//更新操作
@Test
void updateTest(){ User user = new User();
user.setId(3L);
user.setName("docker&K8s"); //操作结果条数
int i = userMapper.updateById(user);
System.out.println(i);
}
时间自动填充策略
在数据库中新建字段并设置为操作的当前时间,且需要在实体类同步属性:
从而达到自动填充时间的。
private Date createTime; private Date updateTime;
@TableField(fill = FieldFill.INSERT)
private Date createTime; @TableField(fill = FieldFill.UPDATE)
private Date updateTime;
user.setUpdateTime(new Date());
在面试中经常会提及悲观锁、乐观锁的概念,其实这两个概念非常简单。
乐观锁
乐观锁顾名思义十分乐观,它总是认为不会出现问题,无论干什么都不会去上锁。如果出现问题,就再更新值去测试。
悲观锁
悲观锁顾名思义十分悲观,它总是认为会出现问题,无论干什么都会去上锁,然后再去操作。
乐观锁机制
乐观锁:、先去查询获得版本号version = --A线程update user set name = "zhuzhiqiang",version = version + where id = and version =
若B线程抢先完成,这时version = ,导致线程A修改失败--B线程update user set name = "zhuzhiqiang",version = version + where id = and version =
测试mybatisPlus的乐观锁插件
1、在数据库表中添加version字段:
2、实体类添加对应属性,并添加@Version注解:
//乐观锁字段(注解)
@Version
private Integer version;
3、注册组件:
@EnableTransactionManagement //事务管理注解@Configurationpublic class MyBatisPlusConfig {
//注册乐观锁插件
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor(){ return new OptimisticLockerInterceptor();
}
}
使用步骤
配置拦截器组件(配置类中):
直接使用Page对象即可:
逻辑删除
逻辑删除指的是在数据库中没有被删除,而是通过一个变量来使其失效:deleted = 0 -> deleted = 1
数据库表中增加字段:
实体类中添加对应属性:
properties配置:
测试删除(本质上是一个更新操作):
注:若执行了逻辑删除,那么再次查询该条数据时,会在select语句中自动拼接deleted=0,即查询不到该条语句。
按照复杂条件进行查询,本质上等价于使用复杂sql进行查询。
源码分析:
测试使用:
复杂条件的SQL查询
public
void
testLike(){
QueryWrapper<User> wrapper = new
QueryWrapper<>(); //相当于where语句,
wrapper //表示name字段中 不包含e的数据
.notLike("name","e") //右查询,以t开头的email字段数据
.likeRight("email", "t");
}
AutoGenerator 是 MyBatis-Plus 的代码生成器,通过 AutoGenerator 可以快速生成 Entity、Mapper、Mapper XML、Service、Controller 等各个模块的代码,极大的提升了开发效率。
public class AutoCodeTool { public static void main(String[] args) { //构建代码自动生成器对象
AutoGenerator autoCode = new AutoGenerator(); //全局配置生效
autoCode.setGlobalConfig(gc); //数据源生效
autoCode.setDataSource(dsc); //包配置生效
autoCode.setPackageInfo(packageConfig); //其它策略生效
autoCode.setStrategy(strategyConfig); //执行代码生成器
autoCode.execute();
}
}
//1、全局配置GlobalConfig gc = new GlobalConfig();//输出目录,将自动生成的代码生成在以下路径中String projectPath = System.getProperty("user.dir");
gc.setOutputDir(projectPath + "/src/main/java");//设置作者信息gc.setAuthor("Created by zhuzqc");//生成代码后不打开文件管理器gc.setOpen(false);//是否覆盖原来生成的代码gc.setFileOverride(false);//主键类型gc.setIdType(IdType.ID_WORKER);//时间类型gc.setDateType(DateType.ONLY_DATE);//配置swagger文档gc.setSwagger2(true);
//2、设置数据源DataSourceConfig dsc = new DataSourceConfig();//数据源具体配置dsc.setUrl("jdbc:mysql://localhost:3306/mubatis_plus?useSSL=false&useUnicode=true&characterEncoding=utf-8");
dsc.setDriverName("com.mysql.cj.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("password123");
dsc.setDbType(DbType.MYSQL);
//3、包的配置PackageConfig packageConfig = new PackageConfig();//生成包路径packageConfig.setParent("com.dcone");//生成模块名packageConfig.setModuleName("common");//生成entitypackageConfig.setEntity("pojo");//生成mapperpackageConfig.setMapper("dao");//生成servicepackageConfig.setService("service");//生成controllerpackageConfig.setController("controller");
//4、其它策略StrategyConfig strategyConfig = new StrategyConfig();//设置需要映射的数据库表strategyConfig.setInclude("user");//驼峰命名strategyConfig.setNaming(NamingStrategy.underline_to_camel);
strategyConfig.setColumnNaming(NamingStrategy.underline_to_camel);//设置LombokstrategyConfig.setEntityLombokModel(true);//RESTFUL风格strategyConfig.setRestControllerStyle(true);//逻辑删除strategyConfig.setLogicDeleteFieldName("deleted");//自动填充配置(创建和修改时间)TableFill gmtCreate = new TableFill("gmt_create_time", FieldFill.INSERT);TableFill gmtModified = new TableFill("gmt_modified_time", FieldFill.INSERT_UPDATE);
autoCode.setStrategy(strategyConfig);//作为列表元素添加自动填充策略ArrayList<TableFill> tableFills = new ArrayList<>();
tableFills.add(gmtCreate);
tableFills.add(gmtModified);
strategyConfig.setTableFillList(tableFills);//乐观锁配置strategyConfig.setVersionFieldName("version");//访问URL下划线风格strategyConfig.setControllerMappingHyphenStyle(true);