MyBaits_Plus

MyBatis_Plus

文章目录

  • MyBatis_Plus
    • 0. 必备知识
    • 1.快速入门
      • 1.1什么是MyBatis_Plus
      • 1.2快速使用
    • 2.配置日志
    • 3.CURD的扩展
      • 3.1Insert
      • 3.2 update
      • 3.3自动填充
      • 3.4乐观锁
      • 3.5delete
    • 4.select
      • 4.1基本查询
      • 4.2分页查询
      • 4.3条件构造器
    • 5.代码自动生成器

0. 必备知识

使用第三方组件一般步骤

  1. 导入对应依赖

  2. 研究依赖如何配置

  3. 代码如何编写

  4. 提高技术扩展能力

对于MyBatis-Plus的学习我们也将按照上面4步进行学习

常见网站

MVN仓库

MyBatisPlus官网

1.快速入门

1.1什么是MyBatis_Plus

  • 简称MP,是一个MyBatis的增强工具,在其基础上只做增强,不做修改
  • 引入MP,就不再需要导入MyBatis了

1.2快速使用

1.添加依赖

  • 父工程的Spring Boot Starter版本2.5+

  • 添加依赖

    • spring-boot-starter
    • spring-boot-starter-test

    这两个如果创建了springboot项目则大概率存在,注意检查是否已经存在

    • mybatis-plus-boot-starter:mybatis plus

    • MySQL Connector/J:数据库驱动

    • Project Lombok:简化java代码,@Data,@NoArgsConstructor,@AllArgsConstructor,生成常见方法

    • mybatis-plus-generator:代码生成器,

    • Spring Boot Starter JDBC

2.安装插件lombok

这是为了让IDEA正确处理Lombok注解

3.配置

首先我们需要了解到,在Springboot项目中,使用.properties.yml配置是等效的,均可以正常识别并使用.

在这里我们使用.properties配置

spring.datasource.username=root
spring.datasource.password=232156

spring.datasource.url=jdbc:mysql://localhost:3306/mybatis_plus?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
  • mybatis_plus ?:对应使用的数据库的名称

  • serverTimezone=Asia/Shanghai:配置时区

  • useUnicode=true&characterEncoding=utf-8:字符编码解码格式

  • MySql5之前的

    • 驱动不同,采用该驱动
    spring.datasource.driver-class-name=com.mysql.jdbc.Driver
    
    • 不需要时区配置

4.编写代码

  • 编写顺序:pojo-mapper-service-controller

主要设计两个包的代码编写

  • pojo:存放实体类,

    //注解就是利用lombok来自动生成一些方法
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class User {
     private Integer id;
     private String name;
     private Integer age;
     private String email;
    }
    
  • mapper:存放对应使用的接口,在这一步,所有的CURD就已经全部实现完了

    //必须继承BaseMapper类
    @Mapper
    public interface UserMapper extends BaseMapper<User> {
    }
    
  • 在主程序入口添加@MapperScan,来快速扫描mapper

    //括号中填写具体的mapper文件夹路径
    @MapperScan("com.baomidou.mybatisplus.samples.quickstart.mapper")
    
  • 测试

    @SpringBootTest
    class MyBatisPlusApplicationTests {
    	//所有方法都来自父类
    	//也可以编写自己的文件
    	@Autowired
    	private UserMapper userMapper;
    
    	@Test
    	void contextLoads() {
    		//参数是wapper
    		List<User> users=userMapper.selectList(null);
    		System.out.println(users);
    	}
    	}
    

问题思考

  • 谁帮我们编写的SQL:MyBatisPlus
  • 方法哪里来?MyBatis_Plus写好了

2.配置日志

我们所有sql是不可见的,我们希望知道他是怎么执行的,所以必须要看日志

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

MyBaits_Plus_第1张图片

  • 自动生成的id

image-20230820165240641

3.CURD的扩展

3.1Insert

主键生成策略

  • 自增id:实体类配置(对应数据库中的也需要对应的设置)

    @TabledId(type=IdType.AUTO)
        NONE:未设置主键
        INPUT:手动输入,需要我们手动输入
        ID_WORKER:默认全局唯一ID
        UUID:全局唯一id uuid
        ID_WORKER_STRID_WORKER字符串表示法
    
  • UUID

  • Redis生成ID

雪花算法

  • 雪花算法(多用于分布式):snowflake是Twitter开源的分布式ID生成算法,结果是一个long型的ID。

  • 其核心思想是使用41bit作为毫秒数,10bit作为机器ID(5bit数据中心,5bit机器ID),12bit作为毫秒的流水号(每个节点每毫秒产生4096个id),最后一个符号位永远为0.可以保证全球唯一

