美文网首页
mybatisPlus学习

mybatisPlus学习

作者: Summer2077 | 来源:发表于2020-04-17 22:25 被阅读0次

    数据库设计规约

    注意:数据库设计规约并不是数据库设计的严格规范,根据不同团队的不同要求设计
    本项目参考《阿里巴巴Java开发手册》:五、MySQL数据库

    1、库名与应用名称尽量一致

    2、表名、字段名必须使用小写字母或数字,禁止出现数字开头,

    3、表名不使用复数名词

    4、表的命名最好是加上“业务名称_表的作用”。如,edu_teacher

    5、表必备三字段:id, gmt_create, gmt_modified

    6、单表行数超过 500 万行或者单表容量超过 2GB,才推荐进行分库分表。 说明:如果预计三年后的数据量根本达不到这个级别,请不要在创建表时就分库分表。

    7、表达是与否概念的字段,必须使用 is_xxx 的方式命名,数据类型是 unsigned tinyint (1 表示是,0 表示否)。

    说明:任何字段如果为非负数,必须是 unsigned。

    注意:POJO 类中的任何布尔类型的变量,都不要加 is 前缀。数据库表示是与否的值,使用 tinyint 类型,坚持 is_xxx 的 命名方式是为了明确其取值含义与取值范围。

    正例:表达逻辑删除的字段名 is_deleted,1 表示删除,0 表示未删除。

    8、小数类型为 decimal,禁止使用 float 和 double。 说明:float 和 double 在存储的时候,存在精度损失的问题,很可能在值的比较时,得到不 正确的结果。如果存储的数据范围超过 decimal 的范围,建议将数据拆成整数和小数分开存储。

    9、如果存储的字符串长度几乎相等,使用 char 定长字符串类型。

    10、varchar 是可变长字符串,不预先分配存储空间,长度不要超过 5000,如果存储长度大于此值,定义字段类型为 text,独立出来一张表,用主键来对应,避免影响其它字段索引效率。

    11、唯一索引名为 uk_字段名(unique key);普通索引名则为 idx_字段名(index)。

    说明:uk_ 即 unique key;idx_ 即 index 的简称

    12、不得使用外键与级联,一切外键概念必须在应用层解决。外键与级联更新适用于单机低并发,不适合分布式、高并发集群;级联更新是强阻塞,存在数据库更新风暴的风险;外键影响数据库的插入速度。

    image.png

    mybatisPlus学习

    本文参照狂神的视频编写https://www.bilibili.com/video/BV17E411N7KN

    在此特别感谢狂神陪伴我度过无聊的2020的上半年。

    本文使用springBoot来整合mybatisPlus进行使用

    1.快速开始(第一个hello world)

    1.1 创建一个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)
    );
    DELETE FROM user;
    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');
    

    1.2 导入依赖

     <dependencies>
           <!-- springboot 的依赖 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
                <exclusions>
                    <exclusion>
                        <groupId>org.junit.vintage</groupId>
                        <artifactId>junit-vintage-engine</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.18.10</version>
                <scope>provided</scope>
            </dependency>
            <!-- 数据库驱动 -->
            <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>
        </dependencies>
    

    1.3 在application.properties中配置对应的数据库连接

    spring.datasource.username=StudyDatabase
    spring.datasource.password=root
    spring.datasource.url=jdbc:mysql://localhost:3306/StudyDatabase?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
    spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
    

    注意:

    1、这里的 url 使用了 ?serverTimezone=GMT%2B8 后缀,因为8.0版本的jdbc驱动需要添加这个后缀,否则运行测试用例报告如下错误:

    java.sql.SQLException: The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more

    2、这里的 driver-class-name 使用了 com.mysql.cj.jdbc.Driver ,在 jdbc 8 中 建议使用这个驱动,否则运行测试用例的时候会有 WARN 信息

    mybatis日志

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

    1.4 编写pojo类(user)

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class User {
        private Long id;
        private String name;
        private int age;
        private String email;
    }
    

    1.5 编写接口(UserMapper)

    @Repository
    public interface UserMapper extends BaseMapper<User> {
    }
    

    1.6 在 Spring Boot 启动类中添加 @MapperScan 注解,扫描 Mapper 文件夹

    @SpringBootApplication
    @MapperScan("com.summer.mapper")
    public class MybatisPlusApplication {
        ......
    }
    

    1.7测试

    @SpringBootTest
    class MybatisplusApplicationTests {
    
        @Autowired
        private UserMapper userMapper;
    
        @Test
        void contextLoads() {
            List<User> users = userMapper.selectList(null);
            users.forEach(System.out::println);
        }
    }
    

    ​ 我看完当时学完的表情

    v2-ba22e4ebc42b37bbb2140dce9a76105c_720w.jpg

    仔细想想其实就是以下几步

    1. 导入依赖mybatis-plus的依赖
    2. 编写pojo类
    3. 编写接口
    4. 测试

    一定要记得在启动类上面加上@MapperScan注解 用来扫描mapper文件

    比起mybatis原版的操作这里少了什么?

    ​ 少了编写xml文件,不需要编写SQL语句,

    为什么我们可以少写这一步呢?

    ​ 我们在接口上面继承了一个抽象类 extends BaseMapper<T>

    ​ T 是一个泛型,往这上面丢入我们想要操作的pojo类,就可以自动生成对应的方法。

    2. 配置日志

    日志为了让我们去查看执行的sql语句

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

    3.CRUD扩展

    3.1插入操作

    @SpringBootTest
    class MybatisplusApplicationTests {
    
        @Autowired
        private UserMapper userMapper;
    
        @Test
        void contextLoads() {
            User user = new User();
            user.setAge(20);
            user.setEmail("1260570909@qq.com");
            user.setName("summer");
            userMapper.insert(user);
            List<User> users = userMapper.selectList(null);
            users.forEach(System.out::println);
        }
    
    }
    
    1586605871205.png

    我们发现我们没有设置id,但是mybatis-plus却给我们生成这么一串的id?

    3.2主键生成策略

    1.如何配置主键生成策略?

    我们在id上面添加主键 @TableId(type = IdType.ID_WORKER),就可以配置。

    public class User {
        @TableId(type = IdType.ID_WORKER)
        private Long id;
    }
    
    1. 主键生成策略的种类:

      我们可以根据需求去选择,mybatis-plus中默认的是 ID_WORKER。

      使用的是一个雪花算法的方法计算出的id。

      一般我们也会选择自增的策略AUTO,不过我们要记得在数据库的主键上添加自增的属性

        AUTO(0),
        NONE(1),
        INPUT(2),
        ID_WORKER(3),
        UUID(4),
        ID_WORKER_STR(5);
    
    

    注意点:

    1.id 要写为long 类型的数据 不然会报错

    private Long id;
    

    mybatis-plus中会自动帮我们生产id,但是id类型是long ,不是int型的

    1. 在配置id自增的时候一定要保证数据库里面id是自增的!!!!
     @TableId(type = IdType.AUTO)
        private Long id;
    
    1. UUID对应的是字符串不是我们平时的int类型

    3.3更新操作

        @Test
        void updatamybatis(){
         User user = new User();
            user.setId(20L);
         user.setName("summer");
            int update = userMapper.updateById(user);
         System.out.println(update);
            List<User> users = userMapper.selectList(null);
         users.forEach(System.out::println);
        }
    
    

    mybatis-plus 会帮我们自动生成SQL语句

    3.4自动填充

    在我们的数据库字段中都会有create_time, update_time这两个字段,我们希望他可以自己改变,而不是我们手动的改变

    1.数据库级别

    ​ 我们在数据中将这两个字段设置为如下就数据库就会自动更新了

    Snipaste_2020-04-11_22-28-11.png

    2.代码级别

    ​ 以往我们都会用new Data来更新,这样又笨重有麻烦,而且会忘记。

    ​ 现在我们可以自动填充了

    1.在代码上写上注解

     @TableField(fill = FieldFill.INSERT)
        private Date createTime;
        @TableField(fill = FieldFill.INSERT_UPDATE)
        private Date updateTime;
    
    

    2.编写配置类

    @Component
    public class MyMetaObjectHandler implements MetaObjectHandler {
        @Override
        public void insertFill(MetaObject metaObject) {
            this.setFieldValByName("createTime",new Date(),metaObject);
            this.setFieldValByName("updateTime",new Date(),metaObject);
     }
        @Override
     public void updateFill(MetaObject metaObject) {
            this.setFieldValByName("updateTime",new Date(),metaObject);
        }
    }
    
    

    3.测试运行

        @Test
        void contextLoads() {
            User user = new User();
            user.setAge(20);
         user.setEmail("1260570909@qq.com");
            user.setName("summer");
         userMapper.insert(user);
            List<User> users = userMapper.selectList(null);
         users.forEach(System.out::println);
        }
    
    
    Snipaste_2020-04-12_09-30-14.png

    自动填充成功!!

    3.5乐观锁

    乐观锁:认为什么都不会出现问题,什么都不会加锁,只有出现问题之后才会去更新对应的值。

    悲观锁:认为什么都是会出问题的,什么操做都会加锁。

    mysql 中我们如何实现乐观锁?

    1.我们在表中的加入字段version

    2.在spring中注册乐观锁

    @EnableTransactionManagement
    @Configuration // 配置类
    public class MyBatisPlusConfig {
     // 注册乐观锁插件
        @Bean
     public OptimisticLockerInterceptor optimisticLockerInterceptor() {
            return new OptimisticLockerInterceptor();
        }
    }
    
    

    3.模拟插队的情况:

        @Test
        void versionTest() {
            User user = userMapper.selectById(20L);
            user.setAge(20);
            user.setEmail("212121@qq.com");
            user.setName("pppnut");
    
            User user2 = userMapper.selectById(20L);
            user.setAge(20);
         user.setEmail("212121@qq.com");
            user.setName("蜜桃");
    
            userMapper.updateById(user2);
            userMapper.updateById(user);
     }
    
      UPDATE user SET name=?, age=?, email=?, version=?, update_time=? WHERE id=? AND version=? 
    

    上述是执行的sql语句,先查数据库中的版本好是否和现在的一致,一致就说明之前没有人对我的数据进行修改,不一致就说明我们的数据被修改,现在的操作取消

    3.6查询操作

      @Test
        void selectTest() {
            //根据id查询
            User user = userMapper.selectById(20L);
            //根据id批量查询
            List<User> users = userMapper.selectBatchIds(Arrays.asList(26L,27L,28L));
            //根据map的条件查询
            HashMap<String, Object> map = new HashMap<>();
            map.put("name","夏天");
            map.put("age",0);
         List<User> users1 = userMapper.selectByMap(map);
    
         System.out.println(user);
            users.forEach(System.out::println);
         users1.forEach(System.out::println);
        }
    

    3.7分页查询

    如何使用?

    1.在mybatis-plus中添加分页插件

          //分页插件
        @Bean
           public PaginationInterceptor paginationInterceptor() {
               return new PaginationInterceptor();
           }
    

    2.测试

      @Test
        void pageTest() {
         Page<User> userPage = new Page<>(1,4);
            userMapper.selectPage(userPage, null);
         userPage.getRecords().forEach(System.out::println);
            System.out.println(userPage.getTotal());
         System.out.println(userPage.getSize());
        }
    

    3.8删除操作

        @Test
        void deleteTest(){
            //通过id删除
            int i = userMapper.deleteById(1);
            //批量删除
            int i1 = userMapper.deleteBatchIds(Arrays.asList(11,12,13));
            HashMap<String, Object> map = new HashMap<>();
            map.put("name","夏天");
            map.put("age",20);
         //条件删除
            int i2 = userMapper.deleteByMap(map);
         System.out.println(i);
            System.out.println(i1);
         System.out.println(i2);
        }
    

    3.9逻辑删除

    管理员可以查看被删除的记录!防止数据的丢失,类似于回收站!

    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
    

    4.条件构造器wrapper

    写一些复杂的sql就可以使用它来替代!

       Wrapper<User> Wrapper = new Wrapper<>();
    
    基本的条件:
    1. 大于 > Greater than #gt

    2. 小于 < Less than #lt

    3. 等于 = Equals #qe

      类比ge,le,ne

    4. between

    5. notBetween

    6. like

      ......

      其他去官网查找

    https://mp.baomidou.com/guide/wrapper.html#setsql

    相关文章

      网友评论

          本文标题:mybatisPlus学习

          本文链接:https://www.haomeiwen.com/subject/ntxpvhtx.html