MyBatisPuls

02、MyBatisPuls

一、MyBatisPuls

1、myBatisPuls介绍

MyBatisPlus(MP) 是基于MyBatis框架基础上开发的增强工具,旨在简化开发,提高效率。

2、myBatisPlus特性

1、无入侵:只做增强不做改变,不会对现有工程产生影响。
2、强大的CRUD操作: 内置通用Mapper,扫两配置即可实现单表CRUD操作
3、支持主键自动生成
4、内置分页插件

3、springboot 整合mybatisplus要加入下面的依赖

<dependency>
   <groupId>com.baomidou</groupId>
   <artifactId>mybatis-plus-boot-starter</artifactId>
   <version>3.5.1</version>
</dependency>
二、标准数据层开发
一、标准数据层CRUP功能
dao层
/**
 *  dao要求:
 *      1. 继承BaseMapper,并且要写上泛型[这是dao操作那张表,就写那张表对应的javaBean类型]
 *      2. 在接口上大注解@Mapper或者在启动类上打注解@MapperScan("com.cwl.dao")
 */
@Mapper
public interface UserDao extends BaseMapper<User> {
}
配置文件application.yml中设置jdbc参数
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql:///user_surface
    username: root
    password: root
配置文件application.yml中设置sql语句打印日志
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

1、新增

@SpringBootTest
public class TestInsert {
	@Autowired
    private UserDao userDao;
 	@Test
    public void Insert(){
        User user = new User();
        user.setName("zhsc");
        user.setAge(19);
        user.setPassword("1234556");
        user.setTel("1234567");
        int row = userDao.insert(user);
        System.out.println("row = " + row);
    }
}

2、删除

// 按照id地址删除
@SpringBootTest
public class TestDelete {
    @Autowired
    private UserDao userDao;
    @Test
    public void test(){
        int row = userDao.deleteById(2);
        System.out.println("row = " + row);
    }
}

3、修改

@SpringBootTest
public class TestUpdate {
    @Autowired
    private UserDao userDao;
    @Test
    public void test(){
        //1.先查询
        User user = userDao.selectById(1);
        user.setTel("1234567890");
        //2.后修改
        int row = userDao.updateById(user);
        System.out.println("row = " + row);
    }
}

4、根据id查询

@SpringBootTest
public class TestFind {
    @Autowired
    private UserDao userDao;
    @Test
    public void test(){
        //1. 按id去查
        User user = userDao.selectById(1);
        System.out.println("user = " + user); 
    }
}
二、分页功能

1、分页查询
设置分页拦截器作为spring管理的bean


@Configuration
public class MyBatisPlusConfig {

    //配置分页拦截器
    @Bean
    public MybatisPlusInterceptor mip(){
        //1. 构建mybatisplus的拦截器对象
        MybatisPlusInterceptor mpi = new MybatisPlusInterceptor();
        //2. 把分页拦截器设置到mip里面
        mpi.addInnerInterceptor(new PaginationInnerInterceptor());
        return mpi;
    }
}
@SpringBootTest
public class testFindPage {
    @Autowired
    private UserDao userDao;
    @Test
    public void test(){
        //1. 创建page对象 用来包装,查询第几页 每页查询多少条
        Page<User> page = new Page<>(2,2);
        //2. 执行分页查询
        //  参数一  page对象
        //  参数二  查询条件,如果是面对整张表的分页,那么就写null
        userDao.selectPage(page, null);

        System.out.println("当前页 = " + page.getCurrent());
        System.out.println("总页数 = " + page.getPages());
        System.out.println("每页个数 = " + page.getSize());
        System.out.println("总记录数 = " + page.getTotal());
        System.out.println("当前页的集合 = " + page.getRecords());

    }
}
三、DQL控制
一、条件查询方式

1、条件查询的普通写法

@SpringBootTest
public class TestFind {
    @Autowired
    private UserDao userDao;
    @Test
    public void test(){
        //查询年龄大于等于18岁,小于65岁的用户
        //1. 构造条件对象
        QueryWrapper<User> qu = new QueryWrapper<>();
        //2. 设置条件  select * from user where age>=18 and age<65
        qu.ge("age", 18).lt("age",65);
        //3. 执行查询
        List<User> list = userDao.selectList(qu);
        System.out.println("list = " + list);
    }
}

