MyBatisPlus

1.配置

连接配置

# MySQL5 驱动不同  com.mysql.jdbc.Driver

# MySQL8 驱动不同  com.mysql.cj.jdbc.Driver 需要增加时区的配置  severTimezone=GMT%2B8


spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver    
    url: jdbc:mysql://localhost:3306/数据库名字?
useUnicode=true&characterEncoding=utf8&useSSL=false&severTimezone=GMT%2B8
    username: root
    password: root

配置日志 可以打印执行的SQL语句

mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

 导入的依赖


    <dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

<!--        数据库连接的-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>


        <!--        mybatis-plus-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.5.1</version>
        </dependency>

        <!--        代码构造生成器的-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-generator</artifactId>
            <version>3.5.1</version>
        </dependency>


        <!--  模板-->
        <dependency>
            <groupId>org.apache.velocity</groupId>
            <artifactId>velocity-engine-core</artifactId>
            <version>2.2</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/io.swagger/swagger-annotations -->
        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-annotations</artifactId>
            <version>1.6.2</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>

        <!--
         资源插件 告诉maven把 src/main/java目录中的 指定扩展名的文件 拷贝到 target/classes目录中。
        -->
        <resources>
            <resource>
                <directory>src/main/java</directory><!--所在的目录-->
                <includes>
                    <!--包括目录下的.properties,.xml 文件都会扫描到-->
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <!--  filtering 选项 false 不启用过滤器, *.property 已经起到过
                        滤的作用了 -->
                <filtering>false</filtering>
            </resource>
        </resources>

2.CRUD

 @Autowired
    private UserMapper userMapper;


    //新增
    @Test
    public void testInsert() {
        User user = new User().setName("三水").setAge(22).setEmail("4556445646");
        int insert = userMapper.insert(user);
        System.out.println("insert = " + insert);
    }


 //测试通过id删除单个
    @Test
    public void testDeleteById(){
        int i = userMapper.deleteById(2L);
        System.out.println("i = " + i);
    }

    //通过id批量删除
    @Test
    public void testDeleteBatchIds(){
        int i = userMapper.deleteBatchIds(Arrays.asList(4L,3L,5L));
        System.out.println("i = " + i);
    }

    //测试通过map删除
    @Test
    public void testDelete(){
        HashMap<String, Object> map = new HashMap<>();
        map.put("name","江东");
        map.put("age",22);

        int i = userMapper.deleteByMap(map);
        System.out.println("i = " + i);
    }


    //通过ID更新
    @Test
    public void testUpdateById(){
        User user = new User();
        user.setId(1495601226191011846L);
        user.setName("哈哈哈阿斯蒂芬");
        int i = userMapper.updateById(user);
        System.out.println("i = " + i);
    }

逻辑删除

物理删除:从数据库中直接移除

逻辑删除:在数据库中没有被移除

1.数据库中添加字段

is_deleted 

添加默认值是     0 表示没有被删除,1是被删除

添加配置

#  global-config:
#    db-config:
#      logic-delete-field: deleted
#      logic-delete-value: 1
#      logic-not-delete-value: 0

2.实体类中添加

@TableLogic    //添加注解
@TableField("is_deleted")  // 阿里规范不要is
private Integer deleted;

3.MP组件

3.1 分布式ID

MP默认给我们使用的就是分布式ID

 

使用

注意:

1.字段上需要添加一个注解 : @TableId(type = IdType.AUTO)

2.数据库中id要设置自增长

描述
AUTO数据库ID自增
NONE无状态,该类型为未设置主键类型(注解里等于跟随全局,全局里约等于 INPUT)
INPUTinsert前自行set主键值
ASSIGN_ID分配ID(主键类型为Number(Long和Integer)或String)(since 3.3.0),使用接口IdentifierGenerator的方法nextId(默认实现类为DefaultIdentifierGenerator雪花算法)
ASSIGN_UUID分配UUID,主键类型为String(since 3.3.0),使用接口IdentifierGenerator的方法nextUUID(默认default方法)
ID_WORKER分布式全局唯一ID 长整型类型(please use ASSIGN_ID)
UUID32位UUID字符串(please use ASSIGN_UUID)
ID_WORKER_STR分布式全局唯一ID 字符串类型(please use ASSIGN_ID)

3.2 自动填充

