简介
为简化开发而生!是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变。
润物无声:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑。
效率至上:只需简单配置,即可快速进行 CRUD 操作,从而节省大量时间。
丰富功能:热加载、代码生成、分页、性能分析等功能一应俱全。
愿景:是成为 MyBatis 最好的搭档,就像 魂斗罗 中的 1P、2P,基友搭配,效率翻倍。

特性
快速入门
DROP TABLE IF EXISTS user;
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, ‘test1@baomidou.com‘),
(2, ‘Jack‘, 20, ‘test2@baomidou.com‘),
(3, ‘Tom‘, 28, ‘test3@baomidou.com‘),
(4, ‘Sandy‘, 21, ‘test4@baomidou.com‘),
(5, ‘Billie‘, 24, ‘test5@baomidou.com‘);
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>
导入其他数据源的包,web启动包,lombok。
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.21</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
spring:
datasource:
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mybatis_plus?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
type: com.alibaba.druid.pool.DruidDataSource
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
? ?private Long id; ? ?
private String name; ? ?
private Integer age; ? ?
private String email;
}
//继承了BaseMapper,所有简单的CRUD操作都已经编写完成了
public interface UserMapper extends BaseMapper<User> {
}
@MapperScan("com.yinrz.mapper") // 扫描我们的 mapper 文件夹
@Configuration // 配置类
public class MyBatisPlusConfig {
}
@SpringBootTest
public class MybatisPlusApplicationTests{
@Resource
UserMapper userMapper;
@Test
public void test01(){
List<User> users = userMapper.selectList(null);
for (User user:users){
System.out.println(user);
}
}
}
运行结果:

insert插入操作
@Test
public void testInsert() {
User user = new User();
user.setName("yinrz");
user.setAge(18);
user.setEmail("1760266861@qq.com");
int result = userMapper.insert(user);
System.out.println(result); // 受影响的行数 ? ?
System.out.println(user); // 发现id会自动回填
}

**我们发现id会自动回填 **
数据库插入的id的默认值为: ID_WORKER 全局的唯一id(雪花算法)
分布式系统唯一ID生成方法总汇:https://www.cnblogs.com/haoxinyue/p/5208136.html
我们可以修改插入的id的生成策略
@TableId(type = IdType.AUTO),数据库要开启主键自增!!!@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
@TableId(type = IdType.AUTO)
private Long id;
private String name;
private Integer age;
private String email;
}
public enum IdType { ? ?
AUTO(0), // 数据库id自增(数据库要开启主键自增!!!) ? ?
NONE(1), // 未设置主键 ? ?
INPUT(2), // 手动输入 ? ?
ID_WORKER(3), // 全局唯一id(默认)
UUID(4), // 全局唯一id,uuid ? ?
ID_WORKER_STR(5); //ID_WORKER的字符串表示法
}

update更新操作
@Test
public void testUpdate(){
User user = new User(); ?
user.setId(1255894026599604227L);
user.setName("yinrz2");
user.setAge(21);
?
int i = userMapper.updateById(user);
System.out.println(i);
}

**注意:updateById传入的参数是一个对象!通过条件自动拼接动态sql 。要在主键上加入@TableId注解,或者主键名就叫id!!! **
delete删除操作
@Test
public void testDeleteById() {
userMapper.deleteById(1255894026599604227L);
}

@Test
public void testDeleteBatchId() {
userMapper.deleteBatchIds(Arrays.asList(1L, 2L));
}

@Test
public void testDeleteMap() {
HashMap<String, Object> map = new HashMap<>();
map.put("name", "Tom");
userMapper.deleteByMap(map);
}

逻辑删除
物理删除 :从数据库中直接移除
逻辑删除 :再数据库中没有被移除,而是通过一个变量来让他失效! deleted = 0 变成 deleted = 1
管理员可以查看被删除的记录!防止数据的丢失,类似于回收站!
@TableLogic
private Integer deleted;
@Bean
public ISqlInjector sqlInjector() {
return new LogicSqlInjector();
}
@Test
public void testDeleteById() {
userMapper.deleteById(4L);
}

select查询操作
@Test
public void testSelectById() {
User user = userMapper.selectById(4L);
System.out.println(user);
}

@Test
public void testSelectByBatchId() {
List<User> users = userMapper.selectBatchIds(Arrays.asList(4,5));
for (User user : users) {
System.out.println(user);
}
}

@Test
public void testSelectByBatchIds() {
HashMap<String, Object> map = new HashMap<>(); // 自定义要查询
map.put("name", "Sandy");
map.put("age", 21);
List<User> users = userMapper.selectByMap(map);
users.forEach(System.out::println);
}

分页查询
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
@Test
public void testPage() {
// 参数一:当前页 // 参数二:页面大小
Page<User> page = new Page<>(1, 3);
userMapper.selectPage(page, null);
List<User> users = page.getRecords();
for (User user:users){
System.out.println(user);
}
System.out.println(page.getTotal());
}

乐观锁
乐观锁假设数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则返回给用户错误的信息,让用户决定如何去做。
当我们要对一个数据库中的一条数据进行修改的时候,为了避免同时被其他人修改,最好的办法就是直接对该数据进行加锁以防止并发。这种借助数据库锁机制,在修改数据之前先锁定,再修改的方式被称之为悲观锁。
乐观锁在修改时会带上version等于当前version值的条件,修改成功后会给version的值加1。加了乐观锁后,在并发环境下,多个人同时修改同一条数据时,只会有1个人修改成功,其他人修改失败。
如何实现:
@Version
private Integer version;
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
@Test
public void testOptimisticLocker() {
// 线程1
User user = userMapper.selectById(8L);
user.setName("yinrz3");
// 线程2
User user2 = userMapper.selectById(8L);
user2.setName("yinrz4");
//线程2先更新
userMapper.updateById(user2);
//线程1再更新
userMapper.updateById(user); // 如果没有乐观锁就会成功更新
}