2、条件查询的lambda的写法

@SpringBootTest
public class TestLambdaFind {

    @Autowired
    private UserDao userDao;

    @Test
    public void test(){
        //1. 创建LambdaQueryWrapper
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
        //2. 设置条件
        lqw.ge(User::getAge, 18).lt(User::getAge, 55);
        //3. 执行查询
        List<User> list = userDao.selectList(lqw);
        System.out.println("list = " + list);
    }
}

3、组合条件查询

@SpringBootTest
public class testAndOr {
    @Autowired
    private UserDao userDao;

    // 组合条件的写法:默认多个条件一起写,就会使用and关键字来拼接
    // 如果希望使用or关键字,那么需要在条件中间调用or()来衔接
    @Test
    public void test(){
        //1. 构建条件对象
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
        //2. 设置条件
        lqw.le(User::getAge, 30).or().gt(User::getAge, 18);
        //3. 执行查询
        List<User> list = userDao.selectList(lqw);
        System.out.println("list = " + list);
    }
}

4、动态条件查询

@SpringBootTest
public class TestDynamic {

    // 动态条件的设置  条件不一定有,需要经过判定之后,才能追加条件
    @Autowired
    private UserDao userDao;
    
    @Test
    public void test(){
        //1. 准备一份数据
        User user = new User();
        user.setName("admin");
        user.setAge(17);
        user.setPassword("12345");
        //2. 判断条件,然后追加条件
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
        //2.1 设置条件  都使用第一个参数位置来控制条件是否追加, true 就追加, false , 就不追加条件
        lqw.eq(user.getName() != null, User::getName, user.getName());
        lqw.eq(user.getAge() != null, User::getAge, user.getAge());
        lqw.eq(user.getPassword() != null, User::getPassword, user.getPassword());
        //3. 执行查询
        List<User> list = userDao.selectList(lqw);
        System.out.println("list = " + list);
    }
}
二、查询条件设置

1、统计查询

	//统计查询
    @Test
    public void test(){
        QueryWrapper<User> qw = new QueryWrapper<>();
        //设置查询的列
        qw.select("count(*) as number", "gender"); //select count(*), gender from user
        //设置分组
        qw.groupBy("gender"); //select count(*), gender from user group by gender
        List<Map<String, Object>> list = userDao.selectMaps(qw);
        System.out.println("list = " + list);
    }

2、等价查询,只查询一条记录

	// 等价查询,只查询一条记录
    @Test
    public void test(){
        //1. 创建条件对象
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
        //1.1 设置条件
        lqw.eq(User::getName , "admin").eq(User::getPassword , "123");
        //2. 执行查询
        User user = userDao.selectOne(lqw);
        System.out.println("user = " + user);
    }

3、区间查询

	// 区间查询
    @Test
    public void testFindByCondition09(){
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
        //查询年龄在18 和 65 之间的用户。
        lqw.between(User::getAge , 18 , 65);
        List<User> list = userDao.selectList(lqw);
        System.out.println("list = " + list);
    }

4、模糊查询

	// 模糊查询
    @Test
    public void test(){
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
        //1. 设置条件 %a%
        lqw.like(User::getName , "a");
        //排序 : 使用年龄来排序,降序排序
        lqw.orderByDesc(User::getAge);
        List<User> list = userDao.selectList(lqw);
        System.out.println("list = " + list);
    }

5、查询条件:更多查询条件设置参看

https://baomidou.com/pages/10c804/#abstractwrapper
四、字段映射与表名映射

1、表字段与编码属性设计不同步(属性名与列名不匹配)

/*
  1. mybatisplus 查询的时候,默认是查询所有的列,并且不是使用 select * 的方式来查询
    而是使用select 每一列的方式来查询。
  2. mybatisplus 查询的时候,是通过扫描了JavaBean里面的所有属性,把所有的属性名
    当成是列名来查询。
    select id , name , password , age , tel from user
  3. 如果某个属性的名字和列名对不上那么就会报错!
     Unknown column 'password' in 'field list'
  4. 解决方案:
     在属性上加上注解 @TableField,给value属性设值,值就是列的名字,设置了之后,mybtisplus
 就按照这个名字来查询
     select id , name , pwd as password, age , tel from user
  */
	@TableField("pwd") //设置列的名字
    private String password;