3.2 update

  • 注意在这里传入的参数实际是一个对象
@Test
	public void testUpdate(){
		User user=new User();
		user.setId(1);
		user.setName("曹操");
		//参数实际是一个对象
		int i=userMapper.updateById(user);
		System.out.println(i);
	}

3.3自动填充

  • 数据库的级别的自动填充

    1. 修改数据库(给对应的字段添加默认值)

    image-20230821164046202

    1. 修改实体类(与数据库同步)

    2. 再次执行更新操作即可

代码级别

  1. 不设置默认值

  2. 实体类字段上增加注解

    @TableField(fill = FieldFill.INSERT)//插入执行,更新不执行
    private Date createTime;
    @TableField(fill = FieldFill.INSERT_UPDATE)//插入更新都执行
    private Date updateTime;
    
  3. 编写处理器处理该注解(放在hadler包中

    @Slf4j//日志
    @Component//丢到springboot里   一定不要忘记把处理器加到Ioc容器中!
    public class MyMetaObjectHandler extends MetaObjectHandler {//extends??
        @Override//插入时的填充策略
        public void insertFill(MetaObject metaObject) {
            log.info("==start insert ······==");
            //setFieldValByName(java.lang.String fieldName, java.lang.Object fieldVal, org.apache.ibatis.reflection.MetaObject metaObject)
           this.strictInsertFill(metaObject, "createTime", LocalDateTime.class, LocalDateTime.now()); 
            this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); 
        }
        @Override//更新时的填充策略
        public void updateFill(MetaObject metaObject) {
            log.info("==start update ······==");
           this.strictInsertFill(metaObject, "updateTime", LocalDateTime.class, LocalDateTime.now()); 
        }
    }
    
  4. 测试即可

    • 更新
    • 插入

3.4乐观锁

  • 乐观锁:他总是认为不会出现问题,无论做什么都不会去上锁!如果出现问题,就再次更新值测试‘
  • 悲观锁:认为总是出现问题,无论干什么都会上锁
  • 当你跟新一条记录时,希望这条记录没有被别人更新

乐观锁的实现

  1. 取出记录时,获取当前version
  2. 更新时,带上这个version
  3. 执行更新,set version=newVersion where version=oldVersion
  4. 如果version不对则更新失败
  1. 给数据库增加version字段

  2. 实体类增加对应字段即注解

    @Version//乐观锁version注解
    private Integer version;
    
  3. 注册组件:新建文件config.MyBatisPlusConfig文件

    @MapperScan("com.upupstudy.mybatis_plus.mapper")//在主程序入口就可以删除对应的扫描了
    @EnableTransactionManagement//事务管理
    @Configuration//代表这是配置类
    public class MyBatisPlusConfig {
        //注册乐观锁插件
        @Bean
        public MybatisPlusInterceptor mybatisPlusInterceptor() {//拦截器
            MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
            interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());//乐观锁插件
            interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2));//分页插件
            return interceptor;
        }
    
    }
    
  4. 测试

3.5delete

  • 物理删除:直接在数据库中删除
  • 新增一个字段:用改值来标记是否被删除(0在1删)
  1. 新增一个deleted字段

  2. 实体类添加对应属性

    @TableLogic//逻辑删除注解
    private Integer deleted;
    
  3. 配置

    #配置逻辑删除  没删除的为0 删除的为1
    mybatis-plus.global-config.db-config.logic-delete-value=1
    mybatis-plus.global-config.db-config.logic-not-delete-value=0
    
  4. 测试

    • 将对应项的deleted值进行更新
    • 但是查询时,无法查询该项
    userMapper.deleteById(1)//看似删除,其实执行的时更新操作
    

4.select

4.1基本查询

  • 单个查询

    @Test//通过id查询单个用户
    public void testSelectById(){
        User user = userMapper.selectById(1);
        System.out.println(user);
    }
    
  • 批量查询

    @Test//通过id查询多个用户
    public void testSelectBatchIds(){
        List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3));
        users.forEach(System.out::println);
        //System.out.println(users);
    }
    
  • 条件查询

    @Test//通过条件查询之一  map
    public void testMap(){
        HashMap<String, Object> map = new HashMap<>();
        //自定义要查询的条件
        map.put("name","张飞");
        map.put("age",18);
        List<User> users = userMapper.selectByMap(map);
        users.forEach(System.out::println);
    }
    

4.2分页查询

