1.分页插件
(1)进行分页的配置
@Configuration
public class MybatisConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
(2)进行分页操作代码为:
@Test
public void testPage(){
Page<User> page=new Page<>(1,3);
userMapper.selectPage(page,null);
System.out.println(page);
}
结果为:
==> Preparing: SELECT COUNT(*) AS total FROM t_user WHERE is_deleted = 0
==> Parameters:
<== Columns: total
<== Row: 7
<== Total: 1
==> Preparing: SELECT uid AS id,user_name AS name,age,email,is_deleted FROM t_user WHERE is_deleted=0 LIMIT ?
==> Parameters: 3(Long)
<== Columns: id, name, age, email, is_deleted
<== Row: 4, 小明, 21, ddd@qq.com, 0
<== Row: 5, Billie, 24, test5@baomidou.com, 0
<== Row: 3432423, 小红, 23, ddd@qq.com, 0
<== Total: 3
分页信息查询:
代码为:
@Test
public void testPage(){
Page<User> page=new Page<>(2,3);
userMapper.selectPage(page,null);
System.out.println(page.getRecords());
System.out.println(page.getCurrent());
System.out.println(page.getPages());
System.out.println(page.getTotal());
System.out.println(page.hasPrevious());
}
结果为:
==> Preparing: SELECT COUNT(*) AS total FROM t_user WHERE is_deleted = 0
==> Parameters:
<== Columns: total
<== Row: 7
<== Total: 1
==> Preparing: SELECT uid AS id,user_name AS name,age,email,is_deleted FROM t_user WHERE is_deleted=0 LIMIT ?,?
==> Parameters: 3(Long), 3(Long)
<== Columns: id, name, age, email, is_deleted
<== Row: 325235235, 小明, 24, ddd@qq.com, 0
<== Row: 1572498526069858305, 张三, 23, dongbin@qq.com, 0
<== Row: 1572500666821685249, 张三, 23, dongbin@qq.com, 0
<== Total: 3
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2721044]
[User(id=325235235, name=小明, age=24, email=ddd@qq.com, isDeleted=0), User(id=1572498526069858305, name=张三, age=23, email=dongbin@qq.com, isDeleted=0), User(id=1572500666821685249, name=张三, age=23, email=dongbin@qq.com, isDeleted=0)]
2
3
7
true
(3)自定义分页
创建接口和抽象方法
/**
* 通过年龄查询用户信息并分页
* @param page Mybatis-plus所提供的分页对象,必须位于第一个参数的位置
* @param age
* @return
*/
Page<User> selectPageVo(@Param("page") Page<User> page, @Param("age") Integer age);
配置mapper:
<select id="selectPageVo" resultType="User">
select uid,user_name,age,email from t_user where age>#{age}
</select>
测试:
@Test
public void testPageVo(){
Page<User> page = new Page<>(1,3);
userMapper.selectPageVo(page,20);
System.out.println(page.getRecords());
System.out.println(page.getCurrent());
System.out.println(page.getPages());
System.out.println(page.getTotal());
System.out.println(page.hasPrevious());
}
结果为:
==> Preparing: SELECT COUNT(*) AS total FROM t_user WHERE age > ?
==> Parameters: 20(Integer)
<== Columns: total
<== Row: 17
<== Total: 1
==> Preparing: select uid,user_name,age,email from t_user where age>? LIMIT ?
==> Parameters: 20(Integer), 3(Long)
<== Columns: uid, user_name, age, email
<== Row: 3, Tom, 28, test3@baomidou.com
<== Row: 4, 小明, 21, ddd@qq.com
<== Row: 5, Billie, 24, test5@baomidou.com
<== Total: 3
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6bee793f]
[User(id=null, name=null, age=28, email=test3@baomidou.com, isDeleted=null), User(id=null, name=null, age=21, email=ddd@qq.com, isDeleted=null), User(id=null, name=null, age=24, email=test5@baomidou.com, isDeleted=null)]
1
6
17
false
2 类型别名配置
在配置文件中进行添加 :
mybatis-plus:
type-aliases-package: com.example.demo.pojo
3 乐观锁
(1)创建数据库t_product
CREATE TABLE t_product
(
id BIGINT(20) NOT NULL COMMENT '主键ID',
NAME VARCHAR(30) NULL DEFAULT NULL COMMENT '商品名称', price INT(11) DEFAULT 0 COMMENT '价格',
VERSION INT(11) DEFAULT 0 COMMENT '乐观锁版本号', PRIMARY KEY (id)
);
(2)添加数据:
INSERT INTO t_product (id, NAME, price) VALUES (1, '外星人笔记本', 100);
(3)创建实体类Product
@Data
public class Product {
private Long id;
private String name;
private Integer price;
private Integer version;
}
(4)创建接口和抽象方法:
@Repository
public interface ProductMapper extends BaseMapper<Product> {
}
(5)举例代码:
@Test
public void testProduct101(){
//小李查询商品价格
Product productLi = productMapper.selectById(1);
System.out.println("小李查询的商品价格"+productLi);
//小王查询商品价格
Product productWa = productMapper.selectById(1);
System.out.println("小王查询的商品价格"+productWa);
//小李将价格+50
productLi.setPrice(productLi.getPrice()+50);
productMapper.updateById(productLi);
//小王将商品减30
productWa.setPrice(productWa.getPrice()-30);
productMapper.updateById(productWa);
//老板查询商品价格
Product productBoss = productMapper.selectById(1);
System.out.println("老板查询的商品价格"+productBoss);
}
经过查询,老板最后查询的内容为以小王为基础所做的改变并没有加上小李所更新的改变。
(6)解决问题方式
加入乐观锁(通过字段Version来判断该数据是否已经修改,若改变,后面的人将驳回修改sql)
增加乐观锁插件:
// 添加乐观锁插件
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
在类中加入@Version注解
@Version // 表示乐观锁
private Integer version;
测试:
@Test
public void testProduct101(){
//小李查询商品价格
Product productLi = productMapper.selectById(1);
System.out.println("小李查询的商品价格"+productLi);
//小王查询商品价格
Product productWa = productMapper.selectById(1);
System.out.println("小王查询的商品价格"+productWa);
//小李将价格+50
productLi.setPrice(productLi.getPrice()+50);
productMapper.updateById(productLi);
//小王将商品减30
productWa.setPrice(productWa.getPrice()-30);
productMapper.updateById(productWa);
//老板查询商品价格
Product productBoss = productMapper.selectById(1);
System.out.println("老板查询的商品价格"+productBoss);
}
结果仅为小李操作后的数据,其字段version+1
4 通用枚举
一些变量的取值被限制在一个有限的范围内如男为0,女为1
(1)创建枚举
枚举头部加上@Getter注解,仅用来get
@Getter
public enum SexEnum {
MALE(1,"男"),
FEMALE(2,"女");
@EnumValue //将注解标识的属性的值存储到数据库中
private Integer sex;
private String sexName;
SexEnum(Integer sex, String sexName) {
this.sex = sex;
this.sexName = sexName;
}
(2)添加扫描枚举配置
# 扫描通用枚举的包
type-enums-package: com.example.demo.enums
(3)赋值操作
将符合的枚举值加入其中,在对应的 属性上加上@EnumValue,将注解标识的属性的值存储到数据库中
(4)测试
@SpringBootTest
public class MybatisEnumTest {
@Autowired
private UserMapper userMapper;
@Test
public void test(){
User user = new User();
user.setName("admin");
user.setAge(33);
user.setSex(SexEnum.MALE);
int result = userMapper.insert(user);
System.out.println(result);
}
测试结果为:
==> Preparing: INSERT INTO t_user ( user_name, age, sex ) VALUES ( ?, ?, ? )
==> Parameters: admin(String), 33(Integer), 1(Integer)
<== Updates: 1
5 代码生成器
见官方文档
https://baomidou.com/pages/779a6e/#%E4%BD%BF%E7%94%A8
6 多数据源
适用于多种场景:纯粹多库、读写分离、一主多从、混合模式等
实现一主多从:
创建user和product在不同数据库中,分别建立实体类
(1)进行数据源配置
spring:
datasource:
# 配置数据源信息 datasource:
dynamic:
# 设置默认的数据源或者数据源组,默认值即为master
primary: master
# 严格匹配数据源,默认false.true未匹配到指定数据源时抛异常,false使用默认数据源
strict: false
datasource:
master:
url: jdbc:mysql://localhost:3306/mybatis_plus?serverTimezone=GMT%2B8&characterEncoding=utf-8&useSSL=false
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: 123456
slave_1:
# 我的数据库是8.0.27 5版本的可以使用jdbc:mysql://localhost:3306/mybatis_plus?characterEncoding=utf-8&useSSL=false
url: jdbc:mysql://localhost:3306/mybatis_plus_1?serverTimezone=GMT%2B8&characterEncoding=utf-8&useSSL=false
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: 123456
(2) 在对应的业务实现类中加上@DS注解即可
@Service
@DS("slave_1")
public class ProductServiceImpl extends ServiceImpl<ProductMapper, Product> implements ProductService {
}
@Service
@DS("master")
public class UserServiceImpl extends ServiceImpl<UserMapper, User>implements UserService {
}