2、编码中添加了数据库中未定义的属性(处理不存在的属性)

	/*
        1. 这个属性是我们为了在其他地方方便判断用户的信息,设置的一个属性。
        2. 这个属性并没有任何一个列与之对应
        3. 为了告诉mybatisplus 查询的时候,不要把这个属性计算在内。
        4. 需要设置注解,exist = false, 没有任何一个列与之对应!
     */
	@TableField(exist = false)
    private String online;

3、采用默认查询开放了更多的字段查看权限(屏蔽某些字段不查询)

	//如果不希望把这个列查询出来,那么就可以加上注解@TableField(select=false)
    @TableField(select = false)
    private String gender;

4、表名与编码开发设计不同步(表名与类型映射)

	/*
    mybatisplus 操作表的策略:
        1. mybatisplus 查询表的时候,它都是扫描JavaBean里面的所有属性名,然后当成是列名来操作
        2. 至于具体操作哪张表,其实它是把JavaBean的名字,变成全小写之后去匹配!
            User -----> user表
        3. 至于到底找的是哪个JavaBean,从dao的类的定义泛型位置出发的。
            public interface UserDao extends BaseMapper<User> {
            Table 'user_surface.user' doesn't exist
            Table 'user_surface.aa' doesn't exist
        4. 在类上加上注解@TableName("t_user"), 设置value属性值,它会被当成是表名来看待!
	 */

4.1 在JavaBean的类上直接打上注解

@TableName("t_user")
@Data
public class User {}

4.2 可以使用全局设置(在application.yml文件中)

mybatis-plus:
  global-config: # 全局配置
    db-config: # 配置表的前缀 和 id的策略
      table-prefix: t_
      id-type: auto
四、DML
一、id自增策略控制(Insert)
	/*
     ID 的策略:
       AUTO: 使用数据库自增的id
       NONE: 没有设置策略,约等于 INPUT
       INPUT : 使用用户输入的id,如果没有输入就默认使用雪花算法生成的id
       ASSIGN_ID : 使用雪花算法生成的id
       ASSIGN_UUID : 使用UUID生成的id,但是它得到的是一个字符串!
    */
	@TableId(type = IdType.ASSIGN_UUID)
    private Long  id;
二、全局设置
mybatis-plus:
  global-config: # 全局配置
    db-config: # 配置表的前缀 和 id的策略
      table-prefix: t_
      id-type: auto
三、批量查询–多记录操作(Select)
	//批量查询
    @Test
    public void testSelectBatch(){
        //构建集合,装id值
        List<Long> ids = Arrays.asList(1579722941208236033L, 1579722996866727938L);

        //执行查询
        List<User> list = userDao.selectBatchIds(ids);

        System.out.println("list = " + list);
    }
四、批量删除—多记录操作(Delete)
	//批量删除
    @Test
    public void testDeleteBatch(){
        //构建集合,装id值
        List<Long> ids = Arrays.asList(1579722941208236033L, 1579722996866727938L);

        //执行查询
        int row = userDao.deleteBatchIds(ids);
        System.out.println("row = " + row);
    }
五、逻辑删除—逻辑删除(Delete/Update)
1、删除操作业务问题:业务数据从数据库中丢弃
2、逻辑删除:为数据设置是否可用状态字段,删除时设置状态字段为不可用状态,数据保留在数据库中

1、在属性上打上注解

	//表示这个是逻辑删除字段。 也可以使用全局来设置。
    // 1 即表示删除的值 , 0 表示未删除的值
    @TableLogic(delval = "1" , value = "0")
    private int deleted;

2、可以使用全局设置(在application.yml文件中)

