1. 简介
MyBatis-Plus
(简称
MP
)是一个
MyBatis
的增强工具
,在
MyBatis
的基础上
只做增强不做改变
,为
简化开发、提高效率而生
2. 依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.17</version>
</dependency>
3. 配application.yaml
spring: # 配置数据源信息
datasource: # 配置数据源类型
type: com.zaxxer.hikari.HikariDataSource # 配置连接数据库信息
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mybatis_plus?
characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8
username: root password: 123456
4. 添加mapper
public interface
UserMapper
extends
BaseMapper
<
User
>
{ }
5. 配日志
# 配置MyBatis日志
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
6. 通用service
/**
* ServiceImpl实现了IService,提供了IService中基础功能的实现
* 若ServiceImpl无法满足业务需求,则可以使用自定的UserService定义方法,并在实现类中实现
*/
@Service public class UserServiceImpl extends ServiceImpl<UserMapper, User>
implements UserService { }
7. 常用注解
@TableName
//使实体类名与数据库中的表名一致
@TableName(t_user)
public class User{
}
//等价于
mybatis-plus: configuration: # 配置MyBatis日志
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config: # 配置MyBatis-Plus操作表的默认前缀
table-prefix: t_
# 配置MyBatis-Plus的主键策略
id-type: auto
@TableId
/**
* MyBatis-Plus在实现CRUD时,会默认将id作为主键列,并在插入数据时,默认
* 基于雪花算法的策略生成id
* 主键不是 id 则需要将使用 @TableId设置这个属性为主键,并可以通过value属性的值与数据库中表中 * 的主键相对应
* ASSIGN_ID(默认,雪花算法) IdType.AUTO(主键自增,要求数据库表的主键开启了自增属性)
*/
@TableId(value = "id",type = IdType.AUTO)
@TableField
//MyBatis-Plus会自动将下划线命名风格转化为驼峰命名风格
//@TableField与@TableId一致,只是使用的是表中普通字段
@TableField("user_name")
private String name;
@TableLogin
//逻辑删除 将对应数据中代表是否被删除字段的状态修改为“被删除状态”,之后在数据库
//中仍旧能看到此条数据记录,可以进行数据的恢复
@TableLogic
private Integer isDeleted;
@Version (乐观锁)
@Version
private Integer version;
@Configuration
@MapperScan("com.example.demo.mapper")
public class MyBatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor plusInterceptor=new MybatisPlusInterceptor();
//添加page分页插件
plusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
//添加乐观锁插件
plusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return plusInterceptor;
}
8. 雪花算法
数据库的扩展方式主要包括:业务分库、主从复制,数据库分表
主从复制:在 master 机上写,在 slave 机上读
业务分库:
1、垂直分库:
专库专用
2、水平分库:把同一个表按一定规则拆分到不同的数据库中,每个库可以位于不同的服务器上
数据库分表:
1、垂直分表:将一张表
频繁访问的字段单独拆成一张表,将
不太访问到的字段或
大字段拆分出来创建一个单独的扩展表
2、 水平分表:在
同一个数据库内,把一张大数据量的表按一定规则,切分成多个结构完全相同表,而每个表只存原表的一部分数据。
2.1 主键自增:按照固定的
范围大小进行分段
优点:可以随着数据的增加平滑地扩充新的表,增加新表,不改原表
缺点:
分布不均匀。(如一张表100万条数据,后一张表1条数据)
2.2 取模:user_id % 10
优点:表分布比较均匀。
缺点:扩充新的表很麻烦,所有数据都要重新分布。
2.3 雪花算法:
是由
Twitter公布的分布式主键生成算法,它能够保证不同表的主键的不重复性,以及相同表的主键的有序性。(64位)
优点:整体上按照时间自增排序,并且整个分布式系统内不会产生
ID
碰撞,并且效率较高。
9. 条件构造器
LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
//避免使用字符串表示字段,防止运行时错误
queryWrapper .like(StringUtils.isNotBlank(username), User::getName, username)
.ge(ageBegin != null, User::getAge, ageBegin)
.le(ageEnd != null, User::getAge, ageEnd);
//将(年龄大于20或邮箱为null)并且用户名中包含有a的用户信息修改
//组装set子句以及修改条件
UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
//lambda表达式内的逻辑优先运算
updateWrapper .set("age", 18)
.set("email", "user@atguigu.com")
.like("username", "a")
.and(i -> i.gt("age", 20)
.or().isNull("email"));
//condition
//StringUtils.isNotBlank()判断某字符串是否不为空且长度不为0且不由空白符(whitespace) 构成 queryWrapper .like(StringUtils.isNotBlank(username), "username", "a")
.ge(ageBegin != null, "age", ageBegin)
.le(ageEnd != null, "age", ageEnd);
10. 插件
1、分页插件
@Configuration
@MapperScan("com.example.demo.mapper")
public class MyBatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor plusInterceptor=new MybatisPlusInterceptor();
//添加page分页插件
plusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
//添加乐观锁插件
plusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return plusInterceptor;
}
xml自定义分页插件
/**
*自定义的sql语句,那些@TableId,@TableFiled注解 不会生效
* 所以属性名与字段名不一致要用 resultMap="BaseResultMap"来映射
* 根据年龄查询用户列表,分页显示
* @param page 分页对象,xml中可以从里面进行取值,传递参数 Page 即自动分页,必须放在第一位
* @param age 年龄 * @return
*/
public Page<User> pageInfo(Page<User> page,Integer age);
xxx.xml
<sql id="baseColumns">id,user_name,age,email</sql>
<select id="pageInfo" resultMap="BaseResultMap">
select<include refid="baseColumns" /> from t_user where age >= #{age}
</select>
2、乐观锁 ---> 7. 常用注解 @Version : 更新表操作时进行version的对照,相同则更新操作,否则更新操作失败,进行重试。
3. 悲观锁 : 当有人进行对表操作时,其他人禁止对表进行表操作
11. 枚举
@Getter
public enum SexEnum {
MALE(1, "男"),
FEMALE(2, "女");
//设置性别信息为枚举项,会将@EnumValue注解所标识的属性值存储到数据库
@EnumValue
private Integer sex;
private String sexName;
SexEnum(Integer sex, String sexName) {
this.sex = sex;
this.sexName = sexName;
}
mybatis-plus:
# 配置扫描通用枚举
type-enums-package: com.atguigu.mybatisplus.enums
12. 代码生成器
1.依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.31</version>
</dependency>
2. 快速生成
@SpringBootTest
public class FastAutoGeneratorTest {
public static void main(String[] args) {
FastAutoGenerator.create("jdbc:mysql://127.0.0.1:3306/mybatis_plus?characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8", "root", "123456")
.globalConfig(builder -> {
builder.author("ld") // 设置作者
// .enableSwagger() // 开启 swagger 模式
.fileOverride()// 覆盖已生成文件
.outputDir("E://JAVA//MyBatisPlus//FastAutoGenerator");// 指定输出目录
}).packageConfig(builder -> {
builder.parent("com.demo")// 设置父包名
.moduleName("mybatisplus") // 设置父包模块名
.pathInfo(Collections.singletonMap(OutputFile.mapperXml, "E://JAVA//MyBatisPlus//FastAutoGenerator")); // 设置mapperXml生成路径
}).strategyConfig(builder -> {
builder.addInclude("t_user") // 设置需要生成的表名
.addTablePrefix("t_", "c_"); // 设置过滤表前缀
}).templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker 引擎模板,默认的是Velocity引擎模板
.execute();
}
}
13. 多数据源
1、依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.5.0</version>
</dependency>
2. 配置多数据源
spring:
# 配置数据源信息
datasource:
dynamic:
# 设置默认的数据源或者数据源组,默认值即为
master primary: master
# 严格匹配数据源,默认false.true未匹配到指定数据源时抛异常,false使用默认数据源
strict: false
datasource:
master:
url: jdbc:mysql://localhost:3306/mybatis_plus?characterEncoding=utf- 8&useSSL=false&serverTimeZone=GMT%2B8
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: 123456
slave_1:
url: jdbc:mysql://localhost:3306/mybatis_plus_1?characterEncoding=utf- 8&useSSL=false&serverTimeZone=GMT%2B8
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: 123456
3. 创建用户service
public interface UserService extends IService<User> { }
@DS("master")
//指定所操作的数据源
@Service public class UserServiceImpl extends ServiceImpl<UserMapper, User>
implements UserService { }
4. 创建商品service
public interface ProductService extends IService<Product> { }
@DS("slave_1")
@Service public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements ProductService { }
5 测试
@Autowired
private UserService userService;
@Autowired
private ProductService productService;
@Test public void testDynamicDataSource(){
System.out.println(userService.getById(1L));
System.out.println(productService.getById(1L));
}
将写操作方法加上主库数据源,读操作方法加上从库数据源,自动切换实现了读写分离
14. MyBatisX插件
MyBatisX
插件用法:
https://baomidou.com/pages/ba5b24/