自动填充
创建时间(gmt_create)、修改时间(gmt_modi?ed)几乎所有的表都要配置上,而且需要自动填充,我们不希望手动更新!
@TableField(fill = FieldFill.INSERT)
private Date createTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {
// 插入时的填充策略
@Override
public void insertFill(MetaObject metaObject) {
this.setFieldValByName("createTime", new Date(), metaObject);
this.setFieldValByName("updateTime", new Date(), metaObject);
}
// 更新时的填充策略
@Override
public void updateFill(MetaObject metaObject) {
this.setFieldValByName("updateTime", new Date(), metaObject);
}
}

性能分析插件
我们在平时的开发中,会遇到一些慢sql,性能分析插件会帮助我们输出每条 SQL 语句及其执行时间 。
@Bean
@Profile({"dev","test"})// 设置 dev test 环境开启,保证我们的效率
public PerformanceInterceptor performanceInterceptor() {
PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
performanceInterceptor.setMaxTime(500); //ms 设置sql执行的最大时间,如果超过了则不执行
performanceInterceptor.setFormat(true);
return performanceInterceptor;
}

? 如果超时:

条件查询器Wrapper
allEq,eq,ne(不等于),gt(大于),ge(大于等于),lt,le,between,notBetween,like,notLike,likeLeft(百分号在左边),likeRight(百分号在右边),isNull,isNotNull,in,notIn,inSql(子查询),notInSql,groupBy,orderBy(默认,升序,小到大),orderByAsc(升序),orderByDesc(降序),having,or,and,nested,apply,last,exists,notExists。
@Test
public void testWrapper() {
QueryWrapper<User> wrapper=new QueryWrapper<>();
wrapper.eq("name","yinrz") //name = yinrz
.between("age",18,22) //age BETWEEN 18 AND 22
.like("name","a") // email LIKE %a%
.notLike("email","b") //email NOT LIKE %b%
.likeRight("email","c") //email LIKE c%
.likeLeft("email","d") //email LIKE %d
.inSql("id","select id from user where id < 10") //id IN (select id from user where id < 10)
.orderByDesc("id"); //ORDER BY id DESC
List<User> users = userMapper.selectList(wrapper);
for (User user :users){
System.out.println(user);
}
}

代码自动生成器
AutoGenerator 是 MyBatis-Plus 的代码生成器,通过 AutoGenerator 可以快速生成 Entity、 Mapper、Mapper XML、Service、Controller 等各个模块的代码,极大的提升了开发效率。
public static void main(String[] args) {
//代码自动生成器
AutoGenerator autoGenerator = new AutoGenerator();
//1.全局配置
GlobalConfig gc=new GlobalConfig();
gc.setOutputDir(System.getProperty("user.dir")+"/src/main/java"); //文件输出路径
gc.setAuthor("yinrz"); //作者名
gc.setOpen(false); //是否打开文件
gc.setDateType(DateType.ONLY_DATE); //设置创建的日期
gc.setFileOverride(false); //是否覆盖
gc.setServiceName("%sService"); //去Service的I前缀
gc.setIdType(IdType.ID_WORKER); //主键填充策略
gc.setSwagger2(true); //是否加入Swagger注解
autoGenerator.setGlobalConfig(gc);
//2.配置数据源
DataSourceConfig dsc=new DataSourceConfig();
dsc.setDriverName("com.mysql.cj.jdbc.Driver");
dsc.setUrl("jdbc:mysql://localhost:3306/mybatis_plus?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8");
dsc.setUsername("root");
dsc.setPassword("root");
dsc.setDbType(DbType.MYSQL);
autoGenerator.setDataSource(dsc);
//3.配置包
PackageConfig pc = new PackageConfig();
//pc.setModuleName("xxx"); //模块名
pc.setParent("com.yinrz"); //父包名
pc.setEntity("entity");
pc.setMapper("mapper");
pc.setService("service");
pc.setController("controller");
autoGenerator.setPackageInfo(pc);
//4.配置策略
StrategyConfig strategy = new StrategyConfig();
strategy.setInclude("user"); //数据库的表名
strategy.setNaming(NamingStrategy.underline_to_camel); //数据库表名驼峰命名
strategy.setColumnNaming(NamingStrategy.underline_to_camel); //数据库字段驼峰命名
strategy.setEntityLombokModel(true); //加lombok注解
strategy.setLogicDeleteFieldName("deleted"); //逻辑删除的字段名
//配置自动填充
TableFill gmtCreate = new TableFill("gmt_create", FieldFill.INSERT);
TableFill gmtModified = new TableFill("gmt_modified", FieldFill.INSERT_UPDATE);
ArrayList<TableFill> tableFills = new ArrayList<>();
tableFills.add(gmtCreate);
tableFills.add(gmtModified);
strategy.setTableFillList(tableFills);
strategy.setVersionFieldName("version"); //乐观锁的字段名
strategy.setRestControllerStyle(true); //RestController注解
strategy.setControllerMappingHyphenStyle(true); // 类似于localhost:8080/hello_id_2
autoGenerator.setStrategy(strategy);
//执行代码生成
autoGenerator.execute();
}

原文:https://www.cnblogs.com/yinrz/p/12812407.html