注意点:我们在主启动类上需要扫描我们持久层文件下的所以接口
@MapperScan("com.kuang.mapper")
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

- //测试插入
- @Test
- public void testInsert(){
- User user= new User();
- user.setName("直接起飞");
- user.setAge(78);
- user.setEmail("23672367@qq.com");
- int result=userMapper.insert(user);
- System.out.println(result);
-
- }

数据库插入的id:全局唯一id
默认ID_WORKER全局唯一id
分布式系统唯一id生成:https://blog.csdn.net/qq_37469055/article/details/118061067
雪花算法就是使用64位long类型的数据存储id,最高位一位存储0或者1,0代表整数,1代表负数,一般都是0,所以最高位不变,41位存储毫秒级时间戳,10位存储机器码(包括5位datacenterId和5位workerId),12存储序列号。这样最大2的10次方的机器,也就是1024台机器,最多每毫秒每台机器产生2的12次方也就是4096个id。
主键自增
我们需要配置主键自增:
1.实体类字段上 @TableId(type = IdType.AUTO)
2.数据库字段一定要是自增的!

3.再测试
其余源码解释
public enum IdType {
AUTO(0), //数据库id自增
NONE(1), //未设置主键
INPUT(2), //手动输入
ID_WORKER(3), //默认全局唯一id
UUID(4), //全局唯一id uuid
ID_WORKER_STR(5); //ID_WORKER 字符串表示法
}
- //更新操作
- @Test
- public void testUpdata() {
- User user = new User();
- //通过条件自动拼接动态sql
- user.setId(6L);
- user.setName("高原起飞");
- //注意:updateById 但是参数是一个对象!
- int result = userMapper.updateById(user);
- System.out.println(result);
- }

- //更新操作
- @Test
- public void testUpdata() {
- User user = new User();
- //通过条件自动拼接动态sql
- user.setId(6L);
- user.setAge(18);
- user.setName("高原起飞");
- //注意:updateById 但是参数是一个对象!
- int result = userMapper.updateById(user);
- System.out.println(result);
- }
所有的sql都是自动帮你动态配置!
创建时间,修改时间!这些操作都是自动化完成的,我们不希望手动更新!
阿里巴巴开发手册:所有的表都应该配置有gmt_create,gmt_modified几乎所有的表都要配置上,且需要自动化。
方式一:数据库级别
1.在表中设置字段,create_time,update_time

2.更新实体类
- private Date createTime;
- private Date updateTime;
3.重新测试插入实体类信息

方式二:代码级别
1.数据库设置

2.实体类属性设置
- @TableField(fill = FieldFill.INSERT)
- private Date createTime;
- @TableField(fill = FieldFill.INSERT_UPDATE)
- private Date updateTime;
3.继承提供的类实现其方法
-
- @Slf4j
- @Component //一定不要忘记把处理器加到IOC容器中
- public class MyMetaObjectHandler implements MetaObjectHandler {
- //插入时的填充策略
- @Override
- public void insertFill(MetaObject metaObject) {
- log.info("start insert fill......");
- //setFieldValByName(String fieldName, Object fieldVal, MetaObject metaObject)
- // 填充的字段名 填充的值 meatObject
- this.setFieldValByName("creatTime",new Date(),metaObject);
- this.setFieldValByName("updateTime",new Date(),metaObject);
- }
-
- //更改时的填充策略
- @Override
- public void updateFill(MetaObject metaObject) {
- log.info("start update fill......");
- this.setFieldValByName("updateTime",new Date(),metaObject);
- }
- }
4.进行测试
插入数据测试

修改数据测试
5.结果查看:注意时间
![]()
![]()
乐观锁:顾名思义,它总是认为不会出现问题,无论干什么都不去上锁!如果出现了问题,再次更新值测试!
悲观锁:顾名思义,它总是认为总是出现问题,无论干什么都上锁!再去操作!
乐观锁实现方式:

1.给数据库添加version字段,默认为1
![]()
2.需要实体类加上对应的字段
- //乐观锁字段
- @Version
- private Integer version;
3.注册组件
-
- import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
- import org.mybatis.spring.annotation.MapperScan;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.transaction.annotation.EnableTransactionManagement;
-
- @EnableTransactionManagement //自动事务管理
- //使用配置类后,扫描持久层工作可以放到这里来,不在启动类上进行扫描
- @MapperScan("com.kuang.mapper")
- @Configuration //配置类
- public class MybatisPlusConfig {
-
- //注册乐观锁插件
- @Bean
- public OptimisticLockerInterceptor optimisticLockerInterceptor() {
- return new OptimisticLockerInterceptor();
- }
-
- }
4.测试一下
- // 测试乐观锁成功
- @Test
- public void testVersionSuccess(){
- // 1. 查询用户信息
- User user = userMapper.selectById(1L);
- // 2. 修改用户信息
- user.setName("嘎嘎");
- user.setAge(24);
- // 3. 执行更新操作
- userMapper.updateById(user);
- }
-
- // 测试乐观锁失败!多线程下
- @Test
- public void testVersionFall(){
- // 线程1
- User user1 = userMapper.selectById(1L);
- user1.setName("嘎嘎111");
- user1.setAge(14);
-
- // 线程2
- User user2 = userMapper.selectById(1L);
- user2.setName("嘎嘎222");
- user2.setAge(24);
- userMapper.updateById(user2);
-
- //因为user2的抢先执行使得user1中保存的version与user2执行后的不同,user1无法修改
- //自旋锁来多次尝试提交!
- userMapper.updateById(user1); //如果没有乐观锁就会覆盖插队线程的值
- }
5.测试结果
成功的结果

失败的结果
![]()
- // 测试查询
- @Test
- public void testSelectById(){
- User user = userMapper.selectById(1);
- System.out.println(user);
- }
-
- // 批量查询
- @Test
- public void testSelectByBatchIds(){
- List
users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3)); - users.forEach(System.out::println);
- }
-
- // 按照条件查询之一使用 map
- @Test
- public void testSelectByMap(){
- HashMap
map = new HashMap<>(); - // 自定义要查询
- map.put("name","Tom");
- map.put("age","28");
- List
users = userMapper.selectByMap(map); - users.forEach(System.out::println);
- }
分页网站频繁使用
分页查询操作方法
1.配置拦截器
- // 分页插件
- @Bean
- public PaginationInterceptor paginationInterceptor() {
- return new PaginationInterceptor();
- }
2.直接使用Page对象即可
- // 测试分页查询
- @Test
- public void testPage(){
- // 参数一: 当前页
- // 参数二: 页面大小
- // 使用了分页插件之后,所有的分页操作变得简单了
- Page
page = new Page<>(1,5); - userMapper.selectPage(page, null);
-
- page.getRecords().forEach(System.out::println);
- //内置许多方法,如下是得到总记录的条数
- System.out.println(page.getTotal());
- }
- // 测试删除
- @Test
- public void testdelete(){
- userMapper.deleteById(6L);
- }
-
- // 测试批量删除
- @Test
- public void testdeleteBatchId(){
- userMapper.deleteBatchIds(Arrays.asList(1287326823914405893L,1287326823914405894L));
- }
-
- //通过map删除
- @Test
- public void testDeleteByMap(){
- HashMap
map = new HashMap<>(); - map.put("name","KUANG");
- userMapper.deleteByMap(map);
- }
物理删除:从数据库中直接移除
逻辑删除:在数据库中没有被移除,而是通过一个变量让他生效!deleted=0 --> deleted=1
测试:
在数据库表中增加一个deleted字段
实体类中增加属性
- @TableLogic // 逻辑删除
- private Integer deleted;
3.配置
- // 逻辑删除组件
- public ISqlInjector sqlInjector(){
- return new LogicSqlInjector();
- }
- # 配置逻辑删除
- mybatis-plus.global-config.db-config.logic-delete-value=1
- mybatis-plus.global-config.db-config.logic-not-delete-value=0
4.测试删除
5.测试查询
以上所有的CRUD操作及其扩展操作,我们必须精通掌握!会大大提高工作效率!
我们在平时的开发中,会遇到一些慢sql。解决方案:测试,druid监控…
作用:性能分析拦截器,用于输出每条SQL语句及其执行时间
MyBatisPlus也提供性能分析插件,如果超过这个时间就停止运行!
1.导入插件
- // SQL执行效率插件
- @Bean
- @Profile({"dev","test"})
- public PerformanceInterceptor performanceInterceptor(){
- PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
- performanceInterceptor.setMaxTime(100); //ms 设置sql执行的最大时间,如果超过了则不执行
- performanceInterceptor.setFormat(true); // 是否格式化
- return performanceInterceptor;
- }
记住,要在SpringBoot中配置环境为dev或者test环境!
2.测试使用
- // 测试查询
- @Test
- public void testSelectById(){
- User user = userMapper.selectById(3);
- System.out.println(user);
- }
只要超出时间就会抛出异常
使用性能分析插件可以提高效率,新版本MP已经移除该拆件了,可以使用druid