mybatis-plus:
  global-config:
    db-config:
      logic-delete-field: deleted # 逻辑删除的字段名
      logic-delete-value: 1 # 删除的值
      logic-not-delete-value: 0 # 未删除的值
	//逻辑删除
    @Test
    public void testDelete(){
        userDao.deleteById(1579723562409803777L);
    }

    //查询所有
    @Test
    public void testFindAll(){
        System.out.println("list = " + userDao.selectList(null));
    }
六、乐观锁(Update)

1、实体类中添加对应字段,并设定当前字段为乐观锁版本控制字段

	// 乐观锁的字段
    @Version
    private int version;

2、配置乐观锁拦截器实现锁机制对应的动态SQL语句拼装

@Configuration
public class MyBatisPlusConfig {

    @Bean
    public MybatisPlusInterceptor mpi (){

        MybatisPlusInterceptor mpi = new MybatisPlusInterceptor();
        // 添加乐观锁的拦截器
        mpi.addInnerInterceptor(new OptimisticLockerInnerInterceptor());

        return mpi;
    }
}

3、使用乐观锁机制在修改前必须先获取到对应数据的verion方可正常进行

	//乐观锁
    @Test
    public void testUpdate(){

        //1. 先查询
        User user = userDao.selectById(1L);

        //再查一次!
        User user02 = userDao.selectById(1L);

        //2. 改密码:
        user.setPassword("888");

        //3. 执行更新
        int row = userDao.updateById(user);
        System.out.println("row = " + row);

        // 再改
        user02.setPassword("999");
        int row02 = userDao.updateById(user02);
        System.out.println("row02 = " + row02);

    }
最后更新的结果是 888
五、快速开发

1、代码生成器

@SpringBootTest
public class TestCode {

    @Test
    public void test01(){

        //创建代码生成器对象,执行生成代码操作
        AutoGenerator autoGenerator = new AutoGenerator();

        //2. 数据源相关配置:读取数据库中的信息,根据数据库表结构生成代码
        DataSourceConfig dataSource = new DataSourceConfig();
        dataSource.setDriverName("com.mysql.cj.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/book?serverTimezone=UTC");
        dataSource.setUsername("root");
        dataSource.setPassword("root");
        autoGenerator.setDataSource(dataSource);

        //设置全局配置
        GlobalConfig globalConfig = new GlobalConfig();
        //设置代码生成位置
        globalConfig.setOutputDir(System.getProperty("user.dir")+"/src/main/java");    
        //设置生成完毕后是否打开生成代码所在的目录
        globalConfig.setOpen(false);    
        //设置作者
        globalConfig.setAuthor("cwl");  
         //设置是否覆盖原始生成的文件  
        globalConfig.setFileOverride(true);    
         //设置数据层接口名,%s为占位符,指代模块名称
        globalConfig.setMapperName("%sDao");   
         //设置Id生成策略
        globalConfig.setIdType(IdType.ASSIGN_ID);  
        autoGenerator.setGlobalConfig(globalConfig);


        //设置包名相关配置
        PackageConfig packageInfo = new PackageConfig();
        //设置生成的包名,与代码所在位置不冲突,二者叠加组成完整路径
        packageInfo.setParent("com.cwl");   
        //设置实体类包名
        packageInfo.setEntity("bean");   
        //设置数据层包名
        packageInfo.setMapper("dao");   
        autoGenerator.setPackageInfo(packageInfo);


        //策略设置
        StrategyConfig strategyConfig = new StrategyConfig();
        //设置当前参与生成的表名,参数为可变参数
        strategyConfig.setInclude("t_user");  
        //设置数据库表的前缀名称,模块名 = 数据库表名 - 前缀名  例如: User = tbl_user - tbl_
        strategyConfig.setTablePrefix("t_");  
        //设置是否启用Rest风格
        strategyConfig.setRestControllerStyle(true);    
        //设置乐观锁字段名
        strategyConfig.setVersionFieldName("version");  
        //设置逻辑删除字段名
        strategyConfig.setLogicDeleteFieldName("deleted");  
        //设置是否启用lombok
        strategyConfig.setEntityLombokModel(true); 
        autoGenerator.setStrategy(strategyConfig);

        //执行方法生成代码
        autoGenerator.execute();
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值