MyBatis-Plus

MyBatisPlus概述

无侵入 :只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
损耗小 :启动即会自动注入基本 CURD ,性能基本无损耗,直接面向对象操作, BaseMapper
强大的 CRUD 操作 :内置通用 Mapper 、通用 Service ,仅仅通过少量配置即可实现单表大部分
CRUD 操作,更有强大的条件构造器,满足各类使用需求 , 以后简单的 CRUD 操作,它不用自己写 了!
支持 Lambda 形式调用 :通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
支持主键自动生成 :支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence ),可自由配
置,完美解决主键问题
支持 ActiveRecord 模式 :支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大
CRUD 操作
支持自定义全局通用操作 :支持全局通用方法注入( Write once, use anywhere
内置代码生成器 :采用代码或者 Maven 插件可快速生成 Mapper Model Service
Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用(自动帮你生成代码)
内置分页插件 :基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同
于普通 List 查询
分页插件支持多种数据库 :支持 MySQL MariaDB Oracle DB2 H2 HSQL SQLite
Postgre SQLServer 等多种数据库
内置性能分析插件 :可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢
查询
内置全局拦截插件 :提供全表 delete update 操作智能分析阻断,也可自定义拦截规则,预防误
操作
MyBatisPlus可以节省我们大量工作时间,所有的CRUD代码它都可以自动化完成
创建一个SpringBoot项目
创建数据库 mybatis_plus
创建user表
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> mysql </groupId>
<artifactId> mysql-connector-java </artifactId>
</dependency>
<!-- lombok -->
<dependency>
<groupId> org.projectlombok </groupId>
<artifactId> lombok </artifactId>
</dependency>
<!-- mybatis-plus -->
<!-- mybatis-plus 是自己开发,并非官方的! -->
<dependency>
<groupId> com.baomidou </groupId>
<artifactId> mybatis-plus-boot-starter </artifactId>
<version> 3.0.5 </version>
</dependency>

 连接数据库!这一步和 mybatis 相同!

# mysql 5 驱动不同 com.mysql.jdbc.Driver
# mysql 8 驱动不同 com.mysql.cj.jdbc.Driver 、需要增加时区的配置
serverTimezone=GMT%2B8
spring.datasource.username = root
spring.datasource.password = admin
spring.datasource.url = jdbc : mysql : //localhost : 3306/mybatis_plus?
useSSL = false&useUnicode = true&characterEncoding = utf-8&serverTimezone = GMT%2B8
spring.datasource.driver-class-name = com.mysql.cj.jdbc.Driver

 使用mybatis,需要配置mapper.xml文件手写sql语句

使用了 mybatis-plus 之后
pojo
@Data 
@AllArgsConstructor
 @NoArgsConstructor
 public class User { 
    private Long id;
     private String name; 
    private Integer age; 
    private String email; 
}
mapper接口
package com.wu.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.wu.pojo.User;
import org.springframework.stereotype.Repository;
// 在对应的Mapper上面继承基本的类 BaseMapper
@Repository // 代表持久层
public interface UserMapper extends BaseMapper<User> {
// 所有的CRUD操作都已经编写完成了
// 你不需要像以前的配置一大堆文件了!
}
注意点,我们需要在主启动类上去扫描我们的mapper包下的所有接口
@MapperScan("com.wu.mapper")
 @Autowired
    UserMapper userMapper;


    @Test
    void contextLoads() {
        //查询全部
        // 参数是一个mapper ,条件构造器 ,不用可以为null
        List<User> userList = userMapper.selectList(null);
        userList.forEach(System.out::println);


    }
配置日志
# 配置日志
mybatis-plus.configuration.log-impl = org.apache.ibatis.logging.stdout.StdOutImpl

 CRUD扩展

Insert 插入

// 测试插入
 @Test
 public void testInsert(){ 
User user = new User(); 
user.setName("Java如此简单"); 
user.setAge(3); 
user.setEmail("22233@qq.com");
 int result = userMapper.insert(user); // 帮我们自动生成id 
System.out.println(result); // 受影响的行数
 System.out.println(user); // 发现,id会自动回填 
}
主键生成策略
默认 ID_WORKER 全局唯一 id

 主键自增(雪花算法 ,UUID)

我们需要配置主键自增:  
1 、实体类字段上@TableId(Type=IdType.AUTO)
2 、数据库字段一定要是自增!
3 、再次测试插入即可!

 

 更新操作

// 测试更新 
@Test public void testUpdate(){ 
User user = new User(); // 通过条件自动拼接动态sql 
user.setId(6L); 
user.setName("关注公众号:狂神说"); 
user.setAge(18); // 注意:updateById 但是参数是一个 对象!
 int i = userMapper.updateById(user);
 System.out.println(i); }
乐观锁
乐观锁 : 故名思意十分乐观,它总是认为不会出现问题,无论干什么不去上锁!如果出现了问题,
再次更新值测试
悲观锁:故名思意十分悲观,它总是认为总是出现问题,无论干什么都会上锁!再去操作!

 

乐观锁: 1 、先查询,获得版本号 version = 1
-- A
update user set name = "kuangshen" , version = version + 1
where id = 2 and version = 1
-- B 线程抢先完成,这个时候 version = 2 ,会导致 A 修改失败!
update user set name = "kuangshen" , version = version + 1
where id = 2 and version = 1

 1、给数据库中增加version字段!

2、我们实体类加对应的字段

@Version // 乐观锁 Version 注解
private Integer version ;

 3、注册组件

// 扫描我们的 mapper 文件夹 @MapperScan("com.kuang.mapper")
 @EnableTransactionManagement
 @Configuration // 配置类
 public class MyBatisPlusConfig { 
// 注册乐观锁插件
 @Bean 
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
 return new OptimisticLockerInterceptor(); 
}
 }
