• MyBatis plus快速入门


    MyBatis plus

    简介

    MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

    愿景

    我们的愿景是成为 MyBatis 最好的搭档,就像 魂斗罗 中的 1P、2P,基友搭配,效率翻倍。

    img

    #特性

    • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑

    • 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作

    • 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 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 操作智能分析阻断,也可自定义拦截规则,预防误操作

    #支持数据库

    • mysql 、 mariadb 、 oracle 、 db2 、 h2 、 hsql 、 sqlite 、 postgresql 、 sqlserver

    • 达梦数据库 、 虚谷数据库 、 人大金仓数据库

    #框架结构

    framework

     

    快速使用

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

    @SpringBootApplication
    @MapperScan("com.baomidou.mybatisplus.samples.quickstart.mapper")
    public class Application {
    ​
        public static void main(String[] args) {
            SpringApplication.run(QuickStartApplication.class, args);
        }
    ​
    }

    编写实体类 User.java(此处使用了 Lombok 简化代码)

    @Data
    public class User {
        private Long id;
        private String name;
        private Integer age;
        private String email;
    }

    编写Mapper类 UserMapper.java

    public interface UserMapper extends BaseMapper<User> {
    ​
    }

    测试查询,无条件

    @RunWith(SpringRunner.class)
    @SpringBootTest
    public class PulsTest {
    ​
        @Autowired
        private UserMapper userMapper;
    ​
        @Test
        public void testSelect() {
            List<User> userList = userMapper.selectList(null);
            for (User user : userList) {
                System.err.println(user);
            }
        }

     

    配置日志

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

    CRUD扩展

    插入

    @Test
    public void testInsert(){  
        User user=new User();    
        user.setName("军鹏");   
        user.setAge(20);    
        user.setEmail("1234@qq.com");    
        int insert = userMapper.insert(user);    
        System.err.println(insert);    
        System.err.println(user);
    }

    自增

    @Data
    public class User {
      @TableId(type = IdType.AUTO) //AUTO为自增,注意数据库也要设为自增
      private int id;
      private String name;
      private int age;
      private String email;
    }

    修改

    @Test
    public void testUpdata(){ 
        User user=new User();   
        user.setId(7);  
        user.setName("博洋");   
        user.setAge(24);    
        int i = userMapper.updateById(user);   //参数是实体类对象
        System.err.println(i+"::::"+user);
    }

    其他源码

    public enum IdType {
        AUTO(0), //自增
        NONE(1), //未设置主键
        INPUT(2), //手动设置 一但设置,必须填写
        ASSIGN_ID(3),//默认的全局唯一id
        ASSIGN_UUID(4), //全球唯一id

    删除

    @Test
    public void testdelete(){
        int i = userMapper.deleteById(1);
        System.err.println(i);
    }

    自动填充

    创建时间,修改时间!这些操作都是自动化完成,不希望手动更新!

    阿里巴巴开发手册:所有的数据库:gmt_create、gmt_modified几乎所有表都要配置上!而且需要自动化!

     

    代码级别

    在实体类属性上添加注解

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

    编写处理器来处理这个注解即可

    @Slf4j
    @Component
    public class MyMetaObjectHandler implements MetaObjectHandler {
        //插入时的填充策略
        @Override
        public void insertFill(MetaObject metaObject) {
            log.info("start insert fill ....");
            // 第一个为数据库插入时间字段,第二为当前时间
            this.setFieldValByName("createTime",new Date(),metaObject);
            this.setFieldValByName("updataTime",new Date(),metaObject);
        }
        //更新时的填充策略
        @Override
        public void updateFill(MetaObject metaObject) {
            log.info("start update fill ....");
            this.setFieldValByName("updataTime",new Date(),metaObject);
        }
    }

    测试观察时间即可!

    乐观锁&悲观锁

    乐观锁:顾名思义十分乐观,他总是认为不会出现问题,无论干什么都不会加锁

    悲观锁:顾名思义十分悲观,它总是以为都会出现问题,无论干什么都会加锁

    乐观锁需要数库加个version字段

    实体类加上注解

    @Version
    private Integer version;

    写一个配置类、

    @MapperScan("com.ysl.mapper")
    @EnableTransactionManagement
    @Configuration
    public class MyMybatisPlusConfig {
        @Bean
        public OptimisticLockerInterceptor optimisticLockerInterceptor() {
            return new OptimisticLockerInterceptor();
        }
    }

    测试

    @Test
        public void testle(){
            User user = userMapper.selectById(10);
            user.setName("博洋c");
            user.setAge(23);
            userMapper.updateById(user);
        }

    失败测试

        
    @Test
        public void testle2(){
            User user = userMapper.selectById(10);
            user.setName("博洋aaaaa");
            user.setAge(23);
            User user2 = userMapper.selectById(10);
            user2.setName("博洋bbbbb");
            user2.setAge(23);
            userMapper.updateById(user); //如果没有乐观锁就会覆盖插队线程的值
        }

    根据id或多个id查询

        
    @Test
        public void testSelectById(){
            User user = userMapper.selectById(2);
            System.err.println(user);
    ​
            List<User> users = userMapper.selectBatchIds(Arrays.asList(2, 3, 4));
            users.forEach(System.out::println);
        }

    根据map查询实现动态sql

      
     @Test
        public void testSelectMap(){
            Map<String,Object> map=new HashMap<String,Object>();
            map.put("name","军鹏");
            map.put("age",20);
            List<User> users = userMapper.selectByMap(map);
            users.forEach(System.out::println);
        }

    分页

    现在配置的类中配置beane

    @MapperScan("com.ysl.mapper")
    @EnableTransactionManagement
    @Configuration
    public class MyMybatisPlusConfig {
        //乐观锁插件
        @Bean
        public OptimisticLockerInterceptor optimisticLockerInterceptor() {
            return new OptimisticLockerInterceptor();
        }
    ​
        //分页插件
        @Bean
        public PaginationInterceptor paginationInterceptor() {
            PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
            // 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求  默认false
            // paginationInterceptor.setOverflow(false);
            // 设置最大单页限制数量,默认 500 条,-1 不受限制
            // paginationInterceptor.setLimit(500);
            // 开启 count 的 join 优化,只针对部分 left join
            paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
            return paginationInterceptor;
        }
    }

    测试

        
    //分页查询
        @Test
        public void testSelectPage(){
            //第一个参数:当前页
            //第二个参数:当前页大小
            Page<User> page = new Page<>(1,5);
            userMapper.selectPage(page, null);
            //获得数据
            page.getRecords().forEach(System.err::println);
        System.err.println(page.getCurrent()+"::"+page.getSize()+"::"+page.getTotal()+"::"+page.getPages());
        }

    删除操作

    根据id

      
     @Test
        public void testDelect(){
            //根据id删除单个
            userMapper.deleteById(10);
            //根据id删除多个
            userMapper.deleteBatchIds(Arrays.asList(9,8));
        }
        

    根据map

     @Test
        public void testDelectByMap(){
            //根据map删除
            Map<String,Object> map=new HashMap<String,Object>();
            map.put("id",7);
            map.put("name","b博洋");
            userMapper.deleteByMap(map);
        }

    逻辑删除

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

    逻辑删除:没有从数据库中移除,而是通过一个变量让它失效 deleted=0 == deleted=1

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

    测试一下,数据库加入deleted字段默认为0

    实体类属性上加注解

     //逻辑删除
      @TableLogic
      private int deleted;

    配置yml文件

    mybatis-plus:
      global-config:
        db-config:
          logic-delete-field: flag  #全局逻辑删除字段值 3.3.0开始支持,详情看下面。
          logic-delete-value: 1 # 逻辑已删除值(默认为 1)
          logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)

    测试删除

    记录还在数据库但是deleted的值为1了

    测试查询

    数据库明明有值,就是查不到

     

    查询的时候,MyBitas plus 会自动拼接上 deleted字段为条件

     

    条件构造器

    Wrapper

    测试

      
     @Test
        public void testSelect() {
            //查询邮箱不为空,并且年龄大于15岁
            QueryWrapper<User> wrapper = new QueryWrapper<>();
            wrapper.isNotNull("email").ge("age",15);
            List<User> users = userMapper.selectList(wrapper);
            users.forEach(System.err::println);
        }
        @Test
        public void testSelect3() {
            //查询年龄在20-30之间
            QueryWrapper<User> wrapper = new QueryWrapper<>();
            wrapper.between("age",20,30);
            Integer user = userMapper.selectCount(wrapper);
            System.err.println(user);
        }
        @Test
        public void testSelect4() {
            //模糊查询,查名字不包含e的
            QueryWrapper<User> wrapper = new QueryWrapper<>();
            wrapper.notLike("name","e");
            List<Map<String, Object>> user = userMapper.selectMaps(wrapper);
            user.forEach(System.err::println);
        }
        @Test
        public void testSelect5() {
             //子查询
            QueryWrapper<User> wrapper = new QueryWrapper<>();
            wrapper.inSql("id","select id from user where id>3");
            List<Object> user = userMapper.selectObjs(wrapper);
            user.forEach(System.err::println);
        }
        @Test
        public void testSelect6() {
            //通过id排序
            QueryWrapper<User> wrapper = new QueryWrapper<>();
            wrapper.orderByDesc("id");
            List<User> users = userMapper.selectList(wrapper);
            users.forEach(System.err::println);
        }

    代码自动生成器

     

    //代码自动生成器生成器
    public class KuangCode {
        public static void main(String[] args) {
            //需要构建一个代码自动生成器对象
            AutoGenerator mpg = new AutoGenerator();
            //配置策略
            //1.全局配置
            GlobalConfig gc = new GlobalConfig();
            String property = System.getProperty("user.dir");
            gc.setOutputDir(property+"/src/main/java");
            gc.setAuthor(""); //作者
            gc.setOpen(false); //是否打开资源管理
            gc.setFileOverride(false); //是否覆盖
            gc.setServiceName("%sService"); //去掉Service的I前缀
            gc.setIdType(IdType.ID_WORKER);
            gc.setDateType(DateType.ONLY_DATE);
            gc.setSwagger2(true);
            mpg.setGlobalConfig(gc);
    ​
            //2.设置数据源
            DataSourceConfig dsc = new DataSourceConfig();
            dsc.setUrl("jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=GMT%2B8");
            dsc.setDriverName("com.mysql.cj.jdbc.Driver");
            dsc.setUsername("root");
            dsc.setPassword("1234");
            dsc.setDbType(DbType.MYSQL);
            mpg.setDataSource(dsc);
    ​
            //3.包的配置
            PackageConfig pc = new PackageConfig();
            pc.setModuleName("blog");
            pc.setParent("com.ysl");
            pc.setEntity("pojo");
            pc.setMapper("mapper");
            pc.setService("service");
            pc.setController("controller");
            mpg.setPackageInfo(pc);
    ​
            //4.策略配置
            StrategyConfig strategy = new StrategyConfig();
            strategy.setInclude("zby");
            strategy.setNaming(NamingStrategy.underline_to_camel);
            strategy.setColumnNaming(NamingStrategy.underline_to_camel);
            strategy.setEntityLombokModel(true);//自动设置Lombok
            strategy.setLogicDeleteFieldName("deleted");
            //自动填充配置  create_time   updata_time
            TableFill createTime = new TableFill("create_time", FieldFill.INSERT);
            TableFill updataTime = new TableFill("updata_time", FieldFill.INSERT_UPDATE);
            ArrayList<TableFill> tableFills = new ArrayList<>();
            tableFills.add(createTime);
            tableFills.add(updataTime);
            strategy.setTableFillList(tableFills);
            //乐观锁
            strategy.setVersionFieldName("version");
    ​
            strategy.setRestControllerStyle(true);
            strategy.setControllerMappingHyphenStyle(true);//localhost:8080/hello_id_2
            mpg.setStrategy(strategy);
            mpg.execute();
    ​
        }
    }
     
  • 相关阅读:
    【转】[C# 基础知识系列]专题七:泛型深入理解(一)
    【转】[C# 基础知识系列]专题六:泛型基础篇——为什么引入泛型
    【转】[C# 基础知识系列]专题五:当点击按钮时触发Click事件背后发生的事情
    【转】[C# 基础知识系列]专题四:事件揭秘
    【转】[C# 基础知识系列]专题三:如何用委托包装多个方法——委托链
    Day 47 Django
    Day 45 JavaScript Window
    Day 43,44 JavaScript
    Day 42 CSS Layout
    Day 41 CSS
  • 原文地址:https://www.cnblogs.com/yslss/p/12603430.html
Copyright © 2020-2023  润新知