阿里规范中,每一张表至少都需要有三个字段,id,createTime,updateTime

  • 在数据库中添加create_time 和 update_time字段

  • 在实体类中添加createTime 和updateTime

  • 在属性上添加注解

     @TableField(value = "create_time", fill = FieldFill.INSERT)
     private Date createTime; // java.util
     ​
     @TableField(value = "update_time", fill = FieldFill.INSERT_UPDATE) // 在新增的,默认修改时间为新增时间
     private Date updateTime;
  • 新建一个handler

    @Slf4j
    @Component // 一定不要忘记把处理器加入到IOC容器中    只有在Spring容器中,才能使用Spring提供的功能
    public class MyMetaObjectHandler implements MetaObjectHandler {
        //插入时的填充策略
        @Override
        public void insertFill(MetaObject metaObject) {
            log.info("start insert fill.....");
            // 每一次新增的时候会自动的执行 fieldName = 实体类字段
            //setFieldValByName(String fieldName, Object fieldVal, MetaObject metaObject)
            this.setFieldValByName("createTime", 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);
        }
    }

    3.3乐观锁

乐观锁:顾名思义十分乐观,它总是认为不会出现问题,无论干什么不去上锁!如果出现了问题,再次更新测试值

悲观锁:顾名思义十分悲观,它总是认为总是会出现问题,无论干什么都会上锁,再去操作! 

当要更新一条记录的时候,希望这条记录没有被别人更新
乐观锁实现方式:

  • 取出记录时,获取当前 version
  • 更新时,带上这个 version
  • 执行更新时, set version = newVersion where version = oldVersion
  • 如果 version 不对,就更新失败

3.3.1在数据库中加入version字段 

并且设置默认值是1

3.3.2.在实体类的字段上加上@Version注解

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

说明:

  • 支持的数据类型只有:int,Integer,long,Long,Date,Timestamp,LocalDateTime
  • 整数类型下 newVersion = oldVersion + 1
  • newVersion 会回写到 entity 中
  • 仅支持 updateById(id) 与 update(entity, wrapper) 方法
  • 在 update(entity, wrapper) 方法下, wrapper 不能复用!!!

3.3.3.注册组件

// Spring Boot 方式
@Configuration
@MapperScan("按需修改")
public class MybatisPlusConfig {
    /**
     * 旧版
     */
    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor() {
        return new OptimisticLockerInterceptor();
    }

    /**
     * 新版
     */
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return mybatisPlusInterceptor;
    }
}

多线程一定要加乐观锁!!! 

测试

 //测试乐观锁成功
    @Test
    public void TestOptimisticLocker1(){
        //1.查询用户表信息
        User user = userMapper.selectById(1L);
        //2.修改用户信息
        user.setName("陈超").setEmail("132465789@qq.com");
        //3.执行更新操作
        userMapper.updateById(user);

    }
    
    //测试乐观锁失败
    @Test
    public void TestOptimisticLocker2(){
        //线程1
        User user = userMapper.selectById(1L);
        user.setName("陈超111").setEmail("132465789@qq.com");

        //模拟另外一个线程执行了插队操作
        User user1 = userMapper.selectById(1L);
        user.setName("陈超222").setEmail("132465789@qq.com");
        userMapper.updateById(user1);


        userMapper.updateById(user);//如果没有乐观锁就会覆盖插队线程的值!

    }

3.4分页插件

配置拦截器插件

@Configuration
@MapperScan("com.jsd.mybatisplusdemo02.mapper")
public class MapperConfig {

    // 最新版
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {

        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        // 分页
        PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
        mybatisPlusInterceptor.addInnerInterceptor(paginationInnerInterceptor);


        //乐观锁
        OptimisticLockerInnerInterceptor optimisticLockerInnerInterceptor = new OptimisticLockerInnerInterceptor();
        mybatisPlusInterceptor.addInnerInterceptor(optimisticLockerInnerInterceptor);

        return mybatisPlusInterceptor;
    }
    
}
    //测试分页查询
    @Test
    public void testPage() {
        //参数1: 当前页
        //参数2: 页面大小
        Page<User> page = new Page<>(1, 3);
        Page<User> userPage = userMapper.selectPage(page, null);

        userPage.getRecords().forEach(System.out::println);

        //总记录数
        long total = page.getTotal();
        System.out.println("total = " + total);
        

        List<User> records = userPage.getRecords();
        System.out.println("records = " + records);



        List<User> records1 = page.getRecords();
        System.out.println("records1 = " + records1);



        long total1 = userPage.getTotal();
        System.out.println("total1 = " + total1);


    }

4.条件构造器

说明:

QueryWrapper(LambdaQueryWrapper) 和 UpdateWrapper(LambdaUpdateWrapper) 的父类
用于生成 sql 的 where 条件, entity 属性也用于生成 sql 的 where 条件
注意: entity 生成的 where 条件与 使用各个 api 生成的 where 条件没有任何关联行为

@Test
    public void testQueryWrapper(){
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.like("name","江");//模糊查询
        wrapper.eq("age",22); //age = 22 的



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

代码生成器

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值