常见的分页方法

  • limit方法
  • pageHelper第三方插件
  • MP内置分页插件
  1. 设置拦截器组件

    @MapperScan("com.upupstudy.mybatis_plus.mapper")
    @EnableTransactionManagement//事务管理
    @Configuration//代表这是配置类
    public class MyBatisPlusConfig {
        //注册乐观锁插件
        @Bean
        public MybatisPlusInterceptor mybatisPlusInterceptor() {//拦截器
            MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
            interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());//乐观锁插件
            //************新增分页插件***************
            interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2));//分页插件
            return interceptor;
        }
    
    }
    
  2. 直接使用page对象分页查询

    /*
    *与前端连用,只需要从前端向后传输一个current参数即可
    *
    */
    @Test//测试分页查询
    public void testPage(){
        //参数一current:当前页   参数二size:页面大小
        //使用了分页插件之后,所有的分页操作都变得简单了
        Page<User> page = new Page<>(2,5);
        userMapper.selectPage(page,null);
        page.getRecords().forEach(System.out::println);
        System.out.println("总页数==>"+page.getTotal());
    }
    

4.3条件构造器

  • 具体条件可在官网查看,这里不一一列出
@Test
public void testWrapper1() {
    //参数是一个wrapper ,条件构造器,和刚才的map对比学习!
    //查询name不为空,email不为空,age大于18的用户
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    wrapper
        .isNotNull("name")
        .isNotNull("email")
        .ge("age",18);//年龄大于18
    
    
    List<User> userList = userMapper.selectList(wrapper);
    userList.forEach(System.out::println);

5.代码自动生成器

可以快速生成Entity,Mapper,Mapper XML,Service,Controller等各个模块的代码,极大的提高了开发效率

1.导入依赖

  • mybatis-plus-generator
  • Freemarker

2.代码编写:建议放在测试文件夹中

  • 交互生成

    FastAutoGenerator.create(DATA_SOURCE_CONFIG)
        // 全局配置
        .globalConfig((scanner, builder) -> builder.author(scanner.apply("请输入作者名称?")).fileOverride())
        // 包配置
        .packageConfig((scanner, builder) -> builder.parent(scanner.apply("请输入包名?")))
        // 策略配置
        .strategyConfig((scanner, builder) -> builder.addInclude(getTables(scanner.apply("请输入表名,多个英文逗号分隔?所有输入 all")))
                            .controllerBuilder().enableRestStyle().enableHyphenStyle()
                            .entityBuilder().enableLombok().addTableFills(
                                    new Column("create_time", FieldFill.INSERT)
                            ).build())
        /*
            模板引擎配置,默认 Velocity 可选模板引擎 Beetl 或 Freemarker
           .templateEngine(new BeetlTemplateEngine())
           .templateEngine(new FreemarkerTemplateEngine())
         */
        .execute();
    
    
    // 处理 all 情况
    protected static List<String> getTables(String tables) {
        return "all".equals(tables) ? Collections.emptyList() : Arrays.asList(tables.split(","));
    }
    
  • 快速生成

FastAutoGenerator.create("url", "username", "password")//对应到.properites中的sql配置
    .globalConfig(builder -> {
        builder.author("baomidou") // 设置作者
            //建议注释
            .enableSwagger() // 开启 swagger 模式,0
            //建议注释
            .fileOverride() // 覆盖已生成文件,建议注释
            .outputDir("D://"); // java一级目录下,绝对路径
    })
    .dataSourceConfig(builder -> builder.typeConvertHandler((globalConfig, typeRegistry, metaInfo) -> {
        int typeCode = metaInfo.getJdbcType().TYPE_CODE;
        if (typeCode == Types.SMALLINT) {
            // 自定义类型转换
            return DbColumnType.INTEGER;
        }
        return typeRegistry.getColumnType(metaInfo);

    }))
    .packageConfig(builder -> {
        builder.parent("com.baomidou.mybatisplus.samples.generator") // 填写到与主程序同一级目录
            .moduleName("system") // 设置父包模块名,为这个文件夹命名
            .pathInfo(Collections.singletonMap(OutputFile.xml, "D://")); // 设置mapperXml生成路径
    })
    .strategyConfig(builder -> {
        builder.addInclude("t_simple") // 设置需要生成的表名
            .addTablePrefix("t_", "c_"); // 设置过滤表前缀
    })
    .templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默认的是Velocity引擎模板
    .execute();

配置方法

详细解释

你可能感兴趣的:(Java基础,java,mybatis,spring,boot,maven)