4 、测试一下!

 

// 测试乐观锁成功!
@Test
public void testOptimisticLocker (){
// 1 、查询用户信息
User user = userMapper . selectById ( 1L );
// 2 、修改用户信息
user . setName ( "不想玩了" );
user . setEmail ( "2361577441@qq.com" );
// 3 、执行更新操作
userMapper . updateById ( user );
}

 

// 测试乐观锁失败!多线程下
@Test
public void testOptimisticLocker2 (){
// 线程 1
User user = userMapper . selectById ( 1L );
user . setName ( "111111" );
user . setEmail ( "23465@qq.com" );
// 模拟另外一个线程执行了插队操作
User user2 = userMapper . selectById ( 1L );
user2 . setName ( "222222" );
user2 . setEmail ( "110@qq.com" );
userMapper . updateById ( user2 );
// 自旋锁来多次尝试提交!
userMapper . updateById ( user ); // 如果没有乐观锁就会覆盖插队线程的值!
}

 查询操作

 

// 测试查询
@Test
public void testSelectById (){
User user = userMapper . selectById ( 1L );
System . out . println ( user );
}
// 测试批量查询!
@Test
public void testSelectByBatchId (){
List < User > users = userMapper . selectBatchIds ( Arrays . asList ( 1 , 2 , 3 ));
users . forEach ( System . out :: println );
}
// 按条件查询之一使用 map 操作
@Test
public void testSelectByBatchIds (){
HashMap < String , Object > map = new HashMap <> ();
// 自定义要查询
map . put ( "name" , " Java如此简单" );
map . put ( "age" , 3 );
List < User > users = userMapper . selectByMap ( map );
users . forEach ( System . out :: println );
}

 分页查询

1 、原始的 limit 进行分页
2 pageHelper 第三方插件
3 MP 其实也内置了分页插件!
1 、配置拦截器组件即可
// 分页插件
@Bean
public PaginationInterceptor paginationInterceptor () {
return new PaginationInterceptor ();
}

2、直接使用Page对象即可! 

// 测试分页查询
@Test
public void testPage (){
// 参数一:当前页
// 参数二:页面大小
// 使用了分页插件之后,所有的分页操作也变得简单的!
Page < User > page = new Page <> ( 2 , 5 );
userMapper . selectPage ( page , null );
page . getRecords (). forEach ( System . out :: println );
System . out . println ( page . getTotal ());
}

 

删除操作
1 、根据 id 删除记录

 

// 测试删除
@Test
public void testDeleteById (){
userMapper . deleteById ( 1240620674645544965L );
}
// 通过 id 批量删除
@Test
public void testDeleteBatchId (){
userMapper . deleteBatchIds ( Arrays . asList ( 1240620674645544961L , 124062067464554496
2L ));
}
// 通过 map 删除
@Test
public void testDeleteMap (){
HashMap < String , Object > map = new HashMap <> ();
map . put ( "name" , " 狂神说 Java" );
userMapper . deleteByMap ( map );

 逻辑删除:

物理删除 :从数据库中直接移除
逻辑删除 :再数据库中没有被移除,而是通过一个变量来让他失效  deleted=0=> deleted = 1

 1、在数据表中增加一个 deleted 字段

2、实体类中增加属性

@TableLogic //逻辑删除

private Integer deleted ;

3、配置!

// 逻辑删除组件!
@Bean
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
 //测试删除
    @Test
    public void testdeleteById() {
        userMapper.deleteById(5l);
    }

    //批量ID删除
    @Test
    public void testDeleteBatchId() {
        userMapper.deleteBatchIds(Arrays.asList(1493186264636956673l, 1493188750437318658l));
    }

    //map删除
    @Test
    public void testDmap() {
        HashMap<String, Object> map = new HashMap<>();
        map.put("name", "天基王");


        userMapper.deleteByMap(map);
    }

 删除后再次查询会自动过滤逻辑删除的字段防止数据丢失

 测试!

@SpringBootTest
public class WrapperTest {
    @Autowired
    UserMapper userMapper;
    @Autowired
    UserService userService;
    @Test
    void test() {
        //查询name不为空的用户,并且邮箱不为空的用户,年龄小于20000
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper
                .isNotNull("name") //名字不为空
                .isNotNull("email") //邮箱不为空
                .ge("age", 2000);   //age大于等于2000
        userMapper.selectList(wrapper)
                .forEach(System.out::println);  //和map  相似


    }

    @Test
    void test1() {
        //查询名字  凯莎
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.eq("name", "凯莎");
        User user = userMapper.selectOne(wrapper); //查询一个数据  .selectOne
        System.out.println(user);


    }

    @Test
    void test2() {
        //查询 22到30
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.between("age", 22, 30); //20到30区间
        Long count = userMapper.selectCount(wrapper);//查询结果数
        System.out.println(count);
    }


    @Test
    void test3() {
        //模糊查询
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper
                .notLike("name", "e")// 不包含e的名字
                .likeRight("email", "t"); //左和右(t%)在%左边  t开头的

        List<Map<String, Object>> maps = userMapper.selectMaps(wrapper);
        maps.forEach(System.out::println);
    }


    @Test
    void test4() {
        //内嵌查询
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        //id 在子查询中查出来
        wrapper.inSql("id", "select id  from user where id<3");
        List<Object> objects = userMapper.selectObjs(wrapper);
        objects.forEach(System.out::println);
    }

    @Test
    void test5() {

        QueryWrapper<User> wrapper = new QueryWrapper<>();
        //通过id降序 排序
        wrapper.orderByDesc("id");

        List<User> list = userMapper.selectList(wrapper);
        list.forEach(System.out::println);